From: Donald Sharp Date: Mon, 24 Mar 2025 01:16:56 +0000 (-0400) Subject: eigrpd: Convert the eiflist to a typesafe hash X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=cb34559d7fbd9b333ed26bfb55ae61bf888b46de;p=matthieu%2Ffrr.git eigrpd: Convert the eiflist to a typesafe hash The eigrp->eiflist is a linked list and should just be a hash instead. The full conversion to a hash like functionality is goingto wait until the connected eigrp data structure is created. Signed-off-by: Donald Sharp --- diff --git a/eigrpd/eigrp_filter.c b/eigrpd/eigrp_filter.c index eceef6b8a7..d6f2ddf7f4 100644 --- a/eigrpd/eigrp_filter.c +++ b/eigrpd/eigrp_filter.c @@ -42,6 +42,7 @@ #include "eigrpd/eigrp_const.h" #include "eigrpd/eigrp_filter.h" #include "eigrpd/eigrp_packet.h" +#include "eigrpd/eigrp_interface.h" /* * Distribute-list update functions. @@ -126,10 +127,9 @@ void eigrp_distribute_update(struct distribute_ctx *ctx, /*struct eigrp_if_info * info = ifp->info; ei = info->eigrp_interface;*/ - struct listnode *node, *nnode; struct eigrp_interface *ei2; /* Find proper interface */ - for (ALL_LIST_ELEMENTS(e->eiflist, node, nnode, ei2)) { + frr_each (eigrp_interface_hash, &e->eifs, ei2) { if (strcmp(ei2->ifp->name, ifp->name) == 0) { ei = ei2; break; diff --git a/eigrpd/eigrp_hello.c b/eigrpd/eigrp_hello.c index bd2b8ccbbd..fe80651b9b 100644 --- a/eigrpd/eigrp_hello.c +++ b/eigrpd/eigrp_hello.c @@ -496,7 +496,6 @@ static uint16_t eigrp_sequence_encode(struct eigrp *eigrp, struct stream *s) { uint16_t length = EIGRP_TLV_SEQ_BASE_LEN; struct eigrp_interface *ei; - struct listnode *node; struct eigrp_neighbor *nbr; size_t backup_end, size_end; int found; @@ -509,7 +508,7 @@ static uint16_t eigrp_sequence_encode(struct eigrp *eigrp, struct stream *s) stream_putc(s, IPV4_MAX_BYTELEN); found = 0; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (nbr->multicast_queue->count > 0) { length += (uint16_t)stream_put_ipv4( diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 05012e63b2..2e3beacae7 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -45,6 +45,16 @@ DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IF, "EIGRP interface"); +int eigrp_interface_cmp(const struct eigrp_interface *a, const struct eigrp_interface *b) +{ + return if_cmp_func(a->ifp, b->ifp); +} + +uint32_t eigrp_interface_hash(const struct eigrp_interface *ei) +{ + return ei->ifp->ifindex; +} + struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, struct prefix *p) { @@ -61,7 +71,7 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, prefix_copy(&ei->address, p); ifp->info = ei; - listnode_add(eigrp->eiflist, ei); + eigrp_interface_hash_add(&eigrp->eifs, ei); ei->type = EIGRP_IFTYPE_BROADCAST; @@ -105,7 +115,7 @@ int eigrp_if_delete_hook(struct interface *ifp) eigrp_nbr_hash_fini(&ei->nbr_hash_head); eigrp = ei->eigrp; - listnode_delete(eigrp->eiflist, ei); + eigrp_interface_hash_del(&eigrp->eifs, ei); eigrp_fifo_free(ei->obuf); @@ -238,7 +248,6 @@ int eigrp_if_up(struct eigrp_interface *ei) struct eigrp_route_descriptor *ne; struct eigrp_metrics metric; struct eigrp_interface *ei2; - struct listnode *node, *nnode; struct eigrp *eigrp; if (ei == NULL) @@ -300,9 +309,8 @@ int eigrp_if_up(struct eigrp_interface *ei) eigrp_route_descriptor_add(eigrp, pe, ne); - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei2) eigrp_update_send(ei2); - } pe->req_action &= ~EIGRP_FSM_NEED_UPDATE; listnode_delete(eigrp->topology_changes_internalIPV4, pe); @@ -434,7 +442,7 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) eigrp_if_down(ei); - listnode_delete(ei->eigrp->eiflist, ei); + eigrp_interface_hash_del(&ei->eigrp->eifs, ei); } /* Simulate down/up on the interface. This is needed, for example, when @@ -454,10 +462,9 @@ struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp, struct interface *ifp, struct in_addr address) { - struct listnode *node; struct eigrp_interface *ei; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { if (ifp && ei->ifp != ifp) continue; @@ -483,10 +490,10 @@ struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *eigrp, const char *if_name) { struct eigrp_interface *ei; - struct listnode *node; /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + // XXX + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* compare int name with eigrp interface's name */ if (strcmp(ei->ifp->name, if_name) == 0) { return ei; diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h index 76f9c1bcb6..effafeaea5 100644 --- a/eigrpd/eigrp_interface.h +++ b/eigrpd/eigrp_interface.h @@ -43,4 +43,10 @@ extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *, /* Simulate down/up on the interface. */ extern void eigrp_if_reset(struct interface *); +extern int eigrp_interface_cmp(const struct eigrp_interface *a, const struct eigrp_interface *b); +extern uint32_t eigrp_interface_hash(const struct eigrp_interface *ei); + +DECLARE_HASH(eigrp_interface_hash, struct eigrp_interface, eif_item, eigrp_interface_cmp, + eigrp_interface_hash); + #endif /* ZEBRA_EIGRP_INTERFACE_H_ */ diff --git a/eigrpd/eigrp_neighbor.c b/eigrpd/eigrp_neighbor.c index 578d1671c8..ac3cbd04b2 100644 --- a/eigrpd/eigrp_neighbor.c +++ b/eigrpd/eigrp_neighbor.c @@ -150,11 +150,10 @@ struct eigrp_neighbor *eigrp_nbr_lookup_by_addr_process(struct eigrp *eigrp, struct in_addr nbr_addr) { struct eigrp_interface *ei; - struct listnode *node; struct eigrp_neighbor lookup, *nbr; /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* iterate over all neighbors on eigrp interface */ lookup.src = nbr_addr; nbr = eigrp_nbr_hash_find(&ei->nbr_hash_head, &lookup); @@ -289,11 +288,10 @@ void eigrp_nbr_state_update(struct eigrp_neighbor *nbr) int eigrp_nbr_count_get(struct eigrp *eigrp) { struct eigrp_interface *iface; - struct listnode *node; uint32_t counter; counter = 0; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) + frr_each (eigrp_interface_hash, &eigrp->eifs, iface) counter += eigrp_nbr_hash_count(&iface->nbr_hash_head); return counter; diff --git a/eigrpd/eigrp_network.c b/eigrpd/eigrp_network.c index 5ca5a18a97..0fdb1c27cb 100644 --- a/eigrpd/eigrp_network.c +++ b/eigrpd/eigrp_network.c @@ -289,7 +289,6 @@ void eigrp_if_update(struct interface *ifp) int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p) { struct route_node *rn; - struct listnode *node, *nnode; struct eigrp_interface *ei; struct prefix *pref; @@ -307,7 +306,7 @@ int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p) route_unlock_node(rn); /* initial reference */ /* Find interfaces that not configured already. */ - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { bool found = false; for (rn = route_top(eigrp->networks); rn; rn = route_next(rn)) { diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c index 4aeb635c05..90af47e9e2 100644 --- a/eigrpd/eigrp_northbound.c +++ b/eigrpd/eigrp_northbound.c @@ -43,13 +43,11 @@ static void redistribute_get_metrics(const struct lyd_node *dnode, em->reliability = yang_dnode_get_uint32(dnode, "reliability"); } -static struct eigrp_interface *eigrp_interface_lookup(const struct eigrp *eigrp, - const char *ifname) +static struct eigrp_interface *eigrp_interface_lookup(struct eigrp *eigrp, const char *ifname) { struct eigrp_interface *eif; - struct listnode *ln; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, ln, eif)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, eif) { if (strcmp(ifname, eif->ifp->name)) continue; diff --git a/eigrpd/eigrp_packet.c b/eigrpd/eigrp_packet.c index 963d229bc1..189d9330cf 100644 --- a/eigrpd/eigrp_packet.c +++ b/eigrpd/eigrp_packet.c @@ -532,8 +532,8 @@ void eigrp_read(struct event *thread) return; /* Self-originated packet should be discarded silently. */ - if (eigrp_if_lookup_by_local_addr(eigrp, NULL, iph->ip_src) - || (IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) { + if (eigrp_if_lookup_by_local_addr(eigrp, ifp, iph->ip_src) || + (IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) { if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) zlog_debug( "eigrp_read[%pI4]: Dropping self-originated packet", diff --git a/eigrpd/eigrp_query.c b/eigrpd/eigrp_query.c index aaa8f9478c..d4f00fb139 100644 --- a/eigrpd/eigrp_query.c +++ b/eigrpd/eigrp_query.c @@ -41,7 +41,7 @@ uint32_t eigrp_query_send_all(struct eigrp *eigrp) { struct eigrp_interface *iface; - struct listnode *node, *node2, *nnode2; + struct listnode *node2, *nnode2; struct eigrp_prefix_descriptor *pe; uint32_t counter; @@ -51,7 +51,7 @@ uint32_t eigrp_query_send_all(struct eigrp *eigrp) } counter = 0; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, iface) { eigrp_send_query(iface); counter++; } diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c index 420cb6cb41..605a1ae4b8 100644 --- a/eigrpd/eigrp_routemap.c +++ b/eigrpd/eigrp_routemap.c @@ -43,7 +43,6 @@ void eigrp_if_rmap_update(struct if_rmap *if_rmap) { struct interface *ifp; struct eigrp_interface *ei, *ei2; - struct listnode *node, *nnode; struct route_map *rmap; struct eigrp *e; @@ -53,7 +52,7 @@ void eigrp_if_rmap_update(struct if_rmap *if_rmap) ei = NULL; e = eigrp_lookup(); - for (ALL_LIST_ELEMENTS(e->eiflist, node, nnode, ei2)) { + frr_each (eigrp_interface_hash, &e->eifs, ei2) { if (strcmp(ei2->ifp->name, ifp->name) == 0) { ei = ei2; break; diff --git a/eigrpd/eigrp_structs.h b/eigrpd/eigrp_structs.h index 4acb8b10b5..c277dcbf5e 100644 --- a/eigrpd/eigrp_structs.h +++ b/eigrpd/eigrp_structs.h @@ -43,6 +43,8 @@ struct eigrp_extdata { uint8_t flags; }; +PREDECL_HASH(eigrp_interface_hash); + struct eigrp { vrf_id_t vrf_id; @@ -59,7 +61,7 @@ struct eigrp { struct in_addr router_id; /* Configured automatically. */ struct in_addr router_id_static; /* Configured manually. */ - struct list *eiflist; /* eigrp interfaces */ + struct eigrp_interface_hash_head eifs; uint8_t passive_interface_default; /* passive-interface default */ int fd; @@ -137,6 +139,8 @@ PREDECL_HASH(eigrp_nbr_hash); /*EIGRP interface structure*/ struct eigrp_interface { + struct eigrp_interface_hash_item eif_item; + struct eigrp_if_params params; /*multicast group refcnts */ diff --git a/eigrpd/eigrp_update.c b/eigrpd/eigrp_update.c index bb61a3e6c1..6511db2feb 100644 --- a/eigrpd/eigrp_update.c +++ b/eigrpd/eigrp_update.c @@ -693,10 +693,10 @@ void eigrp_update_send_all(struct eigrp *eigrp, struct eigrp_interface *exception) { struct eigrp_interface *iface; - struct listnode *node, *node2, *nnode2; + struct listnode *node2, *nnode2; struct eigrp_prefix_descriptor *pe; - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, iface) { if (iface != exception) { eigrp_update_send(iface); } @@ -1025,11 +1025,10 @@ void eigrp_update_send_interface_GR(struct eigrp_interface *ei, void eigrp_update_send_process_GR(struct eigrp *eigrp, enum GR_type gr_type, struct vty *vty) { - struct listnode *node; struct eigrp_interface *ei; /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* send GR to all neighbors on interface */ eigrp_update_send_interface_GR(ei, gr_type, vty); } diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 31782afdb9..e68b85d801 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -195,12 +195,11 @@ static void eigrp_interface_helper(struct vty *vty, struct eigrp *eigrp, const char *ifname, const char *detail) { struct eigrp_interface *ei; - struct listnode *node; if (!ifname) show_ip_eigrp_interface_header(vty, eigrp); - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { if (!ifname || strcmp(ei->ifp->name, ifname) == 0) { show_ip_eigrp_interface_sub(vty, eigrp, ei); if (detail) @@ -252,12 +251,11 @@ static void eigrp_neighbors_helper(struct vty *vty, struct eigrp *eigrp, const char *ifname, const char *detail) { struct eigrp_interface *ei; - struct listnode *node; struct eigrp_neighbor *nbr; show_ip_eigrp_neighbor_header(vty, eigrp); - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { if (!ifname || strcmp(ei->ifp->name, ifname) == 0) { frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) { if (detail || (nbr->state == EIGRP_NEIGHBOR_UP)) @@ -320,7 +318,6 @@ DEFPY (clear_ip_eigrp_neighbors, { struct eigrp *eigrp; struct eigrp_interface *ei; - struct listnode *node; struct eigrp_neighbor *nbr; /* Check if eigrp process is enabled */ @@ -331,7 +328,7 @@ DEFPY (clear_ip_eigrp_neighbors, } /* iterate over all eigrp interfaces */ - for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) { + frr_each (eigrp_interface_hash, &eigrp->eifs, ei) { /* send Goodbye Hello */ eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL); diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c index 908c10ce4e..8d1af94991 100644 --- a/eigrpd/eigrpd.c +++ b/eigrpd/eigrpd.c @@ -139,7 +139,7 @@ static struct eigrp *eigrp_new(uint16_t as, vrf_id_t vrf_id) eigrp->k_values[5] = EIGRP_K6_DEFAULT; /* init internal data structures */ - eigrp->eiflist = list_new(); + eigrp_interface_hash_init(&eigrp->eifs); eigrp->passive_interface_default = EIGRP_IF_ACTIVE; eigrp->networks = eigrp_topology_new(); @@ -252,9 +252,9 @@ void eigrp_finish_final(struct eigrp *eigrp) { struct eigrp_interface *ei; struct eigrp_neighbor *nbr; - struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei)) { + while (eigrp_interface_hash_count(&eigrp->eifs)) { + ei = eigrp_interface_hash_first(&eigrp->eifs); while (eigrp_nbr_hash_count(&ei->nbr_hash_head)) { nbr = eigrp_nbr_hash_first(&ei->nbr_hash_head); eigrp_nbr_delete(nbr); @@ -266,7 +266,7 @@ void eigrp_finish_final(struct eigrp *eigrp) EVENT_OFF(eigrp->t_read); close(eigrp->fd); - list_delete(&eigrp->eiflist); + eigrp_interface_hash_fini(&eigrp->eifs); list_delete(&eigrp->oi_write_q); eigrp_topology_free(eigrp, eigrp->topology_table);