From 95e7f56eec5797a9e6d46d91441d611592b952cf Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 24 Mar 2025 07:35:22 -0400 Subject: [PATCH] eigrpd: Convert eigrp list to a typesafe hash Convert the eigrp_om->eigrp list to a typesafe hash. Allow for quicker lookup and all that jazz. Signed-off-by: Donald Sharp --- eigrpd/eigrp_network.c | 3 +-- eigrpd/eigrp_structs.h | 4 +++- eigrpd/eigrpd.c | 33 ++++++++++++++++++++------------- eigrpd/eigrpd.h | 10 +++++++++- 4 files changed, 33 insertions(+), 17 deletions(-) diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 0fdb1c27cb..910215cbcb 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -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; diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index c277dcbf5e..93bcf07885 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -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 */ diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 8d1af94991..9a4dd6f55f 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -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; } diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h index a6a4e39a59..15d2bb54ee 100644 --- a/eigrpd/eigrpd.h +++ b/eigrpd/eigrpd.h @@ -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 */ -- 2.39.5