]> git.puffer.fish Git - matthieu/frr.git/commitdiff
eigrpd: Convert eigrp list to a typesafe hash
authorDonald Sharp <sharpd@nvidia.com>
Mon, 24 Mar 2025 11:35:22 +0000 (07:35 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Mon, 24 Mar 2025 15:36:13 +0000 (11:36 -0400)
Convert the eigrp_om->eigrp list to a typesafe hash.
Allow for quicker lookup and all that jazz.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
eigrpd/eigrp_network.c
eigrpd/eigrp_structs.h
eigrpd/eigrpd.c
eigrpd/eigrpd.h

index 0fdb1c27cbe7db690e2013e7e1738856adb46fef..910215cbcbea2b7c97f43cc2d8c361b187354c38 100644 (file)
@@ -262,7 +262,6 @@ static void eigrp_network_run_interface(struct eigrp *eigrp, struct prefix *p,
 
 void eigrp_if_update(struct interface *ifp)
 {
-       struct listnode *node, *nnode;
        struct route_node *rn;
        struct eigrp *eigrp;
 
@@ -270,7 +269,7 @@ void eigrp_if_update(struct interface *ifp)
         * In the event there are multiple eigrp autonymnous systems running,
         * we need to check eac one and add the interface as approperate
         */
-       for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) {
+       frr_each (eigrp_master_hash, &eigrp_om->eigrp, eigrp) {
                if (ifp->vrf->vrf_id != eigrp->vrf_id)
                        continue;
 
index c277dcbf5e20f63b25593b2cf5c94baab0067ac3..93bcf07885f6baaa004dcf9eaf12850fc96dbbc9 100644 (file)
@@ -44,8 +44,10 @@ struct eigrp_extdata {
 };
 
 PREDECL_HASH(eigrp_interface_hash);
-
+PREDECL_HASH(eigrp_master_hash);
 struct eigrp {
+       struct eigrp_master_hash_item eigrp_item;
+
        vrf_id_t vrf_id;
 
        uint16_t AS;     /* Autonomous system number */
index 8d1af9499103f57cf1b9a458c0c250e1721f0901..9a4dd6f55ff9322906ab247749140ad4d889bb1a 100644 (file)
@@ -55,6 +55,15 @@ struct eigrp_master *eigrp_om;
 extern struct zclient *zclient;
 extern struct in_addr router_id_zebra;
 
+int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b)
+{
+       return a->vrf_id - b->vrf_id;
+}
+
+uint32_t eigrp_master_hash_hash(const struct eigrp *a)
+{
+       return a->vrf_id;
+}
 
 /*
  * void eigrp_router_id_update(struct eigrp *eigrp)
@@ -111,7 +120,7 @@ void eigrp_master_init(void)
        memset(&eigrp_master, 0, sizeof(eigrp_master));
 
        eigrp_om = &eigrp_master;
-       eigrp_om->eigrp = list_new();
+       eigrp_master_hash_init(&eigrp_om->eigrp);
 
        monotime(&tv);
        eigrp_om->start_time = tv.tv_sec;
@@ -206,7 +215,7 @@ struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id)
        eigrp = eigrp_lookup(vrf_id);
        if (eigrp == NULL) {
                eigrp = eigrp_new(as, vrf_id);
-               listnode_add(eigrp_om->eigrp, eigrp);
+               eigrp_master_hash_add(&eigrp_om->eigrp, eigrp);
        }
 
        return eigrp;
@@ -216,7 +225,6 @@ struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id)
 void eigrp_terminate(void)
 {
        struct eigrp *eigrp;
-       struct listnode *node, *nnode;
 
        /* shutdown already in progress */
        if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN))
@@ -224,9 +232,10 @@ void eigrp_terminate(void)
 
        SET_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN);
 
-       for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp))
+       frr_each (eigrp_master_hash, &eigrp_om->eigrp, eigrp)
                eigrp_finish(eigrp);
 
+       eigrp_master_hash_fini(&eigrp_om->eigrp);
        frr_fini();
 }
 
@@ -235,8 +244,8 @@ void eigrp_finish(struct eigrp *eigrp)
        eigrp_finish_final(eigrp);
 
        /* eigrp being shut-down? If so, was this the last eigrp instance? */
-       if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN)
-           && (listcount(eigrp_om->eigrp) == 0)) {
+       if (CHECK_FLAG(eigrp_om->options, EIGRP_MASTER_SHUTDOWN) &&
+           (eigrp_master_hash_count(&eigrp_om->eigrp) == 0)) {
                if (zclient) {
                        zclient_stop(zclient);
                        zclient_free(zclient);
@@ -276,7 +285,7 @@ void eigrp_finish_final(struct eigrp *eigrp)
        list_delete(&eigrp->topology_changes_externalIPV4);
        list_delete(&eigrp->topology_changes_internalIPV4);
 
-       listnode_delete(eigrp_om->eigrp, eigrp);
+       eigrp_master_hash_del(&eigrp_om->eigrp, eigrp);
 
        stream_free(eigrp->ibuf);
        distribute_list_delete(&eigrp->distribute_ctx);
@@ -286,12 +295,10 @@ void eigrp_finish_final(struct eigrp *eigrp)
 /*Look for existing eigrp process*/
 struct eigrp *eigrp_lookup(vrf_id_t vrf_id)
 {
-       struct eigrp *eigrp;
-       struct listnode *node, *nnode;
+       struct eigrp *eigrp, lookup;
 
-       for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp))
-               if (eigrp->vrf_id == vrf_id)
-                       return eigrp;
+       lookup.vrf_id = vrf_id;
+       eigrp = eigrp_master_hash_find(&eigrp_om->eigrp, &lookup);
 
-       return NULL;
+       return eigrp;
 }
index a6a4e39a591fba005b0ce316e63461cfb5fb0f9e..15d2bb54ee85f454836af3121bd8eec5873d5a5e 100644 (file)
@@ -30,9 +30,11 @@ DECLARE_MGROUP(EIGRPD);
 #define EIGRP_TLV_MTR_VERSION 3 /* MTR TLVs with 32bit metric *Not Supported */
 #define EIGRP_TLV_SAF_VERSION 4 /* SAF TLVs with 64bit metric *Not Supported */
 
+//PREDECL_HASH(eigrp_master_hash);
+
 struct eigrp_master {
        /* EIGRP instance. */
-       struct list *eigrp;
+       struct eigrp_master_hash_head eigrp;
 
        /* EIGRP thread master. */
        struct event_loop *master;
@@ -64,4 +66,10 @@ extern struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id);
 extern struct eigrp *eigrp_lookup(vrf_id_t vrf_id);
 extern void eigrp_router_id_update(struct eigrp *eigrp);
 
+extern int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b);
+extern uint32_t eigrp_master_hash_hash(const struct eigrp *a);
+
+DECLARE_HASH(eigrp_master_hash, struct eigrp, eigrp_item, eigrp_master_hash_cmp,
+            eigrp_master_hash_hash);
+
 #endif /* _ZEBRA_EIGRPD_H */