Skip to content

Commit d68a837

Browse files
committed
net: bridge: add BRIDGE_VLAN_INFO_DYNAMIC flag
Allow a userspace VLAN registration protocol (e.g. an MVRP daemon) to mark the bridge VLAN entries it creates as dynamic, so they can be distinguished from administratively configured (static) entries, which the kernel VLAN table otherwise cannot express. The flag is stored on add, cleared when the entry is re-added without it, and reported in getlink and VLAN DB dumps and notifications. Analogous to the FDB's NTF_EXT_LEARNED. Signed-off-by: Luke Howard <lukeh@padl.com>
1 parent baf18a2 commit d68a837

3 files changed

Lines changed: 21 additions & 4 deletions

File tree

include/uapi/linux/if_bridge.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ enum {
134134
#define BRIDGE_VLAN_INFO_RANGE_END (1<<4) /* VLAN is end of vlan range */
135135
#define BRIDGE_VLAN_INFO_BRENTRY (1<<5) /* Global bridge VLAN entry */
136136
#define BRIDGE_VLAN_INFO_ONLY_OPTS (1<<6) /* Skip create/delete/flags */
137+
#define BRIDGE_VLAN_INFO_DYNAMIC (1<<7) /* 802.1Q Dynamic VLAN Registration Entry */
137138

138139
struct bridge_vlan_info {
139140
__u16 flags;

net/bridge/br_netlink.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,9 @@ static int br_fill_ifvlaninfo_compressed(struct sk_buff *skb,
382382
if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
383383
flags |= BRIDGE_VLAN_INFO_UNTAGGED;
384384

385+
if (v->flags & BRIDGE_VLAN_INFO_DYNAMIC)
386+
flags |= BRIDGE_VLAN_INFO_DYNAMIC;
387+
385388
if (vid_range_start == 0) {
386389
goto initvars;
387390
} else if ((v->vid - vid_range_end) == 1 &&
@@ -434,6 +437,9 @@ static int br_fill_ifvlaninfo(struct sk_buff *skb,
434437
if (v->flags & BRIDGE_VLAN_INFO_UNTAGGED)
435438
vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
436439

440+
if (v->flags & BRIDGE_VLAN_INFO_DYNAMIC)
441+
vinfo.flags |= BRIDGE_VLAN_INFO_DYNAMIC;
442+
437443
if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
438444
sizeof(vinfo), &vinfo))
439445
goto nla_put_failure;

net/bridge/br_vlan.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,11 @@ static void __vlan_delete_pvid(struct net_bridge_vlan_group *vg, u16 vid)
5454
vg->pvid = 0;
5555
}
5656

57-
/* Update the BRIDGE_VLAN_INFO_PVID and BRIDGE_VLAN_INFO_UNTAGGED flags of @v.
58-
* If @commit is false, return just whether the BRIDGE_VLAN_INFO_PVID and
59-
* BRIDGE_VLAN_INFO_UNTAGGED bits of @flags would produce any change onto @v.
57+
/* Update the BRIDGE_VLAN_INFO_PVID, BRIDGE_VLAN_INFO_UNTAGGED and
58+
* BRIDGE_VLAN_INFO_DYNAMIC flags of @v.
59+
* If @commit is false, return just whether the BRIDGE_VLAN_INFO_PVID,
60+
* BRIDGE_VLAN_INFO_UNTAGGED and BRIDGE_VLAN_INFO_DYNAMIC bits of @flags
61+
* would produce any change onto @v.
6062
*/
6163
static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags,
6264
bool commit)
@@ -71,7 +73,8 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags,
7173

7274
/* check if anything would be changed on commit */
7375
change = !!(flags & BRIDGE_VLAN_INFO_PVID) == !!(vg->pvid != v->vid) ||
74-
((flags ^ v->flags) & BRIDGE_VLAN_INFO_UNTAGGED);
76+
((flags ^ v->flags) & (BRIDGE_VLAN_INFO_UNTAGGED |
77+
BRIDGE_VLAN_INFO_DYNAMIC));
7578

7679
if (!commit)
7780
goto out;
@@ -86,6 +89,11 @@ static bool __vlan_flags_update(struct net_bridge_vlan *v, u16 flags,
8689
else
8790
v->flags &= ~BRIDGE_VLAN_INFO_UNTAGGED;
8891

92+
if (flags & BRIDGE_VLAN_INFO_DYNAMIC)
93+
v->flags |= BRIDGE_VLAN_INFO_DYNAMIC;
94+
else
95+
v->flags &= ~BRIDGE_VLAN_INFO_DYNAMIC;
96+
8997
out:
9098
return change;
9199
}
@@ -1869,6 +1877,8 @@ static bool br_vlan_fill_vids(struct sk_buff *skb, u16 vid, u16 vid_range,
18691877
info.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
18701878
if (flags & BRIDGE_VLAN_INFO_PVID)
18711879
info.flags |= BRIDGE_VLAN_INFO_PVID;
1880+
if (flags & BRIDGE_VLAN_INFO_DYNAMIC)
1881+
info.flags |= BRIDGE_VLAN_INFO_DYNAMIC;
18721882

18731883
if (nla_put(skb, BRIDGE_VLANDB_ENTRY_INFO, sizeof(info), &info))
18741884
goto out_err;

0 commit comments

Comments
 (0)