1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/err.h>
15#include <linux/slab.h>
16#include <linux/kernel.h>
17#include <linux/netdevice.h>
18#include <linux/netpoll.h>
19#include <linux/skbuff.h>
20#include <linux/if_vlan.h>
21#include <linux/netfilter_bridge.h>
22#include "br_private.h"
23
24
25static inline int should_deliver(const struct net_bridge_port *p,
26 const struct sk_buff *skb)
27{
28 struct net_bridge_vlan_group *vg;
29
30 vg = nbp_vlan_group_rcu(p);
31 return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
32 br_allowed_egress(vg, skb) && p->state == BR_STATE_FORWARDING &&
33 nbp_switchdev_allowed_egress(p, skb) &&
34 !br_skb_isolated(p, skb);
35}
36
37int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
38{
39 if (!is_skb_forwardable(skb->dev, skb))
40 goto drop;
41
42 skb_push(skb, ETH_HLEN);
43 br_drop_fake_rtable(skb);
44
45 if (skb->ip_summed == CHECKSUM_PARTIAL &&
46 (skb->protocol == htons(ETH_P_8021Q) ||
47 skb->protocol == htons(ETH_P_8021AD))) {
48 int depth;
49
50 if (!__vlan_get_protocol(skb, skb->protocol, &depth))
51 goto drop;
52
53 skb_set_network_header(skb, depth);
54 }
55
56 dev_queue_xmit(skb);
57
58 return 0;
59
60drop:
61 kfree_skb(skb);
62 return 0;
63}
64EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit);
65
66int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
67{
68 return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING,
69 net, sk, skb, NULL, skb->dev,
70 br_dev_queue_push_xmit);
71
72}
73EXPORT_SYMBOL_GPL(br_forward_finish);
74
75static void __br_forward(const struct net_bridge_port *to,
76 struct sk_buff *skb, bool local_orig)
77{
78 struct net_bridge_vlan_group *vg;
79 struct net_device *indev;
80 struct net *net;
81 int br_hook;
82
83 vg = nbp_vlan_group_rcu(to);
84 skb = br_handle_vlan(to->br, to, vg, skb);
85 if (!skb)
86 return;
87
88 indev = skb->dev;
89 skb->dev = to->dev;
90 if (!local_orig) {
91 if (skb_warn_if_lro(skb)) {
92 kfree_skb(skb);
93 return;
94 }
95 br_hook = NF_BR_FORWARD;
96 skb_forward_csum(skb);
97 net = dev_net(indev);
98 } else {
99 if (unlikely(netpoll_tx_running(to->br->dev))) {
100 if (!is_skb_forwardable(skb->dev, skb)) {
101 kfree_skb(skb);
102 } else {
103 skb_push(skb, ETH_HLEN);
104 br_netpoll_send_skb(to, skb);
105 }
106 return;
107 }
108 br_hook = NF_BR_LOCAL_OUT;
109 net = dev_net(skb->dev);
110 indev = NULL;
111 }
112
113 NF_HOOK(NFPROTO_BRIDGE, br_hook,
114 net, NULL, skb, indev, skb->dev,
115 br_forward_finish);
116}
117
118static int deliver_clone(const struct net_bridge_port *prev,
119 struct sk_buff *skb, bool local_orig)
120{
121 struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
122
123 skb = skb_clone(skb, GFP_ATOMIC);
124 if (!skb) {
125 dev->stats.tx_dropped++;
126 return -ENOMEM;
127 }
128
129 __br_forward(prev, skb, local_orig);
130 return 0;
131}
132
133
134
135
136
137
138
139
140
141
142void br_forward(const struct net_bridge_port *to,
143 struct sk_buff *skb, bool local_rcv, bool local_orig)
144{
145 if (to && should_deliver(to, skb)) {
146 if (local_rcv)
147 deliver_clone(to, skb, local_orig);
148 else
149 __br_forward(to, skb, local_orig);
150 return;
151 }
152
153 if (!local_rcv)
154 kfree_skb(skb);
155}
156EXPORT_SYMBOL_GPL(br_forward);
157
158static struct net_bridge_port *maybe_deliver(
159 struct net_bridge_port *prev, struct net_bridge_port *p,
160 struct sk_buff *skb, bool local_orig)
161{
162 int err;
163
164 if (!should_deliver(p, skb))
165 return prev;
166
167 if (!prev)
168 goto out;
169
170 err = deliver_clone(prev, skb, local_orig);
171 if (err)
172 return ERR_PTR(err);
173
174out:
175 return p;
176}
177
178
179void br_flood(struct net_bridge *br, struct sk_buff *skb,
180 enum br_pkt_type pkt_type, bool local_rcv, bool local_orig)
181{
182 u8 igmp_type = br_multicast_igmp_type(skb);
183 struct net_bridge_port *prev = NULL;
184 struct net_bridge_port *p;
185
186 list_for_each_entry_rcu(p, &br->port_list, list) {
187
188
189
190 switch (pkt_type) {
191 case BR_PKT_UNICAST:
192 if (!(p->flags & BR_FLOOD))
193 continue;
194 break;
195 case BR_PKT_MULTICAST:
196 if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev)
197 continue;
198 break;
199 case BR_PKT_BROADCAST:
200 if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev)
201 continue;
202 break;
203 }
204
205
206 if (p->flags & BR_PROXYARP)
207 continue;
208 if ((p->flags & (BR_PROXYARP_WIFI | BR_NEIGH_SUPPRESS)) &&
209 BR_INPUT_SKB_CB(skb)->proxyarp_replied)
210 continue;
211
212 prev = maybe_deliver(prev, p, skb, local_orig);
213 if (IS_ERR(prev))
214 goto out;
215 if (prev == p)
216 br_multicast_count(p->br, p, skb, igmp_type,
217 BR_MCAST_DIR_TX);
218 }
219
220 if (!prev)
221 goto out;
222
223 if (local_rcv)
224 deliver_clone(prev, skb, local_orig);
225 else
226 __br_forward(prev, skb, local_orig);
227 return;
228
229out:
230 if (!local_rcv)
231 kfree_skb(skb);
232}
233
234#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
235static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
236 const unsigned char *addr, bool local_orig)
237{
238 struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
239 const unsigned char *src = eth_hdr(skb)->h_source;
240
241 if (!should_deliver(p, skb))
242 return;
243
244
245 if (skb->dev == p->dev && ether_addr_equal(src, addr))
246 return;
247
248 skb = skb_copy(skb, GFP_ATOMIC);
249 if (!skb) {
250 dev->stats.tx_dropped++;
251 return;
252 }
253
254 if (!is_broadcast_ether_addr(addr))
255 memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
256
257 __br_forward(p, skb, local_orig);
258}
259
260
261void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
262 struct sk_buff *skb,
263 bool local_rcv, bool local_orig)
264{
265 struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
266 u8 igmp_type = br_multicast_igmp_type(skb);
267 struct net_bridge *br = netdev_priv(dev);
268 struct net_bridge_port *prev = NULL;
269 struct net_bridge_port_group *p;
270 struct hlist_node *rp;
271
272 rp = rcu_dereference(hlist_first_rcu(&br->router_list));
273 p = mdst ? rcu_dereference(mdst->ports) : NULL;
274 while (p || rp) {
275 struct net_bridge_port *port, *lport, *rport;
276
277 lport = p ? p->port : NULL;
278 rport = hlist_entry_safe(rp, struct net_bridge_port, rlist);
279
280 if ((unsigned long)lport > (unsigned long)rport) {
281 port = lport;
282
283 if (port->flags & BR_MULTICAST_TO_UNICAST) {
284 maybe_deliver_addr(lport, skb, p->eth_addr,
285 local_orig);
286 goto delivered;
287 }
288 } else {
289 port = rport;
290 }
291
292 prev = maybe_deliver(prev, port, skb, local_orig);
293delivered:
294 if (IS_ERR(prev))
295 goto out;
296 if (prev == port)
297 br_multicast_count(port->br, port, skb, igmp_type,
298 BR_MCAST_DIR_TX);
299
300 if ((unsigned long)lport >= (unsigned long)port)
301 p = rcu_dereference(p->next);
302 if ((unsigned long)rport >= (unsigned long)port)
303 rp = rcu_dereference(hlist_next_rcu(rp));
304 }
305
306 if (!prev)
307 goto out;
308
309 if (local_rcv)
310 deliver_clone(prev, skb, local_orig);
311 else
312 __br_forward(prev, skb, local_orig);
313 return;
314
315out:
316 if (!local_rcv)
317 kfree_skb(skb);
318}
319#endif
320