kernel: bump 6.1 to 6.1.33
[openwrt/staging/hauke.git] / target / linux / generic / pending-6.1 / 710-bridge-add-knob-for-filtering-rx-tx-BPDU-pack.patch
1 From: Felix Fietkau <nbd@nbd.name>
2 Date: Fri, 27 Aug 2021 12:22:32 +0200
3 Subject: [PATCH] bridge: add knob for filtering rx/tx BPDU packets on a port
4
5 Some devices (e.g. wireless APs) can't have devices behind them be part of
6 a bridge topology with redundant links, due to address limitations.
7 Additionally, broadcast traffic on these devices is somewhat expensive, due to
8 the low data rate and wakeups of clients in powersave mode.
9 This knob can be used to ensure that BPDU packets are never sent or forwarded
10 to/from these devices
11
12 Signed-off-by: Felix Fietkau <nbd@nbd.name>
13 ---
14
15 --- a/include/linux/if_bridge.h
16 +++ b/include/linux/if_bridge.h
17 @@ -59,6 +59,7 @@ struct br_ip_list {
18 #define BR_MRP_LOST_IN_CONT BIT(19)
19 #define BR_TX_FWD_OFFLOAD BIT(20)
20 #define BR_PORT_LOCKED BIT(21)
21 +#define BR_BPDU_FILTER BIT(22)
22
23 #define BR_DEFAULT_AGEING_TIME (300 * HZ)
24
25 --- a/net/bridge/br_forward.c
26 +++ b/net/bridge/br_forward.c
27 @@ -199,6 +199,7 @@ out:
28 void br_flood(struct net_bridge *br, struct sk_buff *skb,
29 enum br_pkt_type pkt_type, bool local_rcv, bool local_orig)
30 {
31 + const unsigned char *dest = eth_hdr(skb)->h_dest;
32 struct net_bridge_port *prev = NULL;
33 struct net_bridge_port *p;
34
35 @@ -214,6 +215,10 @@ void br_flood(struct net_bridge *br, str
36 case BR_PKT_MULTICAST:
37 if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev)
38 continue;
39 + if ((p->flags & BR_BPDU_FILTER) &&
40 + unlikely(is_link_local_ether_addr(dest) &&
41 + dest[5] == 0))
42 + continue;
43 break;
44 case BR_PKT_BROADCAST:
45 if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev)
46 --- a/net/bridge/br_input.c
47 +++ b/net/bridge/br_input.c
48 @@ -344,6 +344,8 @@ static rx_handler_result_t br_handle_fra
49 fwd_mask |= p->group_fwd_mask;
50 switch (dest[5]) {
51 case 0x00: /* Bridge Group Address */
52 + if (p->flags & BR_BPDU_FILTER)
53 + goto drop;
54 /* If STP is turned off,
55 then must forward to keep loop detection */
56 if (p->br->stp_enabled == BR_NO_STP ||
57 --- a/net/bridge/br_sysfs_if.c
58 +++ b/net/bridge/br_sysfs_if.c
59 @@ -240,6 +240,7 @@ BRPORT_ATTR_FLAG(multicast_flood, BR_MCA
60 BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
61 BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS);
62 BRPORT_ATTR_FLAG(isolated, BR_ISOLATED);
63 +BRPORT_ATTR_FLAG(bpdu_filter, BR_BPDU_FILTER);
64
65 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
66 static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
67 @@ -292,6 +293,7 @@ static const struct brport_attribute *br
68 &brport_attr_group_fwd_mask,
69 &brport_attr_neigh_suppress,
70 &brport_attr_isolated,
71 + &brport_attr_bpdu_filter,
72 &brport_attr_backup_port,
73 NULL
74 };
75 --- a/net/bridge/br_stp_bpdu.c
76 +++ b/net/bridge/br_stp_bpdu.c
77 @@ -80,7 +80,8 @@ void br_send_config_bpdu(struct net_brid
78 {
79 unsigned char buf[35];
80
81 - if (p->br->stp_enabled != BR_KERNEL_STP)
82 + if (p->br->stp_enabled != BR_KERNEL_STP ||
83 + (p->flags & BR_BPDU_FILTER))
84 return;
85
86 buf[0] = 0;
87 @@ -127,7 +128,8 @@ void br_send_tcn_bpdu(struct net_bridge_
88 {
89 unsigned char buf[4];
90
91 - if (p->br->stp_enabled != BR_KERNEL_STP)
92 + if (p->br->stp_enabled != BR_KERNEL_STP ||
93 + (p->flags & BR_BPDU_FILTER))
94 return;
95
96 buf[0] = 0;
97 @@ -172,6 +174,9 @@ void br_stp_rcv(const struct stp_proto *
98 if (!(br->dev->flags & IFF_UP))
99 goto out;
100
101 + if (p->flags & BR_BPDU_FILTER)
102 + goto out;
103 +
104 if (p->state == BR_STATE_DISABLED)
105 goto out;
106
107 --- a/include/uapi/linux/if_link.h
108 +++ b/include/uapi/linux/if_link.h
109 @@ -561,6 +561,7 @@ enum {
110 IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
111 IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
112 IFLA_BRPORT_LOCKED,
113 + IFLA_BRPORT_BPDU_FILTER,
114 __IFLA_BRPORT_MAX
115 };
116 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
117 --- a/net/bridge/br_netlink.c
118 +++ b/net/bridge/br_netlink.c
119 @@ -188,6 +188,7 @@ static inline size_t br_port_info_size(v
120 + nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */
121 + nla_total_size(1) /* IFLA_BRPORT_ISOLATED */
122 + nla_total_size(1) /* IFLA_BRPORT_LOCKED */
123 + + nla_total_size(1) /* IFLA_BRPORT_BPDU_FILTER */
124 + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */
125 + nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */
126 + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */
127 @@ -274,7 +275,8 @@ static int br_port_fill_attrs(struct sk_
128 nla_put_u8(skb, IFLA_BRPORT_MRP_IN_OPEN,
129 !!(p->flags & BR_MRP_LOST_IN_CONT)) ||
130 nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) ||
131 - nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)))
132 + nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) ||
133 + nla_put_u8(skb, IFLA_BRPORT_BPDU_FILTER, !!(p->flags & BR_BPDU_FILTER)))
134 return -EMSGSIZE;
135
136 timerval = br_timer_value(&p->message_age_timer);
137 @@ -878,6 +880,7 @@ static const struct nla_policy br_port_p
138 [IFLA_BRPORT_LOCKED] = { .type = NLA_U8 },
139 [IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 },
140 [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 },
141 + [IFLA_BRPORT_BPDU_FILTER] = { .type = NLA_U8 },
142 };
143
144 /* Change the state of the port and notify spanning tree */
145 @@ -943,6 +946,7 @@ static int br_setport(struct net_bridge_
146 br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS, BR_NEIGH_SUPPRESS);
147 br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED);
148 br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED);
149 + br_set_port_flag(p, tb, IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER);
150
151 changed_mask = old_flags ^ p->flags;
152
153 --- a/net/core/rtnetlink.c
154 +++ b/net/core/rtnetlink.c
155 @@ -57,7 +57,7 @@
156 #include "dev.h"
157
158 #define RTNL_MAX_TYPE 50
159 -#define RTNL_SLAVE_MAX_TYPE 40
160 +#define RTNL_SLAVE_MAX_TYPE 41
161
162 struct rtnl_link {
163 rtnl_doit_func doit;
164 @@ -4817,7 +4817,9 @@ int ndo_dflt_bridge_getlink(struct sk_bu
165 brport_nla_put_flag(skb, flags, mask,
166 IFLA_BRPORT_MCAST_FLOOD, BR_MCAST_FLOOD) ||
167 brport_nla_put_flag(skb, flags, mask,
168 - IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD)) {
169 + IFLA_BRPORT_BCAST_FLOOD, BR_BCAST_FLOOD) ||
170 + brport_nla_put_flag(skb, flags, mask,
171 + IFLA_BRPORT_BPDU_FILTER, BR_BPDU_FILTER)) {
172 nla_nest_cancel(skb, protinfo);
173 goto nla_put_failure;
174 }