Skip to content

Commit c807d6c

Browse files
longlimsftPaolo Abeni
authored andcommitted
hv_netvsc: Mark VF as slave before exposing it to user-mode
When a VF is being exposed form the kernel, it should be marked as "slave" before exposing to the user-mode. The VF is not usable without netvsc running as master. The user-mode should never see a VF without the "slave" flag. This commit moves the code of setting the slave flag to the time before VF is exposed to user-mode. Cc: [email protected] Fixes: 0c19556 ("netvsc: transparent VF management") Signed-off-by: Long Li <[email protected]> Signed-off-by: Haiyang Zhang <[email protected]> Acked-by: Stephen Hemminger <[email protected]> Acked-by: Dexuan Cui <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 8552085 commit c807d6c

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

drivers/net/hyperv/netvsc_drv.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2206,9 +2206,6 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
22062206
goto upper_link_failed;
22072207
}
22082208

2209-
/* set slave flag before open to prevent IPv6 addrconf */
2210-
vf_netdev->flags |= IFF_SLAVE;
2211-
22122209
schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT);
22132210

22142211
call_netdevice_notifiers(NETDEV_JOIN, vf_netdev);
@@ -2315,23 +2312,38 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
23152312

23162313
}
23172314

2318-
/* Fallback path to check synthetic vf with
2319-
* help of mac addr
2315+
/* Fallback path to check synthetic vf with help of mac addr.
2316+
* Because this function can be called before vf_netdev is
2317+
* initialized (NETDEV_POST_INIT) when its perm_addr has not been copied
2318+
* from dev_addr, also try to match to its dev_addr.
2319+
* Note: On Hyper-V and Azure, it's not possible to set a MAC address
2320+
* on a VF that matches to the MAC of a unrelated NETVSC device.
23202321
*/
23212322
list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
23222323
ndev = hv_get_drvdata(ndev_ctx->device_ctx);
2323-
if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr)) {
2324-
netdev_notice(vf_netdev,
2325-
"falling back to mac addr based matching\n");
2324+
if (ether_addr_equal(vf_netdev->perm_addr, ndev->perm_addr) ||
2325+
ether_addr_equal(vf_netdev->dev_addr, ndev->perm_addr))
23262326
return ndev;
2327-
}
23282327
}
23292328

23302329
netdev_notice(vf_netdev,
23312330
"no netdev found for vf serial:%u\n", serial);
23322331
return NULL;
23332332
}
23342333

2334+
static int netvsc_prepare_bonding(struct net_device *vf_netdev)
2335+
{
2336+
struct net_device *ndev;
2337+
2338+
ndev = get_netvsc_byslot(vf_netdev);
2339+
if (!ndev)
2340+
return NOTIFY_DONE;
2341+
2342+
/* set slave flag before open to prevent IPv6 addrconf */
2343+
vf_netdev->flags |= IFF_SLAVE;
2344+
return NOTIFY_DONE;
2345+
}
2346+
23352347
static int netvsc_register_vf(struct net_device *vf_netdev)
23362348
{
23372349
struct net_device_context *net_device_ctx;
@@ -2758,6 +2770,8 @@ static int netvsc_netdev_event(struct notifier_block *this,
27582770
return NOTIFY_DONE;
27592771

27602772
switch (event) {
2773+
case NETDEV_POST_INIT:
2774+
return netvsc_prepare_bonding(event_dev);
27612775
case NETDEV_REGISTER:
27622776
return netvsc_register_vf(event_dev);
27632777
case NETDEV_UNREGISTER:

0 commit comments

Comments
 (0)