diff options
Diffstat (limited to 'lib/if.c')
| -rw-r--r-- | lib/if.c | 72 |
1 files changed, 49 insertions, 23 deletions
@@ -140,6 +140,13 @@ static int if_cmp_index_func(const struct interface *ifp1, return ifp1->ifindex - ifp2->ifindex; } +static void ifp_connected_free(void *arg) +{ + struct connected *c = arg; + + connected_free(&c); +} + /* Create new interface structure. */ static struct interface *if_new(vrf_id_t vrf_id) { @@ -153,7 +160,7 @@ static struct interface *if_new(vrf_id_t vrf_id) ifp->vrf_id = vrf_id; ifp->connected = list_new(); - ifp->connected->del = (void (*)(void *))connected_free; + ifp->connected->del = ifp_connected_free; ifp->nbr_connected = list_new(); ifp->nbr_connected->del = (void (*)(void *))nbr_connected_free; @@ -178,7 +185,7 @@ void if_destroy_via_zapi(struct interface *ifp) if_set_index(ifp, IFINDEX_INTERNAL); if (!ifp->configured) - if_delete(ifp); + if_delete(&ifp); } void if_up_via_zapi(struct interface *ifp) @@ -276,27 +283,29 @@ void if_delete_retain(struct interface *ifp) } /* Delete and free interface structure. */ -void if_delete(struct interface *ifp) +void if_delete(struct interface **ifp) { + struct interface *ptr = *ifp; struct vrf *vrf; - vrf = vrf_lookup_by_id(ifp->vrf_id); + vrf = vrf_lookup_by_id(ptr->vrf_id); assert(vrf); - IFNAME_RB_REMOVE(vrf, ifp); - if (ifp->ifindex != IFINDEX_INTERNAL) - IFINDEX_RB_REMOVE(vrf, ifp); + IFNAME_RB_REMOVE(vrf, ptr); + if (ptr->ifindex != IFINDEX_INTERNAL) + IFINDEX_RB_REMOVE(vrf, ptr); - if_delete_retain(ifp); + if_delete_retain(ptr); - list_delete(&ifp->connected); - list_delete(&ifp->nbr_connected); + list_delete(&ptr->connected); + list_delete(&ptr->nbr_connected); - if_link_params_free(ifp); + if_link_params_free(ptr); - XFREE(MTYPE_TMP, ifp->desc); + XFREE(MTYPE_TMP, ptr->desc); - XFREE(MTYPE_IF, ifp); + XFREE(MTYPE_IF, ptr); + *ifp = NULL; } /* Used only internally to check within VRF only */ @@ -866,24 +875,27 @@ struct nbr_connected *nbr_connected_new(void) } /* Free connected structure. */ -void connected_free(struct connected *connected) +void connected_free(struct connected **connected) { - if (connected->address) - prefix_free(connected->address); + struct connected *ptr = *connected; - if (connected->destination) - prefix_free(connected->destination); + if (ptr->address) + prefix_free(&ptr->address); - XFREE(MTYPE_CONNECTED_LABEL, connected->label); + if (ptr->destination) + prefix_free(&ptr->destination); - XFREE(MTYPE_CONNECTED, connected); + XFREE(MTYPE_CONNECTED_LABEL, ptr->label); + + XFREE(MTYPE_CONNECTED, ptr); + *connected = NULL; } /* Free nbr connected structure. */ void nbr_connected_free(struct nbr_connected *connected) { if (connected->address) - prefix_free(connected->address); + prefix_free(&connected->address); XFREE(MTYPE_NBR_CONNECTED, connected); } @@ -959,6 +971,20 @@ static int connected_same_prefix(struct prefix *p1, struct prefix *p2) return 0; } +/* 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)) + if (connected->address->family == family) + cnt++; + + return cnt; +} + struct connected *connected_lookup_prefix_exact(struct interface *ifp, struct prefix *p) { @@ -1145,7 +1171,7 @@ void if_terminate(struct vrf *vrf) ifp->node->info = NULL; route_unlock_node(ifp->node); } - if_delete(ifp); + if_delete(&ifp); } } @@ -1527,7 +1553,7 @@ static int lib_interface_destroy(enum nb_event event, ifp = nb_running_unset_entry(dnode); ifp->configured = false; - if_delete(ifp); + if_delete(&ifp); break; } |
