]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: Add hash of nexthop groups
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 24 Jan 2019 13:06:34 +0000 (08:06 -0500)
committerStephen Worley <sworley@cumulusnetworks.com>
Fri, 25 Oct 2019 15:13:35 +0000 (11:13 -0400)
This commit does nothing more than just create a hash structure
that we will use to track nexthop groups.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
zebra/zebra_nhg.c
zebra/zebra_nhg.h
zebra/zebra_router.c
zebra/zebra_router.h

index 4e696b39ac14e1600e575352681aa48fc564e6dc..b3fc46a66f28a16b0ad85cc99a2eb3cdd03c0a62 100644 (file)
@@ -26,6 +26,7 @@
 #include "lib/nexthop_group_private.h"
 #include "lib/routemap.h"
 #include "lib/mpls.h"
+#include "lib/jhash.h"
 
 #include "zebra/connected.h"
 #include "zebra/debug.h"
@@ -558,3 +559,83 @@ int nexthop_active_update(struct route_node *rn, struct route_entry *re)
        return re->nexthop_active_num;
 }
 
+static uint32_t zebra_nhg_hash_key_nexthop_group(struct nexthop_group *nhg)
+{
+       struct nexthop *nh;
+       uint32_t i;
+       uint32_t key = 0;
+
+       /*
+        * We are not interested in hashing over any recursively
+        * resolved nexthops
+        */
+       for (nh = nhg->nexthop; nh; nh = nh->next) {
+               key = jhash_2words(nh->vrf_id, nh->nh_label_type, key);
+               /* gate and blackhole are together in a union */
+               key = jhash(&nh->gate, sizeof(nh->gate), key);
+               key = jhash(&nh->src, sizeof(nh->src), key);
+               key = jhash(&nh->rmap_src, sizeof(nh->rmap_src), key);
+               if (nh->nh_label) {
+                       for (i = 0; i < nh->nh_label->num_labels; i++)
+                               key = jhash_1word(nh->nh_label->label[i], key);
+               }
+               switch (nh->type) {
+               case NEXTHOP_TYPE_IPV4_IFINDEX:
+               case NEXTHOP_TYPE_IPV6_IFINDEX:
+               case NEXTHOP_TYPE_IFINDEX:
+                       key = jhash_1word(nh->ifindex, key);
+                       break;
+               case NEXTHOP_TYPE_BLACKHOLE:
+               case NEXTHOP_TYPE_IPV4:
+               case NEXTHOP_TYPE_IPV6:
+                       break;
+               }
+       }
+       return key;
+}
+
+uint32_t zebra_nhg_hash_key(const void *arg)
+{
+       const struct nhg_hash_entry *nhe = arg;
+       int key = 0x5a351234;
+
+       key = jhash_2words(nhe->vrf_id, nhe->afi, key);
+
+       return jhash_1word(zebra_nhg_hash_key_nexthop_group(&nhe->nhg), key);
+}
+
+bool zebra_nhg_hash_equal(const void *arg1, const void *arg2)
+{
+       const struct nhg_hash_entry *nhe1 = arg1;
+       const struct nhg_hash_entry *nhe2 = arg2;
+       struct nexthop *nh1, *nh2;
+       uint32_t nh_count = 0;
+
+       if (nhe1->vrf_id != nhe2->vrf_id)
+               return false;
+
+       if (nhe1->afi != nhe2->afi)
+               return false;
+
+       /*
+        * Again we are not interested in looking at any recursively
+        * resolved nexthops.  Top level only
+        */
+       for (nh1 = nhe1->nhg.nexthop; nh1; nh1 = nh1->next) {
+               uint32_t inner_nh_count = 0;
+               for (nh2 = nhe2->nhg.nexthop; nh2; nh2 = nh2->next) {
+                       if (inner_nh_count == nh_count) {
+                               break;
+                       }
+                       inner_nh_count++;
+               }
+
+               if (!nexthop_same(nh1, nh2))
+                       return false;
+
+               nh_count++;
+       }
+
+       return true;
+}
+
index ff2351c7599e47b9d9d5fbd81fab0e0b48ef4371..58f8e18b739c2eb1ec6bef414f1cec6d0bfbaac3 100644 (file)
 #define __ZEBRA_NHG_H__
 
 #include "zebra/rib.h"
+#include "lib/nexthop_group.h"
 
 extern int nexthop_active_update(struct route_node *rn, struct route_entry *re);
+
+struct nhg_hash_entry {
+       afi_t afi;
+       vrf_id_t vrf_id;
+
+       struct nexthop_group nhg;
+
+       uint32_t refcnt;
+       uint32_t dplane_ref;
+};
+
+void zebra_nhg_init(void);
+void zebra_nhg_terminate(void);
+
+extern uint32_t zebra_nhg_hash_key(const void *arg);
+
+extern bool zebra_nhg_hash_equal(const void *arg1, const void *arg2);
+
 #endif
index 1e9f9e4ec7d21401218246cb2dc9ea8d7e5b949b..ffffa8c0014ee2034d48b8bc3253cfb540155e6d 100644 (file)
@@ -253,4 +253,8 @@ void zebra_router_init(void)
        zrouter.iptable_hash = hash_create_size(8, zebra_pbr_iptable_hash_key,
                                                zebra_pbr_iptable_hash_equal,
                                                "IPtable Hash Entry");
+
+       zrouter.nhgs =
+               hash_create_size(8, zebra_nhg_hash_key, zebra_nhg_hash_equal,
+                                "Zebra Router Nexthop Groups");
 }
index 25a7adac11f7262a8904de5f0029fc0d4a873906..4bae701d2f137744763c2a99082d84559dcdecfc 100644 (file)
@@ -132,6 +132,11 @@ struct zebra_router {
         * Time for when we sweep the rib from old routes
         */
        time_t startup_time;
+
+       /*
+        * The hash of nexthop groups associated with this router
+        */
+       struct hash *nhgs;
 };
 
 #define GRACEFUL_RESTART_TIME 60