@@ -127,7 +127,7 @@ func upAllLinks() error {
127
127
}
128
128
129
129
func getNICs () ([]netlink.Link , error ) {
130
- var nics []netlink.Link
130
+ var nics , vlanNics []netlink.Link
131
131
132
132
links , err := netlink .LinkList ()
133
133
if err != nil {
@@ -138,9 +138,24 @@ func getNICs() ([]netlink.Link, error) {
138
138
if l .Type () == "device" && l .Attrs ().EncapType != "loopback" {
139
139
nics = append (nics , l )
140
140
}
141
+ if l .Type () == "vlan" {
142
+ vlanNics = append (vlanNics , l )
143
+ }
144
+ }
145
+
146
+ iscsi := goiscsi .NewLinuxISCSI (nil )
147
+ sessions , err := iscsi .GetSessions ()
148
+ if err != nil {
149
+ return nil , fmt .Errorf ("error querying iscsi sessions: %v" , err )
141
150
}
142
151
143
- return filterISCSIInterfaces (nics )
152
+ // no iscsi sessions detected so no additional filtering based on usage for iscsi device
153
+ // access is needed and we can break here
154
+ if len (sessions ) == 0 {
155
+ return nics , nil
156
+ }
157
+
158
+ return filterISCSIInterfaces (nics , vlanNics , sessions )
144
159
}
145
160
146
161
func getNICState (name string ) int {
@@ -196,44 +211,63 @@ func getManagementInterfaceName(mgmtInterface config.Network) string {
196
211
197
212
// filterISCSIInterfaces will query the host to identify iscsi sessions, and skip interfaces
198
213
// used by the existing iscsi session.
199
- func filterISCSIInterfaces (links []netlink.Link ) ([]netlink.Link , error ) {
200
- iscsi := goiscsi .NewLinuxISCSI (nil )
201
- sessions , err := iscsi .GetSessions ()
202
- if err != nil {
203
- return nil , fmt .Errorf ("error querying iscsi sessions: %v" , err )
214
+ func filterISCSIInterfaces (nics , vlanNics []netlink.Link , sessions []goiscsi.ISCSISession ) ([]netlink.Link , error ) {
215
+ hwDeviceMap := make (map [string ]netlink.Link )
216
+ for _ , v := range nics {
217
+ hwDeviceMap [v .Attrs ().HardwareAddr .String ()] = v
204
218
}
205
219
206
- var returnLinks []netlink.Link
220
+ // temporary sessionMap to make it easy to correlate interface addressses with session ip address
221
+ // should speed up identification of interfaces in use with iscsi sessions
222
+ sessionMap := make (map [string ]string )
223
+ for _ , session := range sessions {
224
+ sessionMap [session .IfaceIPaddress ] = ""
225
+ }
226
+
227
+ if err := filterNICSBySession (hwDeviceMap , nics , sessionMap ); err != nil {
228
+ return nil , err
229
+ }
230
+
231
+ if err := filterNICSBySession (hwDeviceMap , vlanNics , sessionMap ); err != nil {
232
+ return nil , err
233
+ }
234
+ logrus .Debugf ("identified following iscsi sessions: %v" , sessionMap )
235
+ // we need to filter the filteredNics to also isolate parent nics if a vlan if is in use
236
+ returnedNics := make ([]netlink.Link , 0 , len (hwDeviceMap ))
237
+ for _ , v := range hwDeviceMap {
238
+ returnedNics = append (returnedNics , v )
239
+ }
240
+ return returnedNics , nil
241
+ }
242
+
243
+ func filterNICSBySession (hwDeviceMap map [string ]netlink.Link , links []netlink.Link , sessionMap map [string ]string ) error {
207
244
for _ , link := range links {
208
- var inuse bool
245
+ logrus . Debugf ( "checking if link %s is in use" , link . Attrs (). Name )
209
246
if getNICState (link .Attrs ().Name ) == NICStateUP {
210
247
iface , err := net .InterfaceByName (link .Attrs ().Name )
211
248
if err != nil {
212
- return nil , fmt .Errorf ("error fetching interface details: %v" , err )
249
+ return fmt .Errorf ("error fetching interface details: %v" , err )
213
250
}
214
251
215
252
addresses , err := iface .Addrs ()
216
253
if err != nil {
217
- return nil , fmt .Errorf ("error fetching addresses from interface: %v" , err )
254
+ return fmt .Errorf ("error fetching addresses from interface: %v" , err )
218
255
}
219
256
220
257
for _ , address := range addresses {
221
258
// interface addresses are in cidr format, and need to be converted before comparison
222
259
// since iscsi session contains just the ip address
223
260
ipAddress , _ , err := net .ParseCIDR (address .String ())
224
261
if err != nil {
225
- return nil , fmt .Errorf ("error parsing ip address: %v" , err )
262
+ return fmt .Errorf ("error parsing ip address: %v" , err )
226
263
}
227
- for _ , session := range sessions {
228
- if session . IfaceIPaddress == ipAddress . String () {
229
- inuse = true
230
- }
264
+ if _ , ok := sessionMap [ ipAddress . String ()]; ok {
265
+ logrus . Debugf ( "filtering interface %s" , link . Attrs (). Name )
266
+ delete ( hwDeviceMap , link . Attrs (). HardwareAddr . String ())
267
+ break //device is already removed, no point checking for other addresses
231
268
}
232
269
}
233
270
}
234
- if ! inuse {
235
- returnLinks = append (returnLinks , link )
236
- }
237
271
}
238
- return returnLinks , nil
272
+ return nil
239
273
}
0 commit comments