[PATCH 1/1] route/vlan: allow clearing vlan ingress map

Thomas Haller thaller at redhat.com
Wed Oct 21 09:01:02 PDT 2015


An entry of the ingress map can be cleared by setting
the "to" part to zero.

Previously, vlan_put_attrs() would skip over zero "to"
and thus the user cannot unset an ingress map entry.

Add a modified-mask to record the state of each ingress
map entry and also sent explicit zeros to kernel.

when we receive a IFLA_VLAN_INGRESS_QOS message from kernel,
vlan_parse() similarly sets the received entries as modified.
This preserves previous behavior when using a received object
to modify a vlan.

Add a capability NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR
to indicate the behavioral change.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 include/netlink/utils.h |  8 ++++++++
 lib/route/link/vlan.c   | 18 ++++++++++++++++--
 lib/utils.c             |  2 +-
 3 files changed, 25 insertions(+), 3 deletions(-)

diff --git a/include/netlink/utils.h b/include/netlink/utils.h
index 31e27f7..9c2ffbb 100644
--- a/include/netlink/utils.h
+++ b/include/netlink/utils.h
@@ -165,6 +165,14 @@ enum {
 	NL_CAPABILITY_VERSION_3_2_27 = 11,
 #define NL_CAPABILITY_VERSION_3_2_27 NL_CAPABILITY_VERSION_3_2_27
 
+	/**
+	 * Don't skip over vlan ingress-map entries with "to" field zero when serializing
+	 * a netlink message. Previously such entires would be ignored which inhibits the
+	 * user from clearing ingress map entries.
+	 */
+	NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR = 12,
+#define NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR
+
 	__NL_CAPABILITY_MAX,
 	NL_CAPABILITY_MAX = (__NL_CAPABILITY_MAX - 1),
 #define NL_CAPABILITY_MAX NL_CAPABILITY_MAX
diff --git a/lib/route/link/vlan.c b/lib/route/link/vlan.c
index a623bbd..7f296df 100644
--- a/lib/route/link/vlan.c
+++ b/lib/route/link/vlan.c
@@ -44,6 +44,7 @@ struct vlan_info
 {
 	uint16_t		vi_vlan_id;
 	uint16_t		vi_protocol;
+	unsigned int            vi_ingress_qos_mask:(VLAN_PRIO_MAX+1);
 	uint32_t		vi_flags;
 	uint32_t		vi_flags_mask;
 	uint32_t		vi_ingress_qos[VLAN_PRIO_MAX+1];
@@ -121,6 +122,7 @@ static int vlan_parse(struct rtnl_link *link, struct nlattr *data,
 		struct nlattr *nla;
 		int remaining;
 
+		vi->vi_ingress_qos_mask = 0;
 		memset(vi->vi_ingress_qos, 0, sizeof(vi->vi_ingress_qos));
 
 		nla_for_each_nested(nla, tb[IFLA_VLAN_INGRESS_QOS], remaining) {
@@ -132,6 +134,17 @@ static int vlan_parse(struct rtnl_link *link, struct nlattr *data,
 				return -NLE_INVAL;
 			}
 
+			/* Kernel will not explicitly serialize mappings with "to" zero
+			 * (although they are implicitly set).
+			 *
+			 * Thus we only mark those as "set" which are explicitly sent.
+			 * That is similar to what we do with the egress map and it preserves
+			 * previous behavior before NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR.
+			 *
+			 * It matters only when a received object is send back to kernel to modify
+			 * the link.
+			 */
+			vi->vi_ingress_qos_mask |= (1 << map->from);
 			vi->vi_ingress_qos[map->from] = map->to;
 		}
 
@@ -211,7 +224,7 @@ static void vlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
 		nl_dump_line(p, 
 		"      ingress vlan prio -> qos/socket prio mapping:\n");
 		for (i = 0, printed = 0; i <= VLAN_PRIO_MAX; i++) {
-			if (vi->vi_ingress_qos[i]) {
+			if (vi->vi_ingress_qos_mask & (1 << i)) {
 				if (printed == 0)
 					nl_dump_line(p, "      ");
 				nl_dump(p, "%x -> %#08x, ",
@@ -297,7 +310,7 @@ static int vlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
 			goto nla_put_failure;
 
 		for (i = 0; i <= VLAN_PRIO_MAX; i++) {
-			if (vi->vi_ingress_qos[i]) {
+			if (vi->vi_ingress_qos_mask & (1 << i)) {
 				map.from = i;
 				map.to = vi->vi_ingress_qos[i];
 
@@ -537,6 +550,7 @@ int rtnl_link_vlan_set_ingress_map(struct rtnl_link *link, int from,
 	if (from < 0 || from > VLAN_PRIO_MAX)
 		return -NLE_INVAL;
 
+	vi->vi_ingress_qos_mask |= (1 << from);
 	vi->vi_ingress_qos[from] = to;
 	vi->vi_mask |= VLAN_HAS_INGRESS_QOS;
 
diff --git a/lib/utils.c b/lib/utils.c
index 08db79e..95bf042 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -1155,7 +1155,7 @@ int nl_has_capability (int capability)
 			NL_CAPABILITY_LINK_BUILD_CHANGE_REQUEST_SET_CHANGE,
 			NL_CAPABILITY_RTNL_NEIGH_GET_FILTER_AF_UNSPEC_FIX,
 			NL_CAPABILITY_VERSION_3_2_27,
-			0,
+			NL_CAPABILITY_RTNL_LINK_VLAN_INGRESS_MAP_CLEAR,
 			0,
 			0,
 			0,
-- 
2.4.3




More information about the libnl mailing list