Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bridge: vlan: Allow setting VLAN neighbor suppression state

Add a new VLAN attribute that allows user space to set the neighbor
suppression state of the port VLAN. Example:

# bridge -d -j -p vlan show dev swp1 vid 10 | jq '.[]["vlans"][]["neigh_suppress"]'
false
# bridge vlan set vid 10 dev swp1 neigh_suppress on
# bridge -d -j -p vlan show dev swp1 vid 10 | jq '.[]["vlans"][]["neigh_suppress"]'
true
# bridge vlan set vid 10 dev swp1 neigh_suppress off
# bridge -d -j -p vlan show dev swp1 vid 10 | jq '.[]["vlans"][]["neigh_suppress"]'
false

# bridge vlan set vid 10 dev br0 neigh_suppress on
Error: bridge: Can't set neigh_suppress for non-port vlans.

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Ido Schimmel and committed by
David S. Miller
83f6d600 412614b1

+21 -1
+1
include/uapi/linux/if_bridge.h
··· 525 525 BRIDGE_VLANDB_ENTRY_MCAST_ROUTER, 526 526 BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS, 527 527 BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS, 528 + BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS, 528 529 __BRIDGE_VLANDB_ENTRY_MAX, 529 530 }; 530 531 #define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
+1
net/bridge/br_vlan.c
··· 2134 2134 [BRIDGE_VLANDB_ENTRY_MCAST_ROUTER] = { .type = NLA_U8 }, 2135 2135 [BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS] = { .type = NLA_REJECT }, 2136 2136 [BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS] = { .type = NLA_U32 }, 2137 + [BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS] = NLA_POLICY_MAX(NLA_U8, 1), 2137 2138 }; 2138 2139 2139 2140 static int br_vlan_rtm_process_one(struct net_device *dev,
+19 -1
net/bridge/br_vlan_options.c
··· 52 52 const struct net_bridge_port *p) 53 53 { 54 54 if (nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_STATE, br_vlan_get_state(v)) || 55 - !__vlan_tun_put(skb, v)) 55 + !__vlan_tun_put(skb, v) || 56 + nla_put_u8(skb, BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS, 57 + !!(v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED))) 56 58 return false; 57 59 58 60 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING ··· 82 80 + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_N_GROUPS */ 83 81 + nla_total_size(sizeof(u32)) /* BRIDGE_VLANDB_ENTRY_MCAST_MAX_GROUPS */ 84 82 #endif 83 + + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS */ 85 84 + 0; 86 85 } 87 86 ··· 241 238 *changed = true; 242 239 } 243 240 #endif 241 + 242 + if (tb[BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS]) { 243 + bool enabled = v->priv_flags & BR_VLFLAG_NEIGH_SUPPRESS_ENABLED; 244 + bool val = nla_get_u8(tb[BRIDGE_VLANDB_ENTRY_NEIGH_SUPPRESS]); 245 + 246 + if (!p) { 247 + NL_SET_ERR_MSG_MOD(extack, "Can't set neigh_suppress for non-port vlans"); 248 + return -EINVAL; 249 + } 250 + 251 + if (val != enabled) { 252 + v->priv_flags ^= BR_VLFLAG_NEIGH_SUPPRESS_ENABLED; 253 + *changed = true; 254 + } 255 + } 244 256 245 257 return 0; 246 258 }