]> git.puffer.fish Git - mirror/frr.git/commitdiff
eigrpd: Convert the eiflist to a typesafe hash
authorDonald Sharp <sharpd@nvidia.com>
Mon, 24 Mar 2025 01:16:56 +0000 (21:16 -0400)
committerDonald Sharp <sharpd@nvidia.com>
Mon, 24 Mar 2025 15:36:13 +0000 (11:36 -0400)
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 <sharpd@nvidia.com>
14 files changed:
eigrpd/eigrp_filter.c
eigrpd/eigrp_hello.c
eigrpd/eigrp_interface.c
eigrpd/eigrp_interface.h
eigrpd/eigrp_neighbor.c
eigrpd/eigrp_network.c
eigrpd/eigrp_northbound.c
eigrpd/eigrp_packet.c
eigrpd/eigrp_query.c
eigrpd/eigrp_routemap.c
eigrpd/eigrp_structs.h
eigrpd/eigrp_update.c
eigrpd/eigrp_vty.c
eigrpd/eigrpd.c

index eceef6b8a7939302809e32bc951ef67af27f1106..d6f2ddf7f4930181ba45336963ac0f3f6eb7bba2 100644 (file)
@@ -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;
index bd2b8ccbbdafc0174fda633500b49c179546c69d..fe80651b9bf601b9f5a2fba813b7ead0f3ea3078 100644 (file)
@@ -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(
index 05012e63b2363a1c53b9ee5d998e6b58a077604f..2e3beacae785d6a35422403e0619de9970f52694 100644 (file)
 
 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;
index 76f9c1bcb61361aaf1f8b4cc4187042ae27d5104..effafeaea5892f33925afaeca0ce6b56950fac8c 100644 (file)
@@ -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_ */
index 578d1671c833f6bf021f6908b727e8c044c15879..ac3cbd04b23e80d1e537bd2080e5e5f154a84c8e 100644 (file)
@@ -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;
index 5ca5a18a974e40e35a033f396a864fd482b43946..0fdb1c27cbe7db690e2013e7e1738856adb46fef 100644 (file)
@@ -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)) {
index 4aeb635c05c3d53487d3dd55586110758e27e418..90af47e9e2524b4cd506744aa100ad57c7d7555d 100644 (file)
@@ -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;
 
index 963d229bc1050312f7e3ddc4d9ad4b2d2e7de0a9..189d9330cf851f9c4babf337ad9f4705c0d099d7 100644 (file)
@@ -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",
index aaa8f9478c53283265cb07b3f059085ba05d3d9c..d4f00fb139465c34b4f9a603452b8c99ead11e26 100644 (file)
@@ -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++;
        }
index 420cb6cb414c2ac95f0fc49b194f8596d1437792..605a1ae4b8c0e1d9e2b26256d765d80acdcb1f46 100644 (file)
@@ -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;
index 4acb8b10b514cca568ab700b1ef213ca0b647ca8..c277dcbf5e20f63b25593b2cf5c94baab0067ac3 100644 (file)
@@ -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 */
index bb61a3e6c1252e398ff152730f2fc8e8db83d591..6511db2feb2b1a9014ee80f3bfc9e3d73d786fd7 100644 (file)
@@ -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);
        }
index 31782afdb96305c88d6807521d85874c91a796f1..e68b85d801190c600d09f72a0da250579c1b97fc 100644 (file)
@@ -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);
 
index 908c10ce4edada6cd701af7af0ebc8221a1edfac..8d1af9499103f57cf1b9a458c0c250e1721f0901 100644 (file)
@@ -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);