diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2023-11-22 19:05:41 +0100 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2023-11-22 23:00:30 +0100 |
commit | 8b23c0b0bd3470babe8702f54a47bb223f471b14 (patch) | |
tree | 07e92fbef506de160930385036fd69901b59e6a6 /lib | |
parent | Merge pull request #14830 from fdumontet6WIND/snmpv2 (diff) | |
download | frr-8b23c0b0bd3470babe8702f54a47bb223f471b14.tar.xz frr-8b23c0b0bd3470babe8702f54a47bb223f471b14.zip |
*: convert `struct interface->connected` to DLIST
Replace `struct list *` with `DLIST(if_connected, ...)`.
NB: while converting this, I found multiple places using connected
prefixes assuming they were IPv4 without checking:
- vrrpd/vrrp.c: vrrp_socket()
- zebra/irdp_interface.c: irdp_get_prefix(), irdp_if_start(),
irdp_advert_off()
(these fixes are really hard to split off into separate commits as that
would require going back and reapplying the change but with the old list
handling)
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/bfd.c | 4 | ||||
-rw-r--r-- | lib/if.c | 51 | ||||
-rw-r--r-- | lib/if.h | 11 |
3 files changed, 26 insertions, 40 deletions
@@ -1282,7 +1282,6 @@ static bool bfd_source_cache_update(struct bfd_source_cache *source, const struct zapi_nexthop *nh = &route->nexthops[nh_index]; const struct interface *interface; const struct connected *connected; - const struct listnode *node; interface = if_lookup_by_index(nh->ifindex, nh->vrf_id); if (interface == NULL) { @@ -1291,8 +1290,7 @@ static bool bfd_source_cache_update(struct bfd_source_cache *source, continue; } - for (ALL_LIST_ELEMENTS_RO(interface->connected, node, - connected)) { + frr_each (if_connected_const, interface->connected, connected) { if (source->address.family != connected->address->family) continue; @@ -164,8 +164,7 @@ static struct interface *if_new(struct vrf *vrf) ifp->vrf = vrf; - ifp->connected = list_new(); - ifp->connected->del = ifp_connected_free; + if_connected_init(ifp->connected); ifp->nbr_connected = list_new(); ifp->nbr_connected->del = (void (*)(void *))nbr_connected_free; @@ -243,11 +242,14 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id) /* Delete interface structure. */ void if_delete_retain(struct interface *ifp) { + struct connected *ifc; + hook_call(if_del, ifp); QOBJ_UNREG(ifp); /* Free connected address list */ - list_delete_all_node(ifp->connected); + while ((ifc = if_connected_pop(ifp->connected))) + ifp_connected_free(ifc); /* Free connected nbr address list */ list_delete_all_node(ifp->nbr_connected); @@ -265,7 +267,7 @@ void if_delete(struct interface **ifp) if_delete_retain(ptr); - list_delete(&ptr->connected); + if_connected_fini(ptr->connected); list_delete(&ptr->nbr_connected); if_link_params_free(ptr); @@ -427,7 +429,6 @@ struct interface *if_lookup_address_local(const void *src, int family, vrf_id_t vrf_id) { struct vrf *vrf = vrf_lookup_by_id(vrf_id); - struct listnode *cnode; struct interface *ifp, *best_down = NULL; struct prefix *p; struct connected *c; @@ -436,7 +437,7 @@ struct interface *if_lookup_address_local(const void *src, int family, return NULL; FOR_ALL_INTERFACES (vrf, ifp) { - for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { + frr_each (if_connected, ifp->connected, c) { p = c->address; if (!p || p->family != family) @@ -468,7 +469,6 @@ struct connected *if_lookup_address(const void *matchaddr, int family, struct vrf *vrf = vrf_lookup_by_id(vrf_id); struct prefix addr; int bestlen = 0; - struct listnode *cnode; struct interface *ifp; struct connected *c; struct connected *match; @@ -487,7 +487,7 @@ struct connected *if_lookup_address(const void *matchaddr, int family, match = NULL; FOR_ALL_INTERFACES (vrf, ifp) { - for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { + frr_each (if_connected, ifp->connected, c) { if (c->address && (c->address->family == AF_INET) && prefix_match(CONNECTED_PREFIX(c), &addr) && (c->address->prefixlen > bestlen)) { @@ -503,12 +503,11 @@ struct connected *if_lookup_address(const void *matchaddr, int family, struct interface *if_lookup_prefix(const struct prefix *prefix, vrf_id_t vrf_id) { struct vrf *vrf = vrf_lookup_by_id(vrf_id); - struct listnode *cnode; struct interface *ifp; struct connected *c; FOR_ALL_INTERFACES (vrf, ifp) { - for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { + frr_each (if_connected, ifp->connected, c) { if (prefix_cmp(c->address, prefix) == 0) { return ifp; } @@ -775,10 +774,9 @@ const char *if_flag_dump(unsigned long flag) /* For debugging */ static void if_dump(const struct interface *ifp) { - struct listnode *node; - struct connected *c __attribute__((unused)); + const struct connected *c; - for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, c)) + frr_each (if_connected_const, ifp->connected, c) zlog_info( "Interface %s vrf %s(%u) index %d metric %d mtu %d mtu6 %d %s", ifp->name, ifp->vrf->name, ifp->vrf->vrf_id, @@ -905,11 +903,10 @@ static int connected_same_prefix(const struct prefix *p1, /* count the number of connected addresses that are in the given family */ unsigned int connected_count_by_family(struct interface *ifp, int family) { - struct listnode *cnode; struct connected *connected; unsigned int cnt = 0; - for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, connected)) + frr_each (if_connected, ifp->connected, connected) if (connected->address->family == family) cnt++; @@ -919,14 +916,9 @@ unsigned int connected_count_by_family(struct interface *ifp, int family) struct connected *connected_lookup_prefix_exact(struct interface *ifp, const struct prefix *p) { - struct listnode *node; - struct listnode *next; struct connected *ifc; - for (node = listhead(ifp->connected); node; node = next) { - ifc = listgetdata(node); - next = node->next; - + frr_each (if_connected, ifp->connected, ifc) { if (connected_same_prefix(ifc->address, p)) return ifc; } @@ -936,17 +928,12 @@ struct connected *connected_lookup_prefix_exact(struct interface *ifp, struct connected *connected_delete_by_prefix(struct interface *ifp, struct prefix *p) { - struct listnode *node; - struct listnode *next; struct connected *ifc; /* In case of same prefix come, replace it with new one. */ - for (node = listhead(ifp->connected); node; node = next) { - ifc = listgetdata(node); - next = node->next; - + frr_each_safe (if_connected, ifp->connected, ifc) { if (connected_same_prefix(ifc->address, p)) { - listnode_delete(ifp->connected, ifc); + if_connected_del(ifp->connected, ifc); return ifc; } } @@ -958,13 +945,12 @@ struct connected *connected_delete_by_prefix(struct interface *ifp, struct connected *connected_lookup_prefix(struct interface *ifp, const struct prefix *addr) { - struct listnode *cnode; struct connected *c; struct connected *match; match = NULL; - for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) { + frr_each (if_connected, ifp->connected, c) { if (c->address && (c->address->family == addr->family) && prefix_match(CONNECTED_PREFIX(c), addr) && (!match @@ -995,16 +981,15 @@ struct connected *connected_add_by_prefix(struct interface *ifp, } /* Add connected address to the interface. */ - listnode_add(ifp->connected, ifc); + if_connected_add_tail(ifp->connected, ifc); return ifc; } struct connected *connected_get_linklocal(struct interface *ifp) { - struct listnode *n; struct connected *c = NULL; - for (ALL_LIST_ELEMENTS_RO(ifp->connected, n, c)) { + frr_each (if_connected, ifp->connected, c) { if (c->address->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6)) break; @@ -204,6 +204,8 @@ struct if_link_params { #define INTERFACE_LINK_PARAMS_SIZE sizeof(struct if_link_params) #define HAS_LINK_PARAMS(ifp) ((ifp)->link_params != NULL) +PREDECL_DLIST(if_connected); + /* Interface structure */ struct interface { RB_ENTRY(interface) name_entry, index_entry; @@ -278,7 +280,7 @@ struct interface { void *distribute_out; /* Connected address list. */ - struct list *connected; + struct if_connected_head connected[1]; /* Neighbor connected address list. */ struct list *nbr_connected; @@ -373,9 +375,6 @@ DECLARE_QOBJ_TYPE(interface); if (vrf) \ RB_FOREACH (ifp, if_name_head, &vrf->ifaces_by_name) -#define FOR_ALL_INTERFACES_ADDRESSES(ifp, connected, node) \ - for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) - /* called from the library code whenever interfaces are created/deleted * note: interfaces may not be fully realized at that point; also they * may not exist in the system (ifindex = IFINDEX_INTERNAL) @@ -410,6 +409,8 @@ DECLARE_KOOH(if_down, (struct interface *ifp), (ifp)); /* Connected address structure. */ struct connected { + struct if_connected_item item; + /* Attached interface. */ struct interface *ifp; @@ -459,6 +460,8 @@ struct connected { uint32_t metric; }; +DECLARE_DLIST(if_connected, struct connected, item); + /* Nbr Connected address structure. */ struct nbr_connected { /* Attached interface. */ |