kernel: replace bridge port isolate hack with upstream patch backport on 4.14
authorFelix Fietkau <nbd@nbd.name>
Wed, 4 Jul 2018 18:14:08 +0000 (20:14 +0200)
committerJo-Philipp Wich <jo@mein.io>
Tue, 18 Dec 2018 08:45:59 +0000 (09:45 +0100)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
(backported from 21ee8ce9b52f8ae4a6babf4032f71e2d4d56392b)
(rebased patches)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
target/linux/generic/backport-4.14/090-net-bridge-add-support-for-port-isolation.patch [new file with mode: 0644]
target/linux/generic/hack-4.14/640-bridge-only-accept-EAP-locally.patch
target/linux/generic/hack-4.14/641-bridge_port_isolate.patch [deleted file]
target/linux/generic/pending-4.14/150-bridge_allow_receiption_on_disabled_port.patch

diff --git a/target/linux/generic/backport-4.14/090-net-bridge-add-support-for-port-isolation.patch b/target/linux/generic/backport-4.14/090-net-bridge-add-support-for-port-isolation.patch
new file mode 100644 (file)
index 0000000..6237177
--- /dev/null
@@ -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)
index 83c9cf7..0dbb8ee 100644 (file)
@@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/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;
  
 -      BR_INPUT_SKB_CB(skb)->brdev = br->dev;
--
-       if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
-               br_do_proxy_arp(skb, br, vid, p);
+       BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED);
  
+       if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
diff --git a/target/linux/generic/hack-4.14/641-bridge_port_isolate.patch b/target/linux/generic/hack-4.14/641-bridge_port_isolate.patch
deleted file mode 100644 (file)
index 43e71ee..0000000
+++ /dev/null
@@ -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
- };
index 0326731..9fcffde 100644 (file)
@@ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/net/bridge/br_input.c
 +++ b/net/bridge/br_input.c
-@@ -238,7 +238,8 @@ static int br_handle_local_finish(struct
+@@ -239,7 +239,8 @@ static int br_handle_local_finish(struct
  {
        struct net_bridge_port *p = br_port_get_rcu(skb->dev);
  
@@ -25,7 +25,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        BR_INPUT_SKB_CB(skb)->brdev = p->br->dev;
        br_pass_frame_up(skb);
-@@ -326,6 +327,15 @@ rx_handler_result_t br_handle_frame(stru
+@@ -327,6 +328,15 @@ rx_handler_result_t br_handle_frame(stru
  
  forward:
        switch (p->state) {