lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon, 13 Apr 2015 15:47:56 +0900
From:	Simon Horman <simon.horman@...ronome.com>
To:	Jiri Pirko <jiri@...nulli.us>, Scott Feldman <sfeldma@...il.com>
Cc:	netdev@...r.kernel.org, Simon Horman <simon.horman@...ronome.com>
Subject: [PATCH/RFC net-next 3/4] rocker: forward packets to CPU when a port not bridged

This is intended to be sufficient for the kernel to act as
a fall-back for any packets that are received when a rocker port
is not bridged.

A subsequent patch will build on this one to make use of the port's
unicast routing entries.

Signed-off-by: Simon Horman <simon.horman@...ronome.com>
---
 drivers/net/ethernet/rocker/rocker.c | 56 ++++++++++++++++++++++++++++++++----
 1 file changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
index b88097b26587..d74d53cb59ab 100644
--- a/drivers/net/ethernet/rocker/rocker.c
+++ b/drivers/net/ethernet/rocker/rocker.c
@@ -199,6 +199,8 @@ struct rocker;
 enum {
 	ROCKER_CTRL_LINK_LOCAL_MCAST,
 	ROCKER_CTRL_LOCAL_ARP,
+	ROCKER_CTRL_LOCAL_UNICAST,
+	ROCKER_CTRL_PROMISC,
 	ROCKER_CTRL_IPV4_MCAST,
 	ROCKER_CTRL_IPV6_MCAST,
 	ROCKER_CTRL_DFLT_BRIDGING,
@@ -3129,6 +3131,17 @@ static struct rocker_ctrl {
 		.eth_type = htons(ETH_P_ARP),
 		.acl = true,
 	},
+	[ROCKER_CTRL_LOCAL_UNICAST] = {
+		/* pass local unicast pkts up to CPU */
+		.eth_dst_mask = ff_mac,
+		.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,
@@ -3161,6 +3174,8 @@ static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
 	u32 out_pport = 0;
 	u8 *eth_src = NULL;
 	u8 *eth_src_mask = NULL;
+	const u8 *eth_dst = ctrl->eth_dst ? :
+		rocker_port_uppermost_dev(rocker_port)->dev_addr;
 	__be16 vlan_id_mask = htons(0xffff);
 	u8 ip_proto = 0;
 	u8 ip_proto_mask = 0;
@@ -3172,7 +3187,7 @@ static int rocker_port_ctrl_vlan_acl(struct rocker_port *rocker_port,
 	err = rocker_flow_tbl_acl(rocker_port, flags,
 				  in_pport, in_pport_mask,
 				  eth_src, eth_src_mask,
-				  ctrl->eth_dst, ctrl->eth_dst_mask,
+				  eth_dst, ctrl->eth_dst_mask,
 				  ctrl->eth_type,
 				  vlan_id, vlan_id_mask,
 				  ip_proto, ip_proto_mask,
@@ -3630,13 +3645,20 @@ static int rocker_port_stp_update(struct rocker_port *rocker_port, u8 state)
 		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_UNICAST] = true;
+				want[ROCKER_CTRL_LOCAL_ARP] = true;
+			}
+		}
 		break;
 	}
 
@@ -4027,10 +4049,33 @@ static int rocker_port_set_mac_address(struct net_device *dev, void *p)
 	err = rocker_cmd_set_port_settings_macaddr(rocker_port, addr->sa_data);
 	if (err)
 		return err;
+
+	if (rocker_port->dev->flags & IFF_UP) {
+		err = rocker_port_fwd_disable(rocker_port);
+		if (err)
+			return err;
+	}
+
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+	if (rocker_port->dev->flags & IFF_UP) {
+		err = rocker_port_fwd_enable(rocker_port);
+		if (err)
+			return err;
+	}
+
 	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))
+			rocker_port_fwd_enable(rocker_port);
+}
+
 static int rocker_port_vlan_rx_add_vid(struct net_device *dev,
 				       __be16 proto, u16 vid)
 {
@@ -4230,6 +4275,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_vlan_rx_add_vid		= rocker_port_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid		= rocker_port_vlan_rx_kill_vid,
-- 
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

Powered by Openwall GNU/*/Linux Powered by OpenVZ