OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 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 |