summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2025-03-24 07:35:22 -0400
committerDonald Sharp <sharpd@nvidia.com>2025-03-24 11:36:13 -0400
commit95e7f56eec5797a9e6d46d91441d611592b952cf (patch)
tree5c6333117627bbf69278c21a293034346f4e335f
parentcb34559d7fbd9b333ed26bfb55ae61bf888b46de (diff)
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 <sharpd@nvidia.com>
-rw-r--r--eigrpd/eigrp_network.c3
-rw-r--r--eigrpd/eigrp_structs.h4
-rw-r--r--eigrpd/eigrpd.c33
-rw-r--r--eigrpd/eigrpd.h10
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 */