Skip to content

Commit 7bf7bb3

Browse files
shemmingerdavem330
authored andcommitted
hv_netvsc: fix network namespace issues with VF support
When finding the parent netvsc device, the search needs to be across all netvsc device instances (independent of network namespace). Find parent device of VF using upper_dev_get routine which searches only adjacent list. Fixes: e8ff40d ("hv_netvsc: improve VF device matching") Signed-off-by: Stephen Hemminger <[email protected]> netns aware byref Signed-off-by: David S. Miller <[email protected]>
1 parent 8cde8f0 commit 7bf7bb3

File tree

2 files changed

+22
-23
lines changed

2 files changed

+22
-23
lines changed

drivers/net/hyperv/hyperv_net.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,8 @@ struct net_device_context {
901901
struct hv_device *device_ctx;
902902
/* netvsc_device */
903903
struct netvsc_device __rcu *nvdev;
904+
/* list of netvsc net_devices */
905+
struct list_head list;
904906
/* reconfigure work */
905907
struct delayed_work dwork;
906908
/* last reconfig time */

drivers/net/hyperv/netvsc_drv.c

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ static int debug = -1;
6767
module_param(debug, int, 0444);
6868
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
6969

70+
static LIST_HEAD(netvsc_dev_list);
71+
7072
static void netvsc_change_rx_flags(struct net_device *net, int change)
7173
{
7274
struct net_device_context *ndev_ctx = netdev_priv(net);
@@ -1781,13 +1783,10 @@ static void netvsc_link_change(struct work_struct *w)
17811783

17821784
static struct net_device *get_netvsc_bymac(const u8 *mac)
17831785
{
1784-
struct net_device *dev;
1785-
1786-
ASSERT_RTNL();
1786+
struct net_device_context *ndev_ctx;
17871787

1788-
for_each_netdev(&init_net, dev) {
1789-
if (dev->netdev_ops != &device_ops)
1790-
continue; /* not a netvsc device */
1788+
list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) {
1789+
struct net_device *dev = hv_get_drvdata(ndev_ctx->device_ctx);
17911790

17921791
if (ether_addr_equal(mac, dev->perm_addr))
17931792
return dev;
@@ -1798,25 +1797,18 @@ static struct net_device *get_netvsc_bymac(const u8 *mac)
17981797

17991798
static struct net_device *get_netvsc_byref(struct net_device *vf_netdev)
18001799
{
1800+
struct net_device_context *net_device_ctx;
18011801
struct net_device *dev;
18021802

1803-
ASSERT_RTNL();
1804-
1805-
for_each_netdev(&init_net, dev) {
1806-
struct net_device_context *net_device_ctx;
1803+
dev = netdev_master_upper_dev_get(vf_netdev);
1804+
if (!dev || dev->netdev_ops != &device_ops)
1805+
return NULL; /* not a netvsc device */
18071806

1808-
if (dev->netdev_ops != &device_ops)
1809-
continue; /* not a netvsc device */
1807+
net_device_ctx = netdev_priv(dev);
1808+
if (!rtnl_dereference(net_device_ctx->nvdev))
1809+
return NULL; /* device is removed */
18101810

1811-
net_device_ctx = netdev_priv(dev);
1812-
if (!rtnl_dereference(net_device_ctx->nvdev))
1813-
continue; /* device is removed */
1814-
1815-
if (rtnl_dereference(net_device_ctx->vf_netdev) == vf_netdev)
1816-
return dev; /* a match */
1817-
}
1818-
1819-
return NULL;
1811+
return dev;
18201812
}
18211813

18221814
/* Called when VF is injecting data into network stack.
@@ -2093,15 +2085,19 @@ static int netvsc_probe(struct hv_device *dev,
20932085
else
20942086
net->max_mtu = ETH_DATA_LEN;
20952087

2096-
ret = register_netdev(net);
2088+
rtnl_lock();
2089+
ret = register_netdevice(net);
20972090
if (ret != 0) {
20982091
pr_err("Unable to register netdev.\n");
20992092
goto register_failed;
21002093
}
21012094

2102-
return ret;
2095+
list_add(&net_device_ctx->list, &netvsc_dev_list);
2096+
rtnl_unlock();
2097+
return 0;
21032098

21042099
register_failed:
2100+
rtnl_unlock();
21052101
rndis_filter_device_remove(dev, nvdev);
21062102
rndis_failed:
21072103
free_percpu(net_device_ctx->vf_stats);
@@ -2147,6 +2143,7 @@ static int netvsc_remove(struct hv_device *dev)
21472143
rndis_filter_device_remove(dev, nvdev);
21482144

21492145
unregister_netdevice(net);
2146+
list_del(&ndev_ctx->list);
21502147

21512148
rtnl_unlock();
21522149
rcu_read_unlock();

0 commit comments

Comments
 (0)