]> granicus.if.org Git - libnl/commitdiff
Add hash support to route cache
authorroopa <roopa@cumulusnetworks.com>
Fri, 9 Nov 2012 22:41:36 +0000 (14:41 -0800)
committerThomas Graf <tgraf@redhat.com>
Fri, 9 Nov 2012 23:13:05 +0000 (00:13 +0100)
This patch adds keygen function to route object

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

index 54df023796a0c550d84cb631e629b0cbd7d1998e..0ee9ca02aa2afc5632ef485d1f6c20a20153eb84 100644 (file)
@@ -35,6 +35,7 @@
 #include <netlink/cache.h>
 #include <netlink/utils.h>
 #include <netlink/data.h>
+#include <netlink/hashtable.h>
 #include <netlink/route/rtnl.h>
 #include <netlink/route/route.h>
 #include <netlink/route/link.h>
@@ -289,6 +290,51 @@ static void route_dump_stats(struct nl_object *obj, struct nl_dump_params *p)
        }
 }
 
+static void route_keygen(struct nl_object *obj, uint32_t *hashkey,
+                         uint32_t table_sz)
+{
+       struct rtnl_route *route = (struct rtnl_route *) obj;
+       unsigned int rkey_sz;
+       struct nl_addr *addr = NULL;
+       struct route_hash_key {
+               uint8_t         rt_family;
+               uint8_t         rt_tos;
+               uint32_t        rt_table;
+               char            rt_addr[0];
+       } __attribute__((packed)) *rkey;
+       char buf[INET6_ADDRSTRLEN+5];
+
+       if (route->rt_dst)
+               addr = route->rt_dst;
+
+       rkey_sz = sizeof(*rkey);
+       if (addr)
+               rkey_sz += nl_addr_get_len(addr);
+       rkey = calloc(1, rkey_sz);
+       if (!rkey) {
+               NL_DBG(2, "Warning: calloc failed for %d bytes...\n", rkey_sz);
+               *hashkey = 0;
+               return;
+       }
+       rkey->rt_family = route->rt_family;
+       rkey->rt_tos = route->rt_tos;
+       rkey->rt_table = route->rt_table;
+       if (addr)
+               memcpy(rkey->rt_addr, nl_addr_get_binary_addr(addr),
+                       nl_addr_get_len(addr));
+
+       *hashkey = nl_hash(rkey, rkey_sz, 0) % table_sz;
+
+       NL_DBG(5, "route %p key (fam %d tos %d table %d addr %s) keysz %d "
+               "hash 0x%x\n", route, rkey->rt_family, rkey->rt_tos,
+               rkey->rt_table, nl_addr2str(addr, buf, sizeof(buf)),
+               rkey_sz, *hashkey);
+
+       free(rkey);
+
+       return;
+}
+
 static int route_compare(struct nl_object *_a, struct nl_object *_b,
                        uint32_t attrs, int flags)
 {
@@ -1151,6 +1197,7 @@ struct nl_object_ops route_obj_ops = {
            [NL_DUMP_STATS]     = route_dump_stats,
        },
        .oo_compare             = route_compare,
+       .oo_keygen              = route_keygen,
        .oo_attrs2str           = route_attrs2str,
        .oo_id_attrs            = (ROUTE_ATTR_FAMILY | ROUTE_ATTR_TOS |
                                   ROUTE_ATTR_TABLE | ROUTE_ATTR_DST),