[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1436415931-16469-1-git-send-email-simon.horman@netronome.com>
Date: Thu, 9 Jul 2015 13:25:31 +0900
From: Simon Horman <simon.horman@...ronome.com>
To: Scott Feldman <sfeldma@...il.com>, Jiri Pirko <jiri@...nulli.us>
Cc: netdev@...r.kernel.org, Simon Horman <simon.horman@...ronome.com>
Subject: [PATCH/RFC net-next] rocker: forward packets to CPU when a port in promiscuous mode
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@...ronome.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
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists