1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Handle bridge arp/nd proxy/suppress
5 * Copyright (C) 2017 Cumulus Networks
6 * Copyright (c) 2017 Roopa Prabhu <roopa@cumulusnetworks.com>
9 * Roopa Prabhu <roopa@cumulusnetworks.com>
12 #include <linux/kernel.h>
13 #include <linux/netdevice.h>
14 #include <linux/etherdevice.h>
15 #include <linux/neighbour.h>
17 #include <linux/if_vlan.h>
18 #include <linux/inetdevice.h>
19 #include <net/addrconf.h>
20 #include <net/ipv6_stubs.h>
21 #if IS_ENABLED(CONFIG_IPV6)
22 #include <net/ip6_checksum.h>
25 #include "br_private.h"
27 void br_recalculate_neigh_suppress_enabled(struct net_bridge
*br
)
29 struct net_bridge_port
*p
;
30 bool neigh_suppress
= false;
32 list_for_each_entry(p
, &br
->port_list
, list
) {
33 if (p
->flags
& BR_NEIGH_SUPPRESS
) {
34 neigh_suppress
= true;
39 br_opt_toggle(br
, BROPT_NEIGH_SUPPRESS_ENABLED
, neigh_suppress
);
42 #if IS_ENABLED(CONFIG_INET)
43 static void br_arp_send(struct net_bridge
*br
, struct net_bridge_port
*p
,
44 struct net_device
*dev
, __be32 dest_ip
, __be32 src_ip
,
45 const unsigned char *dest_hw
,
46 const unsigned char *src_hw
,
47 const unsigned char *target_hw
,
48 __be16 vlan_proto
, u16 vlan_tci
)
50 struct net_bridge_vlan_group
*vg
;
54 netdev_dbg(dev
, "arp send dev %s dst %pI4 dst_hw %pM src %pI4 src_hw %pM\n",
55 dev
->name
, &dest_ip
, dest_hw
, &src_ip
, src_hw
);
58 arp_send(ARPOP_REPLY
, ETH_P_ARP
, dest_ip
, dev
, src_ip
,
59 dest_hw
, src_hw
, target_hw
);
63 skb
= arp_create(ARPOP_REPLY
, ETH_P_ARP
, dest_ip
, dev
, src_ip
,
64 dest_hw
, src_hw
, target_hw
);
69 vg
= nbp_vlan_group_rcu(p
);
71 vg
= br_vlan_group_rcu(br
);
72 pvid
= br_get_pvid(vg
);
73 if (pvid
== (vlan_tci
& VLAN_VID_MASK
))
77 __vlan_hwaccel_put_tag(skb
, vlan_proto
, vlan_tci
);
82 skb_reset_mac_header(skb
);
83 __skb_pull(skb
, skb_network_offset(skb
));
84 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
85 skb
->pkt_type
= PACKET_HOST
;
91 static int br_chk_addr_ip(struct net_device
*dev
, void *data
)
93 __be32 ip
= *(__be32
*)data
;
94 struct in_device
*in_dev
;
97 in_dev
= __in_dev_get_rcu(dev
);
99 addr
= inet_confirm_addr(dev_net(dev
), in_dev
, 0, ip
,
108 static bool br_is_local_ip(struct net_device
*dev
, __be32 ip
)
110 if (br_chk_addr_ip(dev
, &ip
))
113 /* check if ip is configured on upper dev */
114 if (netdev_walk_all_upper_dev_rcu(dev
, br_chk_addr_ip
, &ip
))
120 void br_do_proxy_suppress_arp(struct sk_buff
*skb
, struct net_bridge
*br
,
121 u16 vid
, struct net_bridge_port
*p
)
123 struct net_device
*dev
= br
->dev
;
124 struct net_device
*vlandev
= dev
;
130 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 0;
132 if ((dev
->flags
& IFF_NOARP
) ||
133 !pskb_may_pull(skb
, arp_hdr_len(dev
)))
138 if (parp
->ar_pro
!= htons(ETH_P_IP
) ||
139 parp
->ar_hln
!= dev
->addr_len
||
143 arpptr
= (u8
*)parp
+ sizeof(struct arphdr
);
145 arpptr
+= dev
->addr_len
; /* sha */
146 memcpy(&sip
, arpptr
, sizeof(sip
));
147 arpptr
+= sizeof(sip
);
148 arpptr
+= dev
->addr_len
; /* tha */
149 memcpy(&tip
, arpptr
, sizeof(tip
));
151 if (ipv4_is_loopback(tip
) ||
152 ipv4_is_multicast(tip
))
155 if (br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
)) {
156 if (p
&& (p
->flags
& BR_NEIGH_SUPPRESS
))
158 if (ipv4_is_zeronet(sip
) || sip
== tip
) {
159 /* prevent flooding to neigh suppress ports */
160 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
165 if (parp
->ar_op
!= htons(ARPOP_REQUEST
))
169 vlandev
= __vlan_find_dev_deep_rcu(br
->dev
, skb
->vlan_proto
,
175 if (br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
) &&
176 br_is_local_ip(vlandev
, tip
)) {
177 /* its our local ip, so don't proxy reply
178 * and don't forward to neigh suppress ports
180 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
184 n
= neigh_lookup(&arp_tbl
, &tip
, vlandev
);
186 struct net_bridge_fdb_entry
*f
;
188 if (!(n
->nud_state
& NUD_VALID
)) {
193 f
= br_fdb_find_rcu(br
, n
->ha
, vid
);
195 bool replied
= false;
197 if ((p
&& (p
->flags
& BR_PROXYARP
)) ||
198 (f
->dst
&& (f
->dst
->flags
& (BR_PROXYARP_WIFI
|
199 BR_NEIGH_SUPPRESS
)))) {
201 br_arp_send(br
, p
, skb
->dev
, sip
, tip
,
202 sha
, n
->ha
, sha
, 0, 0);
204 br_arp_send(br
, p
, skb
->dev
, sip
, tip
,
207 skb_vlan_tag_get(skb
));
211 /* If we have replied or as long as we know the
212 * mac, indicate to arp replied
215 br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
))
216 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
224 #if IS_ENABLED(CONFIG_IPV6)
225 struct nd_msg
*br_is_nd_neigh_msg(struct sk_buff
*skb
, struct nd_msg
*msg
)
229 m
= skb_header_pointer(skb
, skb_network_offset(skb
) +
230 sizeof(struct ipv6hdr
), sizeof(*msg
), msg
);
234 if (m
->icmph
.icmp6_code
!= 0 ||
235 (m
->icmph
.icmp6_type
!= NDISC_NEIGHBOUR_SOLICITATION
&&
236 m
->icmph
.icmp6_type
!= NDISC_NEIGHBOUR_ADVERTISEMENT
))
242 static void br_nd_send(struct net_bridge
*br
, struct net_bridge_port
*p
,
243 struct sk_buff
*request
, struct neighbour
*n
,
244 __be16 vlan_proto
, u16 vlan_tci
, struct nd_msg
*ns
)
246 struct net_device
*dev
= request
->dev
;
247 struct net_bridge_vlan_group
*vg
;
248 struct sk_buff
*reply
;
250 struct ipv6hdr
*pip6
;
251 int na_olen
= 8; /* opt hdr + ETH_ALEN for target */
260 len
= LL_RESERVED_SPACE(dev
) + sizeof(struct ipv6hdr
) +
261 sizeof(*na
) + na_olen
+ dev
->needed_tailroom
;
263 reply
= alloc_skb(len
, GFP_ATOMIC
);
267 reply
->protocol
= htons(ETH_P_IPV6
);
269 skb_reserve(reply
, LL_RESERVED_SPACE(dev
));
270 skb_push(reply
, sizeof(struct ethhdr
));
271 skb_set_mac_header(reply
, 0);
273 daddr
= eth_hdr(request
)->h_source
;
275 /* Do we need option processing ? */
276 ns_olen
= request
->len
- (skb_network_offset(request
) +
277 sizeof(struct ipv6hdr
)) - sizeof(*ns
);
278 for (i
= 0; i
< ns_olen
- 1; i
+= (ns
->opt
[i
+ 1] << 3)) {
279 if (ns
->opt
[i
] == ND_OPT_SOURCE_LL_ADDR
) {
280 daddr
= ns
->opt
+ i
+ sizeof(struct nd_opt_hdr
);
285 /* Ethernet header */
286 ether_addr_copy(eth_hdr(reply
)->h_dest
, daddr
);
287 ether_addr_copy(eth_hdr(reply
)->h_source
, n
->ha
);
288 eth_hdr(reply
)->h_proto
= htons(ETH_P_IPV6
);
289 reply
->protocol
= htons(ETH_P_IPV6
);
291 skb_pull(reply
, sizeof(struct ethhdr
));
292 skb_set_network_header(reply
, 0);
293 skb_put(reply
, sizeof(struct ipv6hdr
));
296 pip6
= ipv6_hdr(reply
);
297 memset(pip6
, 0, sizeof(struct ipv6hdr
));
299 pip6
->priority
= ipv6_hdr(request
)->priority
;
300 pip6
->nexthdr
= IPPROTO_ICMPV6
;
301 pip6
->hop_limit
= 255;
302 pip6
->daddr
= ipv6_hdr(request
)->saddr
;
303 pip6
->saddr
= *(struct in6_addr
*)n
->primary_key
;
305 skb_pull(reply
, sizeof(struct ipv6hdr
));
306 skb_set_transport_header(reply
, 0);
308 na
= (struct nd_msg
*)skb_put(reply
, sizeof(*na
) + na_olen
);
310 /* Neighbor Advertisement */
311 memset(na
, 0, sizeof(*na
) + na_olen
);
312 na
->icmph
.icmp6_type
= NDISC_NEIGHBOUR_ADVERTISEMENT
;
313 na
->icmph
.icmp6_router
= (n
->flags
& NTF_ROUTER
) ? 1 : 0;
314 na
->icmph
.icmp6_override
= 1;
315 na
->icmph
.icmp6_solicited
= 1;
316 na
->target
= ns
->target
;
317 ether_addr_copy(&na
->opt
[2], n
->ha
);
318 na
->opt
[0] = ND_OPT_TARGET_LL_ADDR
;
319 na
->opt
[1] = na_olen
>> 3;
321 na
->icmph
.icmp6_cksum
= csum_ipv6_magic(&pip6
->saddr
,
323 sizeof(*na
) + na_olen
,
325 csum_partial(na
, sizeof(*na
) + na_olen
, 0));
327 pip6
->payload_len
= htons(sizeof(*na
) + na_olen
);
329 skb_push(reply
, sizeof(struct ipv6hdr
));
330 skb_push(reply
, sizeof(struct ethhdr
));
332 reply
->ip_summed
= CHECKSUM_UNNECESSARY
;
335 vg
= nbp_vlan_group_rcu(p
);
337 vg
= br_vlan_group_rcu(br
);
338 pvid
= br_get_pvid(vg
);
339 if (pvid
== (vlan_tci
& VLAN_VID_MASK
))
343 __vlan_hwaccel_put_tag(reply
, vlan_proto
, vlan_tci
);
345 netdev_dbg(dev
, "nd send dev %s dst %pI6 dst_hw %pM src %pI6 src_hw %pM\n",
346 dev
->name
, &pip6
->daddr
, daddr
, &pip6
->saddr
, n
->ha
);
349 dev_queue_xmit(reply
);
351 skb_reset_mac_header(reply
);
352 __skb_pull(reply
, skb_network_offset(reply
));
353 reply
->ip_summed
= CHECKSUM_UNNECESSARY
;
354 reply
->pkt_type
= PACKET_HOST
;
360 static int br_chk_addr_ip6(struct net_device
*dev
, void *data
)
362 struct in6_addr
*addr
= (struct in6_addr
*)data
;
364 if (ipv6_chk_addr(dev_net(dev
), addr
, dev
, 0))
370 static bool br_is_local_ip6(struct net_device
*dev
, struct in6_addr
*addr
)
373 if (br_chk_addr_ip6(dev
, addr
))
376 /* check if ip is configured on upper dev */
377 if (netdev_walk_all_upper_dev_rcu(dev
, br_chk_addr_ip6
, addr
))
383 void br_do_suppress_nd(struct sk_buff
*skb
, struct net_bridge
*br
,
384 u16 vid
, struct net_bridge_port
*p
, struct nd_msg
*msg
)
386 struct net_device
*dev
= br
->dev
;
387 struct net_device
*vlandev
= NULL
;
388 struct in6_addr
*saddr
, *daddr
;
389 struct ipv6hdr
*iphdr
;
392 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 0;
394 if (p
&& (p
->flags
& BR_NEIGH_SUPPRESS
))
397 if (msg
->icmph
.icmp6_type
== NDISC_NEIGHBOUR_ADVERTISEMENT
&&
398 !msg
->icmph
.icmp6_solicited
) {
399 /* prevent flooding to neigh suppress ports */
400 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
404 if (msg
->icmph
.icmp6_type
!= NDISC_NEIGHBOUR_SOLICITATION
)
407 iphdr
= ipv6_hdr(skb
);
408 saddr
= &iphdr
->saddr
;
409 daddr
= &iphdr
->daddr
;
411 if (ipv6_addr_any(saddr
) || !ipv6_addr_cmp(saddr
, daddr
)) {
412 /* prevent flooding to neigh suppress ports */
413 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
418 /* build neigh table lookup on the vlan device */
419 vlandev
= __vlan_find_dev_deep_rcu(br
->dev
, skb
->vlan_proto
,
427 if (br_is_local_ip6(vlandev
, &msg
->target
)) {
428 /* its our own ip, so don't proxy reply
429 * and don't forward to arp suppress ports
431 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
435 n
= neigh_lookup(ipv6_stub
->nd_tbl
, &msg
->target
, vlandev
);
437 struct net_bridge_fdb_entry
*f
;
439 if (!(n
->nud_state
& NUD_VALID
)) {
444 f
= br_fdb_find_rcu(br
, n
->ha
, vid
);
446 bool replied
= false;
448 if (f
->dst
&& (f
->dst
->flags
& BR_NEIGH_SUPPRESS
)) {
450 br_nd_send(br
, p
, skb
, n
,
452 skb_vlan_tag_get(skb
), msg
);
454 br_nd_send(br
, p
, skb
, n
, 0, 0, msg
);
458 /* If we have replied or as long as we know the
459 * mac, indicate to NEIGH_SUPPRESS ports that we
463 br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
))
464 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;