netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Simon Horman <simon.horman@netronome.com>
To: Scott Feldman <sfeldma@gmail.com>, Jiri Pirko <jiri@resnulli.us>
Cc: netdev@vger.kernel.org, Simon Horman <simon.horman@netronome.com>
Subject: [PATCH/RFC net-next] rocker: forward packets to CPU when a port in promiscuous mode
Date: Thu,  9 Jul 2015 13:25:31 +0900	[thread overview]
Message-ID: <1436415931-16469-1-git-send-email-simon.horman@netronome.com> (raw)

This change allows the CPU to see all packets seen by a port when the
netdev associated with the port is in promiscuous mode.

This change was previously posted as part of a larger patch and in turn
patchset which also aimed to allow rocker interfaces to receive packets
when not bridged. That problem has subsequently been addressed in a
different way by Scott Feldman.

When this change was previously posted Scott indicated that he had some
reservations about sending all packets from a switch to the CPU. The
purpose of posting this patch is to start discussion of weather this
approach is appropriate and if not how else we might move forwards.

In my opinion if host doesn't want all packets its shouldn't put a port
in promiscuous mode. But perhaps that is an overly naïve view to take.

My main motivation for this change at this time is to allow rocker to
work with Open vSwitch and it appears that this change is sufficient to
reach that goal. Another approach might be to teach
rocker_port_master_changed() about Open vSwitch.

In the longer term I believe Open vSwitch should be able to program
flows into rocker 'hardware' and thus not all packets would reach the CPU.

Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
 drivers/net/ethernet/rocker/rocker.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index 2d8578cade03..9e812b85b421 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -199,6 +199,7 @@ struct rocker;
 enum {
 	ROCKER_CTRL_LINK_LOCAL_MCAST,
 	ROCKER_CTRL_LOCAL_ARP,
+	ROCKER_CTRL_PROMISC,
 	ROCKER_CTRL_IPV4_MCAST,
 	ROCKER_CTRL_IPV6_MCAST,
 	ROCKER_CTRL_DFLT_BRIDGING,
@@ -3222,6 +3223,12 @@ static struct rocker_ctrl {
 		.eth_type = htons(ETH_P_ARP),
 		.acl = true,
 	},
+	[ROCKER_CTRL_PROMISC] = {
+		/* pass all pkts up to CPU */
+		.eth_dst = zero_mac,
+		.eth_dst_mask = zero_mac,
+		.acl = true,
+	},
 	[ROCKER_CTRL_IPV4_MCAST] = {
 		/* pass IPv4 mcast pkts up to CPU, RFC 1112 */
 		.eth_dst = ipv4_mcast,
@@ -3755,13 +3762,19 @@ static int rocker_port_stp_update(struct rocker_port *rocker_port,
 		break;
 	case BR_STATE_LEARNING:
 	case BR_STATE_FORWARDING:
-		want[ROCKER_CTRL_LINK_LOCAL_MCAST] = true;
+		if (!(rocker_port->dev->flags & IFF_PROMISC))
+			want[ROCKER_CTRL_LINK_LOCAL_MCAST] = true;
 		want[ROCKER_CTRL_IPV4_MCAST] = true;
 		want[ROCKER_CTRL_IPV6_MCAST] = true;
-		if (rocker_port_is_bridged(rocker_port))
+		if (rocker_port_is_bridged(rocker_port)) {
 			want[ROCKER_CTRL_DFLT_BRIDGING] = true;
-		else
-			want[ROCKER_CTRL_LOCAL_ARP] = true;
+		} else {
+			if (rocker_port->dev->flags & IFF_PROMISC) {
+				want[ROCKER_CTRL_PROMISC] = true;
+			} else {
+				want[ROCKER_CTRL_LOCAL_ARP] = true;
+			}
+		}
 		break;
 	}
 
@@ -4152,6 +4165,17 @@ static int rocker_port_set_mac_address(struct net_device *dev, void *p)
 	return 0;
 }
 
+static void rocker_port_change_rx_flags(struct net_device *dev, int change)
+{
+	struct rocker_port *rocker_port = netdev_priv(dev);
+
+	if (change & IFF_PROMISC && rocker_port->dev->flags & IFF_UP)
+		if (!rocker_port_fwd_disable(rocker_port,
+					     SWITCHDEV_TRANS_NONE, 0))
+			rocker_port_fwd_enable(rocker_port,
+					       SWITCHDEV_TRANS_NONE, 0);
+}
+
 static int rocker_port_get_phys_port_name(struct net_device *dev,
 					  char *buf, size_t len)
 {
@@ -4171,6 +4195,7 @@ static const struct net_device_ops rocker_port_netdev_ops = {
 	.ndo_open			= rocker_port_open,
 	.ndo_stop			= rocker_port_stop,
 	.ndo_start_xmit			= rocker_port_xmit,
+	.ndo_change_rx_flags		= rocker_port_change_rx_flags,
 	.ndo_set_mac_address		= rocker_port_set_mac_address,
 	.ndo_bridge_getlink		= switchdev_port_bridge_getlink,
 	.ndo_bridge_setlink		= switchdev_port_bridge_setlink,
-- 
2.1.4

             reply	other threads:[~2015-07-09  4:27 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-09  4:25 Simon Horman [this message]
2015-07-09  5:38 ` [PATCH/RFC net-next] rocker: forward packets to CPU when a port in promiscuous mode John Fastabend
2015-07-14  6:37 ` Scott Feldman
2015-07-15  4:45   ` Simon Horman
2015-07-15  5:32     ` Scott Feldman
2015-07-15  6:34       ` Simon Horman
2015-07-15  7:18         ` Scott Feldman
2015-07-15  7:54           ` Simon Horman
2015-07-15 14:50             ` Scott Feldman
2015-07-16  1:41               ` Simon Horman

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=1436415931-16469-1-git-send-email-simon.horman@netronome.com \
    --to=simon.horman@netronome.com \
    --cc=jiri@resnulli.us \
    --cc=netdev@vger.kernel.org \
    --cc=sfeldma@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).