[RFC PATCH 3/5] Add AF_BRIDGE object update support to link cache

roopa at cumulusnetworks.com roopa at cumulusnetworks.com
Mon Nov 5 08:37:36 EST 2012


From: roopa <roopa at cumulusnetworks.com>

This patch implements the oo_update operation for link cache objects.
This implementation currently only handles objects of type AF_BRIDGE.

It updates the existing link object with the attributes of the new
AF_BRIDGE link object

Signed-off-by: Roopa Prabhu <roopa at cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan at cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm at cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok at cumulusnetworks.com>
---
 lib/route/link.c |   82 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/lib/route/link.c b/lib/route/link.c
index 3f9d9dc..ad2c9ef 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -239,6 +239,72 @@ static int link_clone(struct nl_object *_dst, struct nl_object *_src)
 	return 0;
 }
 
+static int link_update(struct nl_object *_dst, struct nl_object *_src)
+{
+	struct rtnl_link *dst = nl_object_priv(_dst);
+	struct rtnl_link *src = nl_object_priv(_src);
+	struct rtnl_link_af_ops *af_ops = NULL;
+	int src_family;
+	int err = NLE_SUCCESS;
+
+	/*
+	 * Only supported for bridge family link objects
+	 */
+	if (src->l_family != AF_BRIDGE)
+		return -NLE_OPNOTSUPP;
+
+	/*
+	 * These are changes specific to AF_BRIDGE
+	 * family
+	 */
+	af_ops = rtnl_link_af_ops_lookup(src->l_family);
+	if (!af_ops)
+	    return -NLE_FAILURE;
+
+	src_family = src->l_family;
+
+	switch (src->ce_msgtype) {
+	case RTM_NEWLINK:
+	case RTM_DELLINK:
+		/*
+		 * Free AF_BRIDGE af_data in dst,
+		 * to make room for new af_data
+		 */
+		if (dst->l_af_data[src_family]) {
+			if (!af_ops->ao_free)
+				BUG();
+
+			af_ops->ao_free(dst, dst->l_af_data[src_family]);
+		}
+		dst->l_flags = src->l_flags;
+		dst->l_mtu = src->l_mtu;
+		dst->l_operstate = src->l_operstate;
+
+		if (src->ce_msgtype == RTM_NEWLINK) {
+			dst->l_master = src->l_master;
+			dst->ce_mask |= LINK_ATTR_MASTER;
+
+			/*
+			 * Copy over new AF_BRIDGE af_data
+			 */
+			if (src->l_af_data[src_family])
+				dst->l_af_data[src_family] = af_ops->ao_clone(
+					dst, src->l_af_data[src_family]);
+		} else {
+			dst->l_master = 0;
+			dst->ce_mask &= ~LINK_ATTR_MASTER;
+		}
+		break;
+
+	default:
+		err = -NLE_OPNOTSUPP;
+	}
+
+	rtnl_link_af_ops_put(af_ops);
+
+	return err;
+}
+
 static struct nla_policy link_policy[IFLA_MAX+1] = {
 	[IFLA_IFNAME]		= { .type = NLA_STRING,
 				    .maxlen = IFNAMSIZ },
@@ -570,19 +636,6 @@ errout:
 	return err;
 }
 
-static int link_event_filter(struct nl_cache *cache, struct nl_object *obj)
-{
-	struct rtnl_link *link = (struct rtnl_link *) obj;
-
-	/*
-	 * Ignore bridging messages when keeping the cache manager up to date.
-	 */
-	if (link->l_family == AF_BRIDGE)
-		return NL_SKIP;
-
-	return NL_OK;
-}
-
 static int link_request_update(struct nl_cache *cache, struct nl_sock *sk)
 {
 	int family = cache->c_iarg1;
@@ -2502,10 +2555,12 @@ static struct nl_object_ops link_obj_ops = {
 	.oo_compare		= link_compare,
 	.oo_attrs2str		= link_attrs2str,
 	.oo_id_attrs		= LINK_ATTR_IFINDEX,
+	.oo_update		= link_update
 };
 
 static struct nl_af_group link_groups[] = {
 	{ AF_UNSPEC,	RTNLGRP_LINK },
+	{ AF_BRIDGE,	RTNLGRP_LINK },
 	{ END_OF_GROUP_LIST },
 };
 
@@ -2523,7 +2578,6 @@ static struct nl_cache_ops rtnl_link_ops = {
 	.co_groups		= link_groups,
 	.co_request_update	= link_request_update,
 	.co_msg_parser		= link_msg_parser,
-	.co_event_filter	= link_event_filter,
 	.co_obj_ops		= &link_obj_ops,
 };
 
-- 
1.7.2.5




More information about the libnl mailing list