]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
Add master support to rtnl_neigh for AF_BRIDGE objects
authorroopa <roopa@cumulusnetworks.com>
Wed, 14 Nov 2012 19:33:51 +0000 (11:33 -0800)
committerThomas Graf <tgraf@suug.ch>
Thu, 15 Nov 2012 18:42:47 +0000 (19:42 +0100)
AF_BRIDGE neigh objects can be uniquely identified by
the family, lladdr and bridge ifindex. This patch adds
bridge ifindex to AF_BRIDGE neigh objects.

Things will be ok even without this patch with just family and
lladdr if we assume that we will have unique lladdr's
accross bridges in a system.

Kernel does not send the bridge ifindex in the AF_BRIDGE
fdb/neigh message. This patch tries to get that info by a
link cache lookup and adds it to the bridge neigh object

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
include/netlink-types.h
lib/route/neigh.c

index 01b450539dc9b429009d3aa94cc572d79fb6769d..02ecf0488a0b36f98692e90f64cc32946666219e 100644 (file)
@@ -205,6 +205,7 @@ struct rtnl_neigh
        struct rtnl_ncacheinfo n_cacheinfo;
        uint32_t                n_state_mask;
        uint32_t                n_flag_mask;
+       uint32_t                n_master;
 };
 
 
index 8e1f4222dfce1e76f272637d44f557fb038cf21e..4b5893a052488421963f0d15f166b946133dc408 100644 (file)
 #define NEIGH_ATTR_FAMILY       0x40
 #define NEIGH_ATTR_TYPE         0x80
 #define NEIGH_ATTR_PROBES       0x100
+#define NEIGH_ATTR_MASTER       0x200
 
 static struct nl_cache_ops rtnl_neigh_ops;
 static struct nl_object_ops neigh_obj_ops;
@@ -229,7 +230,9 @@ static void neigh_keygen(struct nl_object *obj, uint32_t *hashkey,
                return;
        }
        nkey->n_family = neigh->n_family;
-       if (neigh->n_family != AF_BRIDGE)
+       if (neigh->n_family == AF_BRIDGE)
+               nkey->n_ifindex = neigh->n_master;
+       else
                nkey->n_ifindex = neigh->n_ifindex;
        if (addr)
                memcpy(nkey->n_addr,
@@ -262,6 +265,7 @@ static int neigh_compare(struct nl_object *_a, struct nl_object *_b,
        diff |= NEIGH_DIFF(TYPE,        a->n_type != b->n_type);
        diff |= NEIGH_DIFF(LLADDR,      nl_addr_cmp(a->n_lladdr, b->n_lladdr));
        diff |= NEIGH_DIFF(DST,         nl_addr_cmp(a->n_dst, b->n_dst));
+       diff |= NEIGH_DIFF(MASTER,      a->n_master != b->n_master);
 
        if (flags & LOOSE_COMPARISON) {
                diff |= NEIGH_DIFF(STATE,
@@ -301,7 +305,7 @@ static uint32_t neigh_id_attrs_get(struct nl_object *obj)
        struct rtnl_neigh *neigh = (struct rtnl_neigh *)obj;
 
        if (neigh->n_family == AF_BRIDGE)
-               return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY);
+               return (NEIGH_ATTR_LLADDR | NEIGH_ATTR_FAMILY | NEIGH_ATTR_MASTER);
        else
                return (NEIGH_ATTR_IFINDEX | NEIGH_ATTR_DST | NEIGH_ATTR_FAMILY);
 }
@@ -393,6 +397,22 @@ int rtnl_neigh_parse(struct nlmsghdr *n, struct rtnl_neigh **result)
                neigh->ce_mask |= NEIGH_ATTR_PROBES;
        }
 
+       /*
+        * Get the bridge index for AF_BRIDGE family entries
+        */
+       if (neigh->n_family == AF_BRIDGE) {
+               struct nl_cache *lcache = nl_cache_mngt_require("route/link");
+               if (lcache ) {
+                       struct rtnl_link *link = rtnl_link_get(lcache,
+                                                       neigh->n_ifindex);
+                       if (link) {
+                               neigh->n_master = link->l_master;
+                               rtnl_link_put(link);
+                               neigh->ce_mask |= NEIGH_ATTR_MASTER;
+                       }
+               }
+       }
+
        *result = neigh;
        return 0;