summaryrefslogtreecommitdiff
path: root/lib/if.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/if.c')
-rw-r--r--lib/if.c72
1 files changed, 49 insertions, 23 deletions
diff --git a/lib/if.c b/lib/if.c
index 594961d763..9d0f13ecbd 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -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;
}