[PATCH] route/link: handle RTEXT_FILTER_BRVLAN_COMPRESSED

Tobias Jungel tobias.jungel at bisdn.de
Thu Nov 26 02:06:03 PST 2015


notifications from the kernel regarding vlan ids are now handled

Signed-off-by: Tobias Jungel <tobias.jungel at bisdn.de>
---
 lib/route/link/bridge.c | 30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/lib/route/link/bridge.c b/lib/route/link/bridge.c
index 9510fde..e40f890 100644
--- a/lib/route/link/bridge.c
+++ b/lib/route/link/bridge.c
@@ -190,6 +190,8 @@ static int bridge_parse_af(struct rtnl_link *link, struct nlattr *attr,
 {
 	struct bridge_data *bd = data;
 	struct bridge_vlan_info *vinfo = NULL;
+	static uint16_t vid_range_start = 0;
+	static uint16_t vid_range_flags = -1;
 
 	if (nla_type(attr) != IFLA_BRIDGE_VLAN_INFO)
 		return 0;
@@ -202,18 +204,32 @@ static int bridge_parse_af(struct rtnl_link *link, struct nlattr *attr,
 		return -EINVAL;
 
 	if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
-		NL_DBG(1, "Unexpected BRIDGE_VLAN_INFO_RANGE_BEGIN flag; can not handle it.\n");
-		return -EINVAL;
+		vid_range_start = vinfo->vid;
+		vid_range_flags = (vinfo->flags ^ BRIDGE_VLAN_INFO_RANGE_BEGIN);
+		return 0;
+	}
+
+	if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) {
+		/* sanity check the range flags */
+		if (vid_range_flags != (vinfo->flags ^ BRIDGE_VLAN_INFO_RANGE_END)) {
+			NL_DBG(1, "VLAN range flags differ; can not handle it.\n");
+			return -EINVAL;
+		}
+	} else {
+		vid_range_start = vinfo->vid;
 	}
 
-	if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
-		bd->vlan_info.pvid = vinfo->vid;
+	for (; vid_range_start <= vinfo->vid; vid_range_start++) {
+		if (vinfo->flags & BRIDGE_VLAN_INFO_PVID)
+			bd->vlan_info.pvid = vinfo->vid;
 
-	if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
-		set_bit(vinfo->vid, bd->vlan_info.untagged_bitmap);
+		if (vinfo->flags & BRIDGE_VLAN_INFO_UNTAGGED)
+			set_bit(vid_range_start, bd->vlan_info.untagged_bitmap);
 
-	set_bit(vinfo->vid, bd->vlan_info.vlan_bitmap);
+		set_bit(vid_range_start, bd->vlan_info.vlan_bitmap);
+	}
 
+	vid_range_flags = -1;
 	bd->ce_mask |= BRIDGE_ATTR_PORT_VLAN;
 
 	return 0;
-- 
2.5.0




More information about the libnl mailing list