Skip to content

Commit 821f1b2

Browse files
roopa-prabhudavem330
authored andcommitted
bridge: add new BR_NEIGH_SUPPRESS port flag to suppress arp and nd flood
This patch adds a new bridge port flag BR_NEIGH_SUPPRESS to suppress arp and nd flood on bridge ports. It implements rfc7432, section 10. https://tools.ietf.org/html/rfc7432#section-10 for ethernet VPN deployments. It is similar to the existing BR_PROXYARP* flags but has a few semantic differences to conform to EVPN standard. Unlike the existing flags, this new flag suppresses flood of all neigh discovery packets (arp and nd) to tunnel ports. Supports both vlan filtering and non-vlan filtering bridges. In case of EVPN, it is mainly used to avoid flooding of arp and nd packets to tunnel ports like vxlan. This patch adds netlink and sysfs support to set this bridge port flag. Signed-off-by: Roopa Prabhu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 951f788 commit 821f1b2

File tree

9 files changed

+54
-3
lines changed

9 files changed

+54
-3
lines changed

include/linux/if_bridge.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ struct br_ip_list {
4949
#define BR_MULTICAST_TO_UNICAST BIT(12)
5050
#define BR_VLAN_TUNNEL BIT(13)
5151
#define BR_BCAST_FLOOD BIT(14)
52+
#define BR_NEIGH_SUPPRESS BIT(15)
5253

5354
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
5455

include/uapi/linux/if_link.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ enum {
327327
IFLA_BRPORT_VLAN_TUNNEL,
328328
IFLA_BRPORT_BCAST_FLOOD,
329329
IFLA_BRPORT_GROUP_FWD_MASK,
330+
IFLA_BRPORT_NEIGH_SUPPRESS,
330331
__IFLA_BRPORT_MAX
331332
};
332333
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)

net/bridge/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ obj-$(CONFIG_BRIDGE) += bridge.o
77
bridge-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \
88
br_ioctl.o br_stp.o br_stp_bpdu.o \
99
br_stp_if.o br_stp_timer.o br_netlink.o \
10-
br_netlink_tunnel.o
10+
br_netlink_tunnel.o br_arp_nd_proxy.o
1111

1212
bridge-$(CONFIG_SYSFS) += br_sysfs_if.o br_sysfs_br.o
1313

net/bridge/br_arp_nd_proxy.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Handle bridge arp/nd proxy/suppress
3+
*
4+
* Copyright (C) 2017 Cumulus Networks
5+
* Copyright (c) 2017 Roopa Prabhu <[email protected]>
6+
*
7+
* Authors:
8+
* Roopa Prabhu <[email protected]>
9+
*
10+
* This program is free software; you can redistribute it and/or
11+
* modify it under the terms of the GNU General Public License
12+
* as published by the Free Software Foundation; either version
13+
* 2 of the License, or (at your option) any later version.
14+
*/
15+
16+
#include <linux/kernel.h>
17+
#include "br_private.h"
18+
19+
void br_recalculate_neigh_suppress_enabled(struct net_bridge *br)
20+
{
21+
struct net_bridge_port *p;
22+
bool neigh_suppress = false;
23+
24+
list_for_each_entry(p, &br->port_list, list) {
25+
if (p->flags & BR_NEIGH_SUPPRESS) {
26+
neigh_suppress = true;
27+
break;
28+
}
29+
}
30+
31+
br->neigh_suppress_enabled = neigh_suppress;
32+
}

net/bridge/br_forward.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb,
204204
/* Do not flood to ports that enable proxy ARP */
205205
if (p->flags & BR_PROXYARP)
206206
continue;
207-
if ((p->flags & BR_PROXYARP_WIFI) &&
207+
if ((p->flags & (BR_PROXYARP_WIFI | BR_NEIGH_SUPPRESS)) &&
208208
BR_INPUT_SKB_CB(skb)->proxyarp_replied)
209209
continue;
210210

net/bridge/br_if.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ void br_dev_delete(struct net_device *dev, struct list_head *head)
310310
del_nbp(p);
311311
}
312312

313+
br_recalculate_neigh_suppress_enabled(br);
314+
313315
br_fdb_delete_by_port(br, NULL, 0, 1);
314316

315317
cancel_delayed_work_sync(&br->gc_work);
@@ -660,4 +662,7 @@ void br_port_flags_change(struct net_bridge_port *p, unsigned long mask)
660662

661663
if (mask & BR_AUTO_MASK)
662664
nbp_update_port_count(br);
665+
666+
if (mask & BR_NEIGH_SUPPRESS)
667+
br_recalculate_neigh_suppress_enabled(br);
663668
}

net/bridge/br_netlink.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static inline size_t br_port_info_size(void)
138138
+ nla_total_size(1) /* IFLA_BRPORT_PROXYARP */
139139
+ nla_total_size(1) /* IFLA_BRPORT_PROXYARP_WIFI */
140140
+ nla_total_size(1) /* IFLA_BRPORT_VLAN_TUNNEL */
141+
+ nla_total_size(1) /* IFLA_BRPORT_NEIGH_SUPPRESS */
141142
+ nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_ROOT_ID */
142143
+ nla_total_size(sizeof(struct ifla_bridge_id)) /* IFLA_BRPORT_BRIDGE_ID */
143144
+ nla_total_size(sizeof(u16)) /* IFLA_BRPORT_DESIGNATED_PORT */
@@ -210,7 +211,9 @@ static int br_port_fill_attrs(struct sk_buff *skb,
210211
nla_put_u8(skb, IFLA_BRPORT_CONFIG_PENDING, p->config_pending) ||
211212
nla_put_u8(skb, IFLA_BRPORT_VLAN_TUNNEL, !!(p->flags &
212213
BR_VLAN_TUNNEL)) ||
213-
nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask))
214+
nla_put_u16(skb, IFLA_BRPORT_GROUP_FWD_MASK, p->group_fwd_mask) ||
215+
nla_put_u8(skb, IFLA_BRPORT_NEIGH_SUPPRESS,
216+
!!(p->flags & BR_NEIGH_SUPPRESS)))
214217
return -EMSGSIZE;
215218

216219
timerval = br_timer_value(&p->message_age_timer);
@@ -785,6 +788,11 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
785788
p->group_fwd_mask = fwd_mask;
786789
}
787790

791+
err = br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_SUPPRESS,
792+
BR_NEIGH_SUPPRESS);
793+
if (err)
794+
return err;
795+
788796
br_port_flags_change(p, old_flags ^ p->flags);
789797
return 0;
790798
}

net/bridge/br_private.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ struct net_bridge {
404404
#ifdef CONFIG_NET_SWITCHDEV
405405
int offload_fwd_mark;
406406
#endif
407+
bool neigh_suppress_enabled;
407408
};
408409

409410
struct br_input_skb_cb {
@@ -1139,4 +1140,5 @@ static inline void br_switchdev_frame_unmark(struct sk_buff *skb)
11391140
}
11401141
#endif /* CONFIG_NET_SWITCHDEV */
11411142

1143+
void br_recalculate_neigh_suppress_enabled(struct net_bridge *br);
11421144
#endif

net/bridge/br_sysfs_if.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP);
191191
BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI);
192192
BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD);
193193
BRPORT_ATTR_FLAG(broadcast_flood, BR_BCAST_FLOOD);
194+
BRPORT_ATTR_FLAG(neigh_suppress, BR_NEIGH_SUPPRESS);
194195

195196
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
196197
static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
@@ -241,6 +242,7 @@ static const struct brport_attribute *brport_attrs[] = {
241242
&brport_attr_multicast_flood,
242243
&brport_attr_broadcast_flood,
243244
&brport_attr_group_fwd_mask,
245+
&brport_attr_neigh_suppress,
244246
NULL
245247
};
246248

0 commit comments

Comments
 (0)