generic: revert workarounds for AR8337 switch
[oweals/openwrt.git] / target / linux / generic / backport-4.14 / 090-net-bridge-add-support-for-port-isolation.patch
1 From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
2 Date: Thu, 24 May 2018 11:56:48 +0300
3 Subject: [PATCH] net: bridge: add support for port isolation
4
5 This patch adds support for a new port flag - BR_ISOLATED. If it is set
6 then isolated ports cannot communicate between each other, but they can
7 still communicate with non-isolated ports. The same can be achieved via
8 ACLs but they can't scale with large number of ports and also the
9 complexity of the rules grows. This feature can be used to achieve
10 isolated vlan functionality (similar to pvlan) as well, though currently
11 it will be port-wide (for all vlans on the port). The new test in
12 should_deliver uses data that is already cache hot and the new boolean
13 is used to avoid an additional source port test in should_deliver.
14
15 Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
16 Reviewed-by: Toshiaki Makita <makita.toshiaki@lab.ntt.co.jp>
17 Signed-off-by: David S. Miller <davem@davemloft.net>
18 ---
19
20 --- a/include/uapi/linux/if_link.h
21 +++ b/include/uapi/linux/if_link.h
22 @@ -326,6 +326,8 @@ enum {
23         IFLA_BRPORT_MCAST_TO_UCAST,
24         IFLA_BRPORT_VLAN_TUNNEL,
25         IFLA_BRPORT_BCAST_FLOOD,
26 +       IFLA_BRPORT_NEIGH_SUPPRESS,
27 +       IFLA_BRPORT_ISOLATED,
28         __IFLA_BRPORT_MAX
29  };
30  #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
31 --- a/net/bridge/br_forward.c
32 +++ b/net/bridge/br_forward.c
33 @@ -30,7 +30,8 @@ static inline int should_deliver(const s
34         vg = nbp_vlan_group_rcu(p);
35         return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
36                 br_allowed_egress(vg, skb) && p->state == BR_STATE_FORWARDING &&
37 -               nbp_switchdev_allowed_egress(p, skb);
38 +               nbp_switchdev_allowed_egress(p, skb) &&
39 +               !br_skb_isolated(p, skb);
40  }
41  
42  int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
43 --- a/net/bridge/br_input.c
44 +++ b/net/bridge/br_input.c
45 @@ -170,6 +170,7 @@ int br_handle_frame_finish(struct net *n
46                 goto drop;
47  
48         BR_INPUT_SKB_CB(skb)->brdev = br->dev;
49 +       BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED);
50  
51         if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP))
52                 br_do_proxy_arp(skb, br, vid, p);
53 --- a/net/bridge/br_netlink.c
54 +++ b/net/bridge/br_netlink.c
55 @@ -138,6 +138,7 @@ static inline size_t br_port_info_size(v
56                 + nla_total_size(1)     /* IFLA_BRPORT_PROXYARP */
57                 + nla_total_size(1)     /* IFLA_BRPORT_PROXYARP_WIFI */
58                 + nla_total_size(1)     /* IFLA_BRPORT_VLAN_TUNNEL */
59 +               + nla_total_size(1)     /* IFLA_BRPORT_ISOLATED */
60                 + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */
61                 + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */
62                 + nla_total_size(sizeof(u16))   /* IFLA_BRPORT_DESIGNATED_PORT */
63 @@ -208,7 +209,8 @@ static int br_port_fill_attrs(struct sk_
64                        p->topology_change_ack) ||
65             nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, p->config_pending) ||
66             nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags &
67 -                                                       BR_VLAN_TUNNEL)))
68 +                                                       BR_VLAN_TUNNEL)) ||
69 +           nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)))
70                 return -EMSGSIZE;
71  
72         timerval = br_timer_value(&p->message_age_timer);
73 @@ -637,6 +639,7 @@ static const struct nla_policy br_port_p
74         [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NLA_U8 },
75         [IFLA_BRPORT_MCAST_FLOOD] = { .type = NLA_U8 },
76         [IFLA_BRPORT_BCAST_FLOOD] = { .type = NLA_U8 },
77 +       [IFLA_BRPORT_ISOLATED]  = { .type = NLA_U8 },
78  };
79  
80  /* Change the state of the port and notify spanning tree */
81 @@ -773,6 +776,11 @@ static int br_setport(struct net_bridge_
82                         return err;
83         }
84  #endif
85 +
86 +       err = br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED);
87 +       if (err)
88 +               return err;
89 +
90         br_port_flags_change(p, old_flags ^ p->flags);
91         return 0;
92  }
93 --- a/net/bridge/br_private.h
94 +++ b/net/bridge/br_private.h
95 @@ -407,6 +407,7 @@ struct br_input_skb_cb {
96  #endif
97  
98         bool proxyarp_replied;
99 +       bool src_port_isolated;
100  
101  #ifdef CONFIG_BRIDGE_VLAN_FILTERING
102         bool vlan_filtered;
103 @@ -554,6 +555,14 @@ int br_forward_finish(struct net *net, s
104  void br_flood(struct net_bridge *br, struct sk_buff *skb,
105               enum br_pkt_type pkt_type, bool local_rcv, bool local_orig);
106  
107 +/* return true if both source port and dest port are isolated */
108 +static inline bool br_skb_isolated(const struct net_bridge_port *to,
109 +                                  const struct sk_buff *skb)
110 +{
111 +       return BR_INPUT_SKB_CB(skb)->src_port_isolated &&
112 +              (to->flags & BR_ISOLATED);
113 +}
114 +
115  /* br_if.c */
116  void br_port_carrier_check(struct net_bridge_port *p);
117  int br_add_bridge(struct net *net, const char *name);
118 --- a/net/bridge/br_sysfs_if.c
119 +++ b/net/bridge/br_sysfs_if.c
120 @@ -174,6 +174,7 @@ BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP);
121  BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI);
122  BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD);
123  BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
124 +BRPORT_ATTR_FLAG(isolated, BR_ISOLATED);
125  
126  #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
127  static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
128 @@ -223,6 +224,7 @@ static const struct brport_attribute *br
129         &brport_attr_proxyarp_wifi,
130         &brport_attr_multicast_flood,
131         &brport_attr_broadcast_flood,
132 +       &brport_attr_isolated,
133         NULL
134  };
135  
136 --- a/include/linux/if_bridge.h
137 +++ b/include/linux/if_bridge.h
138 @@ -49,6 +49,7 @@ struct br_ip_list {
139  #define BR_MULTICAST_TO_UNICAST        BIT(12)
140  #define BR_VLAN_TUNNEL         BIT(13)
141  #define BR_BCAST_FLOOD         BIT(14)
142 +#define BR_ISOLATED            BIT(16)
143  
144  #define BR_DEFAULT_AGEING_TIME (300 * HZ)
145