[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