mirror of https://github.com/hak5/openwrt.git
kernel: replace bridge port isolate hack with upstream patch backport on 4.14
Signed-off-by: Felix Fietkau <nbd@nbd.name>openwrt-19.07
parent
68f9921ed8
commit
21ee8ce9b5
|
@ -0,0 +1,145 @@
|
||||||
|
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
|
||||||
|
Date: Thu, 24 May 2018 11:56:48 +0300
|
||||||
|
Subject: [PATCH] net: bridge: add support for port isolation
|
||||||
|
|
||||||
|
This patch adds support for a new port flag - BR_ISOLATED. If it is set
|
||||||
|
then isolated ports cannot communicate between each other, but they can
|
||||||
|
still communicate with non-isolated ports. The same can be achieved via
|
||||||
|
ACLs but they can't scale with large number of ports and also the
|
||||||
|
complexity of the rules grows. This feature can be used to achieve
|
||||||
|
isolated vlan functionality (similar to pvlan) as well, though currently
|
||||||
|
it will be port-wide (for all vlans on the port). The new test in
|
||||||
|
should_deliver uses data that is already cache hot and the new boolean
|
||||||
|
is used to avoid an additional source port test in should_deliver.
|
||||||
|
|
||||||
|
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
|
||||||
|
Reviewed-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
|
||||||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/include/uapi/linux/if_link.h
|
||||||
|
+++ b/include/uapi/linux/if_link.h
|
||||||
|
@@ -326,6 +326,8 @@ enum {
|
||||||
|
IFLA_BRPORT_MCAST_TO_UCAST,
|
||||||
|
IFLA_BRPORT_VLAN_TUNNEL,
|
||||||
|
IFLA_BRPORT_BCAST_FLOOD,
|
||||||
|
+ IFLA_BRPORT_NEIGH_SUPPRESS,
|
||||||
|
+ IFLA_BRPORT_ISOLATED,
|
||||||
|
__IFLA_BRPORT_MAX
|
||||||
|
};
|
||||||
|
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
|
||||||
|
--- a/net/bridge/br_forward.c
|
||||||
|
+++ b/net/bridge/br_forward.c
|
||||||
|
@@ -30,7 +30,8 @@ static inline int should_deliver(const s
|
||||||
|
vg = nbp_vlan_group_rcu(p);
|
||||||
|
return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
|
||||||
|
br_allowed_egress(vg, skb) && p->state == BR_STATE_FORWARDING &&
|
||||||
|
- nbp_switchdev_allowed_egress(p, skb);
|
||||||
|
+ nbp_switchdev_allowed_egress(p, skb) &&
|
||||||
|
+ !br_skb_isolated(p, skb);
|
||||||
|
}
|
||||||
|
|
||||||
|
int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
|
||||||
|
--- a/net/bridge/br_input.c
|
||||||
|
+++ b/net/bridge/br_input.c
|
||||||
|
@@ -170,6 +170,7 @@ int br_handle_frame_finish(struct net *n
|
||||||
|
goto drop;
|
||||||
|
|
||||||
|
BR_INPUT_SKB_CB(skb)->brdev = br->dev;
|
||||||
|
+ BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
|
||||||
|
br_do_proxy_arp(skb, br, vid, p);
|
||||||
|
--- a/net/bridge/br_netlink.c
|
||||||
|
+++ b/net/bridge/br_netlink.c
|
||||||
|
@@ -138,6 +138,7 @@ static inline size_t br_port_info_size(v
|
||||||
|
+ nla_total_size(1) /* IFLA_BRPORT_PROXYARP */
|
||||||
|
+ nla_total_size(1) /* IFLA_BRPORT_PROXYARP_WIFI */
|
||||||
|
+ nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */
|
||||||
|
+ + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */
|
||||||
|
+ nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */
|
||||||
|
+ nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */
|
||||||
|
+ nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */
|
||||||
|
@@ -208,7 +209,8 @@ static int br_port_fill_attrs(struct sk_
|
||||||
|
p->topology_change_ack) ||
|
||||||
|
nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, p->config_pending) ||
|
||||||
|
nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags &
|
||||||
|
- BR_VLAN_TUNNEL)))
|
||||||
|
+ BR_VLAN_TUNNEL)) ||
|
||||||
|
+ nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)))
|
||||||
|
return -EMSGSIZE;
|
||||||
|
|
||||||
|
timerval = br_timer_value(&p->message_age_timer);
|
||||||
|
@@ -637,6 +639,7 @@ static const struct nla_policy br_port_p
|
||||||
|
[IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NLA_U8 },
|
||||||
|
[IFLA_BRPORT_MCAST_FLOOD] = { .type = NLA_U8 },
|
||||||
|
[IFLA_BRPORT_BCAST_FLOOD] = { .type = NLA_U8 },
|
||||||
|
+ [IFLA_BRPORT_ISOLATED] = { .type = NLA_U8 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Change the state of the port and notify spanning tree */
|
||||||
|
@@ -773,6 +776,11 @@ static int br_setport(struct net_bridge_
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+ err = br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED);
|
||||||
|
+ if (err)
|
||||||
|
+ return err;
|
||||||
|
+
|
||||||
|
br_port_flags_change(p, old_flags ^ p->flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--- a/net/bridge/br_private.h
|
||||||
|
+++ b/net/bridge/br_private.h
|
||||||
|
@@ -407,6 +407,7 @@ struct br_input_skb_cb {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool proxyarp_replied;
|
||||||
|
+ bool src_port_isolated;
|
||||||
|
|
||||||
|
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
|
||||||
|
bool vlan_filtered;
|
||||||
|
@@ -554,6 +555,14 @@ int br_forward_finish(struct net *net, s
|
||||||
|
void br_flood(struct net_bridge *br, struct sk_buff *skb,
|
||||||
|
enum br_pkt_type pkt_type, bool local_rcv, bool local_orig);
|
||||||
|
|
||||||
|
+/* return true if both source port and dest port are isolated */
|
||||||
|
+static inline bool br_skb_isolated(const struct net_bridge_port *to,
|
||||||
|
+ const struct sk_buff *skb)
|
||||||
|
+{
|
||||||
|
+ return BR_INPUT_SKB_CB(skb)->src_port_isolated &&
|
||||||
|
+ (to->flags & BR_ISOLATED);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* br_if.c */
|
||||||
|
void br_port_carrier_check(struct net_bridge_port *p);
|
||||||
|
int br_add_bridge(struct net *net, const char *name);
|
||||||
|
--- a/net/bridge/br_sysfs_if.c
|
||||||
|
+++ b/net/bridge/br_sysfs_if.c
|
||||||
|
@@ -174,6 +174,7 @@ BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP);
|
||||||
|
BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI);
|
||||||
|
BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD);
|
||||||
|
BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
|
||||||
|
+BRPORT_ATTR_FLAG(isolated, BR_ISOLATED);
|
||||||
|
|
||||||
|
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
|
||||||
|
static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
|
||||||
|
@@ -223,6 +224,7 @@ static const struct brport_attribute *br
|
||||||
|
&brport_attr_proxyarp_wifi,
|
||||||
|
&brport_attr_multicast_flood,
|
||||||
|
&brport_attr_broadcast_flood,
|
||||||
|
+ &brport_attr_isolated,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
--- a/include/linux/if_bridge.h
|
||||||
|
+++ b/include/linux/if_bridge.h
|
||||||
|
@@ -49,6 +49,7 @@ struct br_ip_list {
|
||||||
|
#define BR_MULTICAST_TO_UNICAST BIT(12)
|
||||||
|
#define BR_VLAN_TUNNEL BIT(13)
|
||||||
|
#define BR_BCAST_FLOOD BIT(14)
|
||||||
|
+#define BR_ISOLATED BIT(16)
|
||||||
|
|
||||||
|
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
||||||
|
|
|
@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
|
|
||||||
--- a/net/bridge/br_input.c
|
--- a/net/bridge/br_input.c
|
||||||
+++ b/net/bridge/br_input.c
|
+++ b/net/bridge/br_input.c
|
||||||
@@ -166,11 +166,14 @@ int br_handle_frame_finish(struct net *n
|
@@ -166,10 +166,14 @@ int br_handle_frame_finish(struct net *n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||||
goto drop;
|
goto drop;
|
||||||
|
|
||||||
- BR_INPUT_SKB_CB(skb)->brdev = br->dev;
|
- BR_INPUT_SKB_CB(skb)->brdev = br->dev;
|
||||||
-
|
BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED);
|
||||||
if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
|
|
||||||
br_do_proxy_arp(skb, br, vid, p);
|
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
From e988390850731aa1697ed09d47b0932fac1af175 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Felix Fietkau <nbd@nbd.name>
|
|
||||||
Date: Fri, 7 Jul 2017 17:20:03 +0200
|
|
||||||
Subject: bridge: port isolate
|
|
||||||
|
|
||||||
Isolating individual bridge ports
|
|
||||||
|
|
||||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|
||||||
---
|
|
||||||
include/linux/if_bridge.h | 1 +
|
|
||||||
net/bridge/br_forward.c | 5 +++++
|
|
||||||
net/bridge/br_input.c | 3 +++
|
|
||||||
net/bridge/br_sysfs_if.c | 2 ++
|
|
||||||
4 files changed, 11 insertions(+)
|
|
||||||
|
|
||||||
--- a/include/linux/if_bridge.h
|
|
||||||
+++ b/include/linux/if_bridge.h
|
|
||||||
@@ -49,6 +49,7 @@ struct br_ip_list {
|
|
||||||
#define BR_MULTICAST_TO_UNICAST BIT(12)
|
|
||||||
#define BR_VLAN_TUNNEL BIT(13)
|
|
||||||
#define BR_BCAST_FLOOD BIT(14)
|
|
||||||
+#define BR_ISOLATE_MODE BIT(15)
|
|
||||||
|
|
||||||
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
|
|
||||||
|
|
||||||
--- a/net/bridge/br_forward.c
|
|
||||||
+++ b/net/bridge/br_forward.c
|
|
||||||
@@ -141,6 +141,9 @@ static int deliver_clone(const struct ne
|
|
||||||
void br_forward(const struct net_bridge_port *to,
|
|
||||||
struct sk_buff *skb, bool local_rcv, bool local_orig)
|
|
||||||
{
|
|
||||||
+ if (to->flags & BR_ISOLATE_MODE && !local_orig)
|
|
||||||
+ to = NULL;
|
|
||||||
+
|
|
||||||
if (to && should_deliver(to, skb)) {
|
|
||||||
if (local_rcv)
|
|
||||||
deliver_clone(to, skb, local_orig);
|
|
||||||
@@ -183,6 +186,8 @@ void br_flood(struct net_bridge *br, str
|
|
||||||
struct net_bridge_port *p;
|
|
||||||
|
|
||||||
list_for_each_entry_rcu(p, &br->port_list, list) {
|
|
||||||
+ if (!local_orig && (p->flags & BR_ISOLATE_MODE))
|
|
||||||
+ continue;
|
|
||||||
/* Do not flood unicast traffic to ports that turn it off, nor
|
|
||||||
* other traffic if flood off, except for traffic we originate
|
|
||||||
*/
|
|
||||||
--- a/net/bridge/br_input.c
|
|
||||||
+++ b/net/bridge/br_input.c
|
|
||||||
@@ -177,6 +177,9 @@ int br_handle_frame_finish(struct net *n
|
|
||||||
if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
|
|
||||||
br_do_proxy_arp(skb, br, vid, p);
|
|
||||||
|
|
||||||
+ if (p->flags & BR_ISOLATE_MODE)
|
|
||||||
+ return br_pass_frame_up(skb);
|
|
||||||
+
|
|
||||||
switch (pkt_type) {
|
|
||||||
case BR_PKT_MULTICAST:
|
|
||||||
mdst = br_mdb_get(br, skb, vid);
|
|
||||||
--- a/net/bridge/br_sysfs_if.c
|
|
||||||
+++ b/net/bridge/br_sysfs_if.c
|
|
||||||
@@ -174,6 +174,7 @@ BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP);
|
|
||||||
BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI);
|
|
||||||
BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD);
|
|
||||||
BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
|
|
||||||
+BRPORT_ATTR_FLAG(isolated, BR_ISOLATE_MODE);
|
|
||||||
|
|
||||||
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
|
|
||||||
static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
|
|
||||||
@@ -223,6 +224,7 @@ static const struct brport_attribute *br
|
|
||||||
&brport_attr_proxyarp_wifi,
|
|
||||||
&brport_attr_multicast_flood,
|
|
||||||
&brport_attr_broadcast_flood,
|
|
||||||
+ &brport_attr_isolated,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
Loading…
Reference in New Issue