All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: kys@microsoft.com, haiyangz@microsoft.com, sthemmin@microsoft.com
Cc: devel@linuxdriverproject.org, netdev@vger.kernel.org
Subject: [PATCH net 8/9] hv_netvsc: propagate rx filters to VF
Date: Thu,  1 Mar 2018 10:27:55 -0800	[thread overview]
Message-ID: <20180301182756.23027-9-sthemmin@microsoft.com> (raw)
In-Reply-To: <20180301182756.23027-1-sthemmin@microsoft.com>

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.

The rx filter management in netvsc device does not need to be done
in a work queue since it is called with RTNL held.

Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
 drivers/net/hyperv/hyperv_net.h   |  4 +---
 drivers/net/hyperv/netvsc_drv.c   | 35 ++++++++++++++++++++++++++++++-----
 drivers/net/hyperv/rndis_filter.c | 35 ++++++++++++-----------------------
 3 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 0db3bd1ea06f..a4e1ebba84cf 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -172,8 +172,6 @@ struct rndis_device {
 	spinlock_t request_lock;
 	struct list_head req_list;
 
-	struct work_struct mcast_work;
-
 	bool link_state;        /* 0 - link up, 1 - link down */
 
 	u8 hw_mac_adr[ETH_ALEN];
@@ -216,7 +214,7 @@ int rndis_filter_open(struct netvsc_device *nvdev);
 int rndis_filter_close(struct netvsc_device *nvdev);
 struct netvsc_device *rndis_filter_device_add(struct hv_device *dev,
 					      struct netvsc_device_info *info);
-void rndis_filter_update(struct netvsc_device *nvdev);
+void rndis_filter_update(struct netvsc_device *nvdev, unsigned int flags);
 void rndis_filter_device_remove(struct hv_device *dev,
 				struct netvsc_device *nvdev);
 int rndis_filter_set_rss_param(struct rndis_device *rdev,
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index fa6cf18e7719..1909c58e0a7e 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -66,12 +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);
+	struct netvsc_device *nvdev = rtnl_dereference(ndev_ctx->nvdev);
+
+	if (vf_netdev) {
+		if (change & IFF_PROMISC)
+			dev_set_promiscuity(net,
+				    (net->flags & IFF_PROMISC) ? 1 : -1);
+
+		if (change & IFF_ALLMULTI)
+			dev_set_allmulti(net,
+				 (net->flags & IFF_ALLMULTI) ? 1 : -1);
+	}
 
-	rndis_filter_update(nvdev);
+	if (change & (IFF_PROMISC | IFF_ALLMULTI))
+		rndis_filter_update(nvdev, net->flags);
+}
+
+/* Hyper-V vswitch does not support filtering but VF does */
+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);
+
+	if (vf_netdev) {
+		dev_uc_sync(vf_netdev, net);
+		dev_mc_sync(vf_netdev, net);
+	}
 }
 
 static int netvsc_open(struct net_device *net)
@@ -1575,7 +1599,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,
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 3ce11361634f..199ec6da6bde 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -32,8 +32,6 @@
 
 #include "hyperv_net.h"
 
-static void rndis_set_multicast(struct work_struct *w);
-
 #define RNDIS_EXT_LEN PAGE_SIZE
 struct rndis_request {
 	struct list_head list_ent;
@@ -78,7 +76,6 @@ static struct rndis_device *get_rndis_device(void)
 	spin_lock_init(&device->request_lock);
 
 	INIT_LIST_HEAD(&device->req_list);
-	INIT_WORK(&device->mcast_work, rndis_set_multicast);
 
 	device->state = RNDIS_DEV_UNINITIALIZED;
 
@@ -846,26 +843,21 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev,
 	return ret;
 }
 
-static void rndis_set_multicast(struct work_struct *w)
+void rndis_filter_update(struct netvsc_device *nvdev,
+			 unsigned int flags)
 {
-	struct rndis_device *rdev
-		= container_of(w, struct rndis_device, mcast_work);
+	u32 filter = NDIS_PACKET_TYPE_DIRECTED;
 
-	if (rdev->ndev->flags & IFF_PROMISC)
-		rndis_filter_set_packet_filter(rdev,
-					       NDIS_PACKET_TYPE_PROMISCUOUS);
-	else
-		rndis_filter_set_packet_filter(rdev,
-					       NDIS_PACKET_TYPE_BROADCAST |
-					       NDIS_PACKET_TYPE_ALL_MULTICAST |
-					       NDIS_PACKET_TYPE_DIRECTED);
-}
-
-void rndis_filter_update(struct netvsc_device *nvdev)
-{
-	struct rndis_device *rdev = nvdev->extension;
+	if (flags & IFF_PROMISC) {
+		filter = NDIS_PACKET_TYPE_PROMISCUOUS;
+	} else {
+		if (flags & IFF_ALLMULTI)
+			flags |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+		if (flags & IFF_BROADCAST)
+			flags |= NDIS_PACKET_TYPE_BROADCAST;
+	}
 
-	schedule_work(&rdev->mcast_work);
+	rndis_filter_set_packet_filter(nvdev->extension, filter);
 }
 
 static int rndis_filter_init_device(struct rndis_device *dev,
@@ -995,9 +987,6 @@ static int rndis_filter_close_device(struct rndis_device *dev)
 	if (dev->state != RNDIS_DEV_DATAINITIALIZED)
 		return 0;
 
-	/* Make sure rndis_set_multicast doesn't re-enable filter! */
-	cancel_work_sync(&dev->mcast_work);
-
 	ret = rndis_filter_set_packet_filter(dev, 0);
 	if (ret == -ENODEV)
 		ret = 0;
-- 
2.16.1

  parent reply	other threads:[~2018-03-01 18:27 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-01 18:27 [PATCH net 0/9] hv_netvsc: minor bug fixes Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 1/9] hv_netvsc: avoid retry on send during shutdown Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 2/9] hv_netvsc: only wake transmit queue if link is up Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 3/9] hv_netvsc: fix error unwind handling if vmbus_open fails Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 4/9] hv_netvsc: cancel subchannel setup before halting device Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 5/9] hv_netvsc: fix race in napi poll when rescheduling Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 6/9] hv_netvsc: use napi_schedule_irqoff Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 7/9] hv_netvsc: don't need full irqsave for request_lock Stephen Hemminger
2018-03-01 18:27 ` Stephen Hemminger [this message]
2018-03-01 21:56   ` [PATCH net 8/9] hv_netvsc: propagate rx filters to VF Jakub Kicinski
2018-03-01 23:46   ` Stephen Hemminger
2018-03-01 18:27 ` [PATCH net 9/9] hv_netvsc: defer queue selection " Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180301182756.23027-9-sthemmin@microsoft.com \
    --to=stephen@networkplumber.org \
    --cc=devel@linuxdriverproject.org \
    --cc=haiyangz@microsoft.com \
    --cc=kys@microsoft.com \
    --cc=netdev@vger.kernel.org \
    --cc=sthemmin@microsoft.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.