Add a new bridge port attribute that allows user space to enable
per-{Port, VLAN} neighbor suppression. Example:

 # bridge -d -j -p link show dev swp1 | jq '.[]["neigh_vlan_suppress"]'
 false
 # bridge link set dev swp1 neigh_vlan_suppress on
 # bridge -d -j -p link show dev swp1 | jq '.[]["neigh_vlan_suppress"]'
 true
 # bridge link set dev swp1 neigh_vlan_suppress off
 # bridge -d -j -p link show dev swp1 | jq '.[]["neigh_vlan_suppress"]'
 false

Signed-off-by: Ido Schimmel <ido...@nvidia.com>
Acked-by: Nikolay Aleksandrov <ra...@blackwall.org>
---
 include/uapi/linux/if_link.h | 1 +
 net/bridge/br_netlink.c      | 8 +++++++-
 net/core/rtnetlink.c         | 2 +-
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 8d679688efe0..4ac1000b0ef2 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -569,6 +569,7 @@ enum {
        IFLA_BRPORT_MAB,
        IFLA_BRPORT_MCAST_N_GROUPS,
        IFLA_BRPORT_MCAST_MAX_GROUPS,
+       IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
        __IFLA_BRPORT_MAX
 };
 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index fefb1c0e248b..05c5863d2e20 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -189,6 +189,7 @@ static inline size_t br_port_info_size(void)
                + nla_total_size(1)     /* IFLA_BRPORT_ISOLATED */
                + nla_total_size(1)     /* IFLA_BRPORT_LOCKED */
                + nla_total_size(1)     /* IFLA_BRPORT_MAB */
+               + nla_total_size(1)     /* IFLA_BRPORT_NEIGH_VLAN_SUPPRESS */
                + nla_total_size(sizeof(struct ifla_bridge_id)) /* 
IFLA_BRPORT_ROOT_ID */
                + nla_total_size(sizeof(struct ifla_bridge_id)) /* 
IFLA_BRPORT_BRIDGE_ID */
                + nla_total_size(sizeof(u16))   /* IFLA_BRPORT_DESIGNATED_PORT 
*/
@@ -278,7 +279,9 @@ static int br_port_fill_attrs(struct sk_buff *skb,
                       !!(p->flags & BR_MRP_LOST_IN_CONT)) ||
            nla_put_u8(skb, IFLA_BRPORT_ISOLATED, !!(p->flags & BR_ISOLATED)) ||
            nla_put_u8(skb, IFLA_BRPORT_LOCKED, !!(p->flags & BR_PORT_LOCKED)) 
||
-           nla_put_u8(skb, IFLA_BRPORT_MAB, !!(p->flags & BR_PORT_MAB)))
+           nla_put_u8(skb, IFLA_BRPORT_MAB, !!(p->flags & BR_PORT_MAB)) ||
+           nla_put_u8(skb, IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
+                      !!(p->flags & BR_NEIGH_VLAN_SUPPRESS)))
                return -EMSGSIZE;
 
        timerval = br_timer_value(&p->message_age_timer);
@@ -891,6 +894,7 @@ static const struct nla_policy 
br_port_policy[IFLA_BRPORT_MAX + 1] = {
        [IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 },
        [IFLA_BRPORT_MCAST_N_GROUPS] = { .type = NLA_REJECT },
        [IFLA_BRPORT_MCAST_MAX_GROUPS] = { .type = NLA_U32 },
+       [IFLA_BRPORT_NEIGH_VLAN_SUPPRESS] = NLA_POLICY_MAX(NLA_U8, 1),
 };
 
 /* Change the state of the port and notify spanning tree */
@@ -957,6 +961,8 @@ static int br_setport(struct net_bridge_port *p, struct 
nlattr *tb[],
        br_set_port_flag(p, tb, IFLA_BRPORT_ISOLATED, BR_ISOLATED);
        br_set_port_flag(p, tb, IFLA_BRPORT_LOCKED, BR_PORT_LOCKED);
        br_set_port_flag(p, tb, IFLA_BRPORT_MAB, BR_PORT_MAB);
+       br_set_port_flag(p, tb, IFLA_BRPORT_NEIGH_VLAN_SUPPRESS,
+                        BR_NEIGH_VLAN_SUPPRESS);
 
        if ((p->flags & BR_PORT_MAB) &&
            (!(p->flags & BR_PORT_LOCKED) || !(p->flags & BR_LEARNING))) {
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e844d75220fb..653901a1bf75 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -61,7 +61,7 @@
 #include "dev.h"
 
 #define RTNL_MAX_TYPE          50
-#define RTNL_SLAVE_MAX_TYPE    42
+#define RTNL_SLAVE_MAX_TYPE    43
 
 struct rtnl_link {
        rtnl_doit_func          doit;
-- 
2.37.3

Reply via email to