@@ -1215,22 +1215,44 @@ static void netvsc_free_netdev(struct net_device *netdev)
1215
1215
free_netdev (netdev );
1216
1216
}
1217
1217
1218
- static struct net_device * get_netvsc_net_device ( char * mac )
1218
+ static struct net_device * get_netvsc_bymac ( const u8 * mac )
1219
1219
{
1220
- struct net_device * dev , * found = NULL ;
1220
+ struct net_device * dev ;
1221
1221
1222
1222
ASSERT_RTNL ();
1223
1223
1224
1224
for_each_netdev (& init_net , dev ) {
1225
- if (memcmp (dev -> dev_addr , mac , ETH_ALEN ) == 0 ) {
1226
- if (dev -> netdev_ops != & device_ops )
1227
- continue ;
1228
- found = dev ;
1229
- break ;
1230
- }
1225
+ if (dev -> netdev_ops != & device_ops )
1226
+ continue ; /* not a netvsc device */
1227
+
1228
+ if (ether_addr_equal (mac , dev -> perm_addr ))
1229
+ return dev ;
1230
+ }
1231
+
1232
+ return NULL ;
1233
+ }
1234
+
1235
+ static struct net_device * get_netvsc_byref (const struct net_device * vf_netdev )
1236
+ {
1237
+ struct net_device * dev ;
1238
+
1239
+ ASSERT_RTNL ();
1240
+
1241
+ for_each_netdev (& init_net , dev ) {
1242
+ struct net_device_context * net_device_ctx ;
1243
+
1244
+ if (dev -> netdev_ops != & device_ops )
1245
+ continue ; /* not a netvsc device */
1246
+
1247
+ net_device_ctx = netdev_priv (dev );
1248
+ if (net_device_ctx -> nvdev == NULL )
1249
+ continue ; /* device is removed */
1250
+
1251
+ if (net_device_ctx -> vf_netdev == vf_netdev )
1252
+ return dev ; /* a match */
1231
1253
}
1232
1254
1233
- return found ;
1255
+ return NULL ;
1234
1256
}
1235
1257
1236
1258
static int netvsc_register_vf (struct net_device * vf_netdev )
@@ -1239,12 +1261,15 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
1239
1261
struct net_device_context * net_device_ctx ;
1240
1262
struct netvsc_device * netvsc_dev ;
1241
1263
1264
+ if (vf_netdev -> addr_len != ETH_ALEN )
1265
+ return NOTIFY_DONE ;
1266
+
1242
1267
/*
1243
1268
* We will use the MAC address to locate the synthetic interface to
1244
1269
* associate with the VF interface. If we don't find a matching
1245
1270
* synthetic interface, move on.
1246
1271
*/
1247
- ndev = get_netvsc_net_device (vf_netdev -> dev_addr );
1272
+ ndev = get_netvsc_bymac (vf_netdev -> perm_addr );
1248
1273
if (!ndev )
1249
1274
return NOTIFY_DONE ;
1250
1275
@@ -1284,16 +1309,13 @@ static int netvsc_vf_up(struct net_device *vf_netdev)
1284
1309
struct netvsc_device * netvsc_dev ;
1285
1310
struct net_device_context * net_device_ctx ;
1286
1311
1287
- ndev = get_netvsc_net_device (vf_netdev -> dev_addr );
1312
+ ndev = get_netvsc_byref (vf_netdev );
1288
1313
if (!ndev )
1289
1314
return NOTIFY_DONE ;
1290
1315
1291
1316
net_device_ctx = netdev_priv (ndev );
1292
1317
netvsc_dev = net_device_ctx -> nvdev ;
1293
1318
1294
- if (!netvsc_dev || !net_device_ctx -> vf_netdev )
1295
- return NOTIFY_DONE ;
1296
-
1297
1319
netdev_info (ndev , "VF up: %s\n" , vf_netdev -> name );
1298
1320
netvsc_inject_enable (net_device_ctx );
1299
1321
@@ -1322,16 +1344,13 @@ static int netvsc_vf_down(struct net_device *vf_netdev)
1322
1344
struct netvsc_device * netvsc_dev ;
1323
1345
struct net_device_context * net_device_ctx ;
1324
1346
1325
- ndev = get_netvsc_net_device (vf_netdev -> dev_addr );
1347
+ ndev = get_netvsc_byref (vf_netdev );
1326
1348
if (!ndev )
1327
1349
return NOTIFY_DONE ;
1328
1350
1329
1351
net_device_ctx = netdev_priv (ndev );
1330
1352
netvsc_dev = net_device_ctx -> nvdev ;
1331
1353
1332
- if (!netvsc_dev || !net_device_ctx -> vf_netdev )
1333
- return NOTIFY_DONE ;
1334
-
1335
1354
netdev_info (ndev , "VF down: %s\n" , vf_netdev -> name );
1336
1355
netvsc_inject_disable (net_device_ctx );
1337
1356
netvsc_switch_datapath (ndev , false);
@@ -1351,14 +1370,13 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
1351
1370
struct netvsc_device * netvsc_dev ;
1352
1371
struct net_device_context * net_device_ctx ;
1353
1372
1354
- ndev = get_netvsc_net_device (vf_netdev -> dev_addr );
1373
+ ndev = get_netvsc_byref (vf_netdev );
1355
1374
if (!ndev )
1356
1375
return NOTIFY_DONE ;
1357
1376
1358
1377
net_device_ctx = netdev_priv (ndev );
1359
1378
netvsc_dev = net_device_ctx -> nvdev ;
1360
- if (!netvsc_dev || !net_device_ctx -> vf_netdev )
1361
- return NOTIFY_DONE ;
1379
+
1362
1380
netdev_info (ndev , "VF unregistering: %s\n" , vf_netdev -> name );
1363
1381
netvsc_inject_disable (net_device_ctx );
1364
1382
net_device_ctx -> vf_netdev = NULL ;
0 commit comments