Skip to content

Commit

Permalink
q-in-q-force-nest-vlan-flags
Browse files Browse the repository at this point in the history
  • Loading branch information
Johan Zetterlund authored and Johan Zetterlund committed Jan 12, 2024
1 parent bcfda88 commit 81d6e51
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
3 changes: 2 additions & 1 deletion include/linux-private/linux/if_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ enum {
#define BRIDGE_VLAN_INFO_RANGE_BEGIN (1<<3) /* VLAN is start of vlan range */
#define BRIDGE_VLAN_INFO_RANGE_END (1<<4) /* VLAN is end of vlan range */
#define BRIDGE_VLAN_INFO_BRENTRY (1<<5) /* Global bridge VLAN entry */

#define BRIDGE_VLAN_INFO_POLICY_FORCE (1<<7) /* Force use of pvid for tagged ingress */
#define BRIDGE_VLAN_INFO_POLICY_NEST (1<<8) /* Use pvid for Q-in-Q mode */
struct bridge_vlan_info {
__u16 flags;
__u16 vid;
Expand Down
2 changes: 2 additions & 0 deletions include/netlink/route/link/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ struct rtnl_link_bridge_vlan
uint16_t pvid;
uint32_t vlan_bitmap[RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN];
uint32_t untagged_bitmap[RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN];
uint32_t force_bitmap[RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN];
uint32_t nest_bitmap[RTNL_LINK_BRIDGE_VLAN_BITMAP_LEN];
};

/**
Expand Down
40 changes: 40 additions & 0 deletions lib/route/link/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,12 @@ static int bridge_port_parse_af_full(struct rtnl_link *link, struct nlattr *attr
if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
set_bit(vid_range_start, bd->vlan_info.untagged_bitmap);

if (vinfo->flags & BRIDGE_VLAN_INFO_POLICY_FORCE)
set_bit(vid_range_start, bd->vlan_info.force_bitmap);

if (vinfo->flags & BRIDGE_VLAN_INFO_POLICY_NEST)
set_bit(vid_range_start, bd->vlan_info.nest_bitmap);

set_bit(vid_range_start, bd->vlan_info.vlan_bitmap);
bd->ce_mask |= BRIDGE_ATTR_PORT_VLAN;
}
Expand Down Expand Up @@ -579,6 +585,16 @@ static void __parse_vlan(struct rtnl_link_bridge_vlan *bv, int vid, int flags)

if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
vlan_field_set(bv->untagged_bitmap, vid);

if (flags & BRIDGE_VLAN_INFO_POLICY_FORCE)
vlan_field_set(bv->force_bitmap, vid);
else
vlan_field_clear(bv->force_bitmap, vid);

if (flags & BRIDGE_VLAN_INFO_POLICY_NEST)
vlan_field_set(bv->nest_bitmap, vid);
else
vlan_field_clear(bv->nest_bitmap, vid);
}

static int __parse_vlans(struct nlattr *af_spec, struct bridge_data *bd)
Expand Down Expand Up @@ -659,6 +675,12 @@ static int __fill_vlan(struct rtnl_link_bridge_vlan *bv, struct nl_msg *msg,
if (vlan_field_get(bv->untagged_bitmap, vid))
vlan.flags |= BRIDGE_VLAN_INFO_UNTAGGED;

if (vlan_field_get(bv->nest_bitmap, vid))
vlan.flags |= BRIDGE_VLAN_INFO_POLICY_NEST;

if (vlan_field_get(bv->force_bitmap, vid))
vlan.flags |= BRIDGE_VLAN_INFO_POLICY_FORCE;

return nla_put(msg, IFLA_BRIDGE_VLAN_INFO, sizeof(vlan), &vlan);
}

Expand Down Expand Up @@ -1095,6 +1117,9 @@ int rtnl_link_bridge_vlan_flush(struct rtnl_link *link)
vlan_field_flush(bd->vlan_info.vlan_bitmap);
vlan_field_flush(bd->vlan_info.untagged_bitmap);

vlan_field_flush(bd->vlan_info.nest_bitmap);
vlan_field_flush(bd->vlan_info.force_bitmap);

bd->vlan_info.pvid = 0;
bd->ce_mask |= BRIDGE_ATTR_PORT_VLAN;

Expand Down Expand Up @@ -1170,6 +1195,16 @@ int rtnl_link_bridge_vlan_add(struct rtnl_link *link,
if (vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED)
vlan_field_set(bd->vlan_info.untagged_bitmap, vlan->vid);

if (vlan->flags & BRIDGE_VLAN_INFO_POLICY_FORCE)
vlan_field_set(bd->vlan_info.force_bitmap, vlan->vid);
else
vlan_field_clear(bd->vlan_info.force_bitmap, vlan->vid);

if (vlan->flags & BRIDGE_VLAN_INFO_POLICY_NEST)
vlan_field_set(bd->vlan_info.nest_bitmap, vlan->vid);
else
vlan_field_clear(bd->vlan_info.nest_bitmap, vlan->vid);

bd->ce_mask |= BRIDGE_ATTR_PORT_VLAN;

return 0;
Expand Down Expand Up @@ -1215,6 +1250,11 @@ int rtnl_link_bridge_vlan_get(struct rtnl_link *link, int vid,
if (vlan_field_get(bd->vlan_info.untagged_bitmap, vid))
vlan->flags |= BRIDGE_VLAN_INFO_UNTAGGED;

if (vlan_field_get(bd->vlan_info.force_bitmap, vid))
vlan->flags |= BRIDGE_VLAN_INFO_POLICY_FORCE;

if (vlan_field_get(bd->vlan_info.nest_bitmap, vid))
vlan->flags |= BRIDGE_VLAN_INFO_POLICY_NEST;
return 0;
}

Expand Down

0 comments on commit 81d6e51

Please sign in to comment.