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
,
92 struct netdev_nested_priv
*priv
)
94 __be32 ip
= *(__be32
*)priv
->data
;
95 struct in_device
*in_dev
;
98 in_dev
= __in_dev_get_rcu(dev
);
100 addr
= inet_confirm_addr(dev_net(dev
), in_dev
, 0, ip
,
109 static bool br_is_local_ip(struct net_device
*dev
, __be32 ip
)
111 struct netdev_nested_priv priv
= {
115 if (br_chk_addr_ip(dev
, &priv
))
118 /* check if ip is configured on upper dev */
119 if (netdev_walk_all_upper_dev_rcu(dev
, br_chk_addr_ip
, &priv
))
125 void br_do_proxy_suppress_arp(struct sk_buff
*skb
, struct net_bridge
*br
,
126 u16 vid
, struct net_bridge_port
*p
)
128 struct net_device
*dev
= br
->dev
;
129 struct net_device
*vlandev
= dev
;
135 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 0;
137 if ((dev
->flags
& IFF_NOARP
) ||
138 !pskb_may_pull(skb
, arp_hdr_len(dev
)))
143 if (parp
->ar_pro
!= htons(ETH_P_IP
) ||
144 parp
->ar_hln
!= dev
->addr_len
||
148 arpptr
= (u8
*)parp
+ sizeof(struct arphdr
);
150 arpptr
+= dev
->addr_len
; /* sha */
151 memcpy(&sip
, arpptr
, sizeof(sip
));
152 arpptr
+= sizeof(sip
);
153 arpptr
+= dev
->addr_len
; /* tha */
154 memcpy(&tip
, arpptr
, sizeof(tip
));
156 if (ipv4_is_loopback(tip
) ||
157 ipv4_is_multicast(tip
))
160 if (br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
)) {
161 if (p
&& (p
->flags
& BR_NEIGH_SUPPRESS
))
163 if (ipv4_is_zeronet(sip
) || sip
== tip
) {
164 /* prevent flooding to neigh suppress ports */
165 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
170 if (parp
->ar_op
!= htons(ARPOP_REQUEST
))
174 vlandev
= __vlan_find_dev_deep_rcu(br
->dev
, skb
->vlan_proto
,
180 if (br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
) &&
181 br_is_local_ip(vlandev
, tip
)) {
182 /* its our local ip, so don't proxy reply
183 * and don't forward to neigh suppress ports
185 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
189 n
= neigh_lookup(&arp_tbl
, &tip
, vlandev
);
191 struct net_bridge_fdb_entry
*f
;
193 if (!(n
->nud_state
& NUD_VALID
)) {
198 f
= br_fdb_find_rcu(br
, n
->ha
, vid
);
200 bool replied
= false;
202 if ((p
&& (p
->flags
& BR_PROXYARP
)) ||
203 (f
->dst
&& (f
->dst
->flags
& (BR_PROXYARP_WIFI
|
204 BR_NEIGH_SUPPRESS
)))) {
206 br_arp_send(br
, p
, skb
->dev
, sip
, tip
,
207 sha
, n
->ha
, sha
, 0, 0);
209 br_arp_send(br
, p
, skb
->dev
, sip
, tip
,
212 skb_vlan_tag_get(skb
));
216 /* If we have replied or as long as we know the
217 * mac, indicate to arp replied
220 br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
))
221 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
229 #if IS_ENABLED(CONFIG_IPV6)
230 struct nd_msg
*br_is_nd_neigh_msg(struct sk_buff
*skb
, struct nd_msg
*msg
)
234 m
= skb_header_pointer(skb
, skb_network_offset(skb
) +
235 sizeof(struct ipv6hdr
), sizeof(*msg
), msg
);
239 if (m
->icmph
.icmp6_code
!= 0 ||
240 (m
->icmph
.icmp6_type
!= NDISC_NEIGHBOUR_SOLICITATION
&&
241 m
->icmph
.icmp6_type
!= NDISC_NEIGHBOUR_ADVERTISEMENT
))
247 static void br_nd_send(struct net_bridge
*br
, struct net_bridge_port
*p
,
248 struct sk_buff
*request
, struct neighbour
*n
,
249 __be16 vlan_proto
, u16 vlan_tci
, struct nd_msg
*ns
)
251 struct net_device
*dev
= request
->dev
;
252 struct net_bridge_vlan_group
*vg
;
253 struct sk_buff
*reply
;
255 struct ipv6hdr
*pip6
;
256 int na_olen
= 8; /* opt hdr + ETH_ALEN for target */
265 len
= LL_RESERVED_SPACE(dev
) + sizeof(struct ipv6hdr
) +
266 sizeof(*na
) + na_olen
+ dev
->needed_tailroom
;
268 reply
= alloc_skb(len
, GFP_ATOMIC
);
272 reply
->protocol
= htons(ETH_P_IPV6
);
274 skb_reserve(reply
, LL_RESERVED_SPACE(dev
));
275 skb_push(reply
, sizeof(struct ethhdr
));
276 skb_set_mac_header(reply
, 0);
278 daddr
= eth_hdr(request
)->h_source
;
280 /* Do we need option processing ? */
281 ns_olen
= request
->len
- (skb_network_offset(request
) +
282 sizeof(struct ipv6hdr
)) - sizeof(*ns
);
283 for (i
= 0; i
< ns_olen
- 1; i
+= (ns
->opt
[i
+ 1] << 3)) {
284 if (!ns
->opt
[i
+ 1]) {
288 if (ns
->opt
[i
] == ND_OPT_SOURCE_LL_ADDR
) {
289 daddr
= ns
->opt
+ i
+ sizeof(struct nd_opt_hdr
);
294 /* Ethernet header */
295 ether_addr_copy(eth_hdr(reply
)->h_dest
, daddr
);
296 ether_addr_copy(eth_hdr(reply
)->h_source
, n
->ha
);
297 eth_hdr(reply
)->h_proto
= htons(ETH_P_IPV6
);
298 reply
->protocol
= htons(ETH_P_IPV6
);
300 skb_pull(reply
, sizeof(struct ethhdr
));
301 skb_set_network_header(reply
, 0);
302 skb_put(reply
, sizeof(struct ipv6hdr
));
305 pip6
= ipv6_hdr(reply
);
306 memset(pip6
, 0, sizeof(struct ipv6hdr
));
308 pip6
->priority
= ipv6_hdr(request
)->priority
;
309 pip6
->nexthdr
= IPPROTO_ICMPV6
;
310 pip6
->hop_limit
= 255;
311 pip6
->daddr
= ipv6_hdr(request
)->saddr
;
312 pip6
->saddr
= *(struct in6_addr
*)n
->primary_key
;
314 skb_pull(reply
, sizeof(struct ipv6hdr
));
315 skb_set_transport_header(reply
, 0);
317 na
= (struct nd_msg
*)skb_put(reply
, sizeof(*na
) + na_olen
);
319 /* Neighbor Advertisement */
320 memset(na
, 0, sizeof(*na
) + na_olen
);
321 na
->icmph
.icmp6_type
= NDISC_NEIGHBOUR_ADVERTISEMENT
;
322 na
->icmph
.icmp6_router
= (n
->flags
& NTF_ROUTER
) ? 1 : 0;
323 na
->icmph
.icmp6_override
= 1;
324 na
->icmph
.icmp6_solicited
= 1;
325 na
->target
= ns
->target
;
326 ether_addr_copy(&na
->opt
[2], n
->ha
);
327 na
->opt
[0] = ND_OPT_TARGET_LL_ADDR
;
328 na
->opt
[1] = na_olen
>> 3;
330 na
->icmph
.icmp6_cksum
= csum_ipv6_magic(&pip6
->saddr
,
332 sizeof(*na
) + na_olen
,
334 csum_partial(na
, sizeof(*na
) + na_olen
, 0));
336 pip6
->payload_len
= htons(sizeof(*na
) + na_olen
);
338 skb_push(reply
, sizeof(struct ipv6hdr
));
339 skb_push(reply
, sizeof(struct ethhdr
));
341 reply
->ip_summed
= CHECKSUM_UNNECESSARY
;
344 vg
= nbp_vlan_group_rcu(p
);
346 vg
= br_vlan_group_rcu(br
);
347 pvid
= br_get_pvid(vg
);
348 if (pvid
== (vlan_tci
& VLAN_VID_MASK
))
352 __vlan_hwaccel_put_tag(reply
, vlan_proto
, vlan_tci
);
354 netdev_dbg(dev
, "nd send dev %s dst %pI6 dst_hw %pM src %pI6 src_hw %pM\n",
355 dev
->name
, &pip6
->daddr
, daddr
, &pip6
->saddr
, n
->ha
);
358 dev_queue_xmit(reply
);
360 skb_reset_mac_header(reply
);
361 __skb_pull(reply
, skb_network_offset(reply
));
362 reply
->ip_summed
= CHECKSUM_UNNECESSARY
;
363 reply
->pkt_type
= PACKET_HOST
;
369 static int br_chk_addr_ip6(struct net_device
*dev
,
370 struct netdev_nested_priv
*priv
)
372 struct in6_addr
*addr
= (struct in6_addr
*)priv
->data
;
374 if (ipv6_chk_addr(dev_net(dev
), addr
, dev
, 0))
380 static bool br_is_local_ip6(struct net_device
*dev
, struct in6_addr
*addr
)
383 struct netdev_nested_priv priv
= {
384 .data
= (void *)addr
,
387 if (br_chk_addr_ip6(dev
, &priv
))
390 /* check if ip is configured on upper dev */
391 if (netdev_walk_all_upper_dev_rcu(dev
, br_chk_addr_ip6
, &priv
))
397 void br_do_suppress_nd(struct sk_buff
*skb
, struct net_bridge
*br
,
398 u16 vid
, struct net_bridge_port
*p
, struct nd_msg
*msg
)
400 struct net_device
*dev
= br
->dev
;
401 struct net_device
*vlandev
= NULL
;
402 struct in6_addr
*saddr
, *daddr
;
403 struct ipv6hdr
*iphdr
;
406 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 0;
408 if (p
&& (p
->flags
& BR_NEIGH_SUPPRESS
))
411 if (msg
->icmph
.icmp6_type
== NDISC_NEIGHBOUR_ADVERTISEMENT
&&
412 !msg
->icmph
.icmp6_solicited
) {
413 /* prevent flooding to neigh suppress ports */
414 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
418 if (msg
->icmph
.icmp6_type
!= NDISC_NEIGHBOUR_SOLICITATION
)
421 iphdr
= ipv6_hdr(skb
);
422 saddr
= &iphdr
->saddr
;
423 daddr
= &iphdr
->daddr
;
425 if (ipv6_addr_any(saddr
) || !ipv6_addr_cmp(saddr
, daddr
)) {
426 /* prevent flooding to neigh suppress ports */
427 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
432 /* build neigh table lookup on the vlan device */
433 vlandev
= __vlan_find_dev_deep_rcu(br
->dev
, skb
->vlan_proto
,
441 if (br_is_local_ip6(vlandev
, &msg
->target
)) {
442 /* its our own ip, so don't proxy reply
443 * and don't forward to arp suppress ports
445 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;
449 n
= neigh_lookup(ipv6_stub
->nd_tbl
, &msg
->target
, vlandev
);
451 struct net_bridge_fdb_entry
*f
;
453 if (!(n
->nud_state
& NUD_VALID
)) {
458 f
= br_fdb_find_rcu(br
, n
->ha
, vid
);
460 bool replied
= false;
462 if (f
->dst
&& (f
->dst
->flags
& BR_NEIGH_SUPPRESS
)) {
464 br_nd_send(br
, p
, skb
, n
,
466 skb_vlan_tag_get(skb
), msg
);
468 br_nd_send(br
, p
, skb
, n
, 0, 0, msg
);
472 /* If we have replied or as long as we know the
473 * mac, indicate to NEIGH_SUPPRESS ports that we
477 br_opt_get(br
, BROPT_NEIGH_SUPPRESS_ENABLED
))
478 BR_INPUT_SKB_CB(skb
)->proxyarp_replied
= 1;