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