Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0cc3c18 authored by Stephen Hemminger's avatar Stephen Hemminger Committed by Greg Kroah-Hartman
Browse files

hv_netvsc: propagate rx filters to VF



[ Upstream commit bee9d41b37ea6b1f860e5bc0989cf1cf1d7e6ab3 ]

The netvsc device should propagate filters to the SR-IOV VF
device (if present). The flags also need to be propagated to the
VF device as well. This only really matters on local Hyper-V
since Azure does not support multiple addresses.

Signed-off-by: default avatarStephen Hemminger <sthemmin@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ed85935e
Loading
Loading
Loading
Loading
+36 −4
Original line number Diff line number Diff line
@@ -66,10 +66,36 @@ static int debug = -1;
module_param(debug, int, S_IRUGO);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");

static void netvsc_set_multicast_list(struct net_device *net)
static void netvsc_change_rx_flags(struct net_device *net, int change)
{
	struct net_device_context *net_device_ctx = netdev_priv(net);
	struct netvsc_device *nvdev = rtnl_dereference(net_device_ctx->nvdev);
	struct net_device_context *ndev_ctx = netdev_priv(net);
	struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
	int inc;

	if (!vf_netdev)
		return;

	if (change & IFF_PROMISC) {
		inc = (net->flags & IFF_PROMISC) ? 1 : -1;
		dev_set_promiscuity(vf_netdev, inc);
	}

	if (change & IFF_ALLMULTI) {
		inc = (net->flags & IFF_ALLMULTI) ? 1 : -1;
		dev_set_allmulti(vf_netdev, inc);
	}
}

static void netvsc_set_rx_mode(struct net_device *net)
{
	struct net_device_context *ndev_ctx = netdev_priv(net);
	struct net_device *vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev);
	struct netvsc_device *nvdev = rtnl_dereference(ndev_ctx->nvdev);

	if (vf_netdev) {
		dev_uc_sync(vf_netdev, net);
		dev_mc_sync(vf_netdev, net);
	}

	rndis_filter_update(nvdev);
}
@@ -1582,7 +1608,8 @@ static const struct net_device_ops device_ops = {
	.ndo_open =			netvsc_open,
	.ndo_stop =			netvsc_close,
	.ndo_start_xmit =		netvsc_start_xmit,
	.ndo_set_rx_mode =		netvsc_set_multicast_list,
	.ndo_change_rx_flags =		netvsc_change_rx_flags,
	.ndo_set_rx_mode =		netvsc_set_rx_mode,
	.ndo_change_mtu =		netvsc_change_mtu,
	.ndo_validate_addr =		eth_validate_addr,
	.ndo_set_mac_address =		netvsc_set_mac_addr,
@@ -1814,6 +1841,11 @@ static void __netvsc_vf_setup(struct net_device *ndev,
		netdev_warn(vf_netdev,
			    "unable to change mtu to %u\n", ndev->mtu);

	/* set multicast etc flags on VF */
	dev_change_flags(vf_netdev, ndev->flags | IFF_SLAVE);
	dev_uc_sync(vf_netdev, ndev);
	dev_mc_sync(vf_netdev, ndev);

	if (netif_running(ndev)) {
		ret = dev_open(vf_netdev);
		if (ret)