summaryrefslogtreecommitdiff
path: root/lib/vrf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vrf.c')
-rw-r--r--lib/vrf.c199
1 files changed, 30 insertions, 169 deletions
diff --git a/lib/vrf.c b/lib/vrf.c
index 13884aba62..79885ff3e3 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -35,6 +35,12 @@ DEFINE_MTYPE_STATIC(LIB, VRF_BITMAP, "VRF bit-map")
DEFINE_QOBJ_TYPE(vrf)
+static __inline int vrf_id_compare (struct vrf *, struct vrf *);
+
+RB_GENERATE (vrf_id_head, vrf, id_entry, vrf_id_compare)
+
+struct vrf_id_head vrfs_by_id = RB_INITIALIZER (&vrfs_by_id);
+
/*
* Turn on/off debug code
* for vrf.
@@ -50,9 +56,6 @@ struct vrf_master
int (*vrf_disable_hook) (vrf_id_t, const char *, void **);
} vrf_master = {0,};
-/* VRF table */
-struct route_table *vrf_table = NULL;
-
/* VRF is part of a list too to store it before its actually active */
struct list *vrf_list;
@@ -75,13 +78,10 @@ vrf_list_lookup_by_name (const char *name)
return NULL;
}
-/* Build the table key */
-static void
-vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
+static __inline int
+vrf_id_compare (struct vrf *a, struct vrf *b)
{
- p->family = AF_INET;
- p->prefixlen = IPV4_MAX_BITLEN;
- p->u.prefix4.s_addr = vrf_id;
+ return (a->vrf_id - b->vrf_id);
}
/* Get a VRF. If not found, create one.
@@ -94,9 +94,7 @@ vrf_build_key (vrf_id_t vrf_id, struct prefix *p)
struct vrf *
vrf_get (vrf_id_t vrf_id, const char *name)
{
- struct prefix p;
- struct route_node *rn = NULL;
- struct vrf *vrf = NULL;
+ struct vrf *vrf;
if (debug_vrf)
zlog_debug ("VRF_GET: %s(%d)", name, vrf_id);
@@ -156,17 +154,8 @@ vrf_get (vrf_id_t vrf_id, const char *name)
if (vrf->vrf_id == vrf_id)
return vrf;
- /*
- * Now we have a situation where we've had a
- * vrf created, but not yet created the vrf_id route
- * node, let's do so and match the code up.
- */
- vrf_build_key (vrf_id, &p);
- rn = route_node_get (vrf_table, &p);
-
- rn->info = vrf;
- vrf->node = rn;
vrf->vrf_id = vrf_id;
+ RB_INSERT (vrf_id_head, &vrfs_by_id, vrf);
if (vrf_master.vrf_new_hook)
(*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info);
@@ -182,12 +171,9 @@ vrf_get (vrf_id_t vrf_id, const char *name)
* We've already been told about the vrf_id
* or we haven't.
*/
- vrf_build_key (vrf_id, &p);
- rn = route_node_get (vrf_table, &p);
- if (rn->info)
+ vrf = vrf_lookup (vrf_id);
+ if (vrf)
{
- vrf = rn->info;
- route_unlock_node (rn);
/*
* We know at this point that the vrf->name is not
* right because we would have caught it above.
@@ -209,12 +195,10 @@ vrf_get (vrf_id_t vrf_id, const char *name)
else
{
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
-
- rn->info = vrf;
- vrf->node = rn;
vrf->vrf_id = vrf_id;
strcpy (vrf->name, name);
listnode_add_sort (vrf_list, vrf);
+ RB_INSERT (vrf_id_head, &vrfs_by_id, vrf);
if_init (&vrf->iflist);
QOBJ_REG (vrf, vrf);
if (vrf_master.vrf_new_hook)
@@ -237,23 +221,18 @@ vrf_get (vrf_id_t vrf_id, const char *name)
*/
else if (!name)
{
- vrf_build_key (vrf_id, &p);
- rn = route_node_get (vrf_table, &p);
+ vrf = vrf_lookup (vrf_id);
if (debug_vrf)
- zlog_debug("Vrf found: %p", rn->info);
+ zlog_debug("Vrf found: %p", vrf);
- if (rn->info)
- {
- route_unlock_node (rn);
- return (rn->info);
- }
+ if (vrf)
+ return vrf;
else
{
vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf));
- rn->info = vrf;
- vrf->node = rn;
vrf->vrf_id = vrf_id;
if_init (&vrf->iflist);
+ RB_INSERT (vrf_id_head, &vrfs_by_id, vrf);
QOBJ_REG (vrf, vrf);
if (debug_vrf)
zlog_debug("Vrf Created: %p", vrf);
@@ -284,12 +263,8 @@ vrf_delete (struct vrf *vrf)
QOBJ_UNREG (vrf);
if_terminate (&vrf->iflist);
- if (vrf->node)
- {
- vrf->node->info = NULL;
- route_unlock_node(vrf->node);
- }
-
+ if (vrf->vrf_id != VRF_UNKNOWN)
+ RB_REMOVE (vrf_id_head, &vrfs_by_id, vrf);
listnode_delete (vrf_list, vrf);
XFREE (MTYPE_VRF, vrf);
@@ -299,18 +274,9 @@ vrf_delete (struct vrf *vrf)
struct vrf *
vrf_lookup (vrf_id_t vrf_id)
{
- struct prefix p;
- struct route_node *rn;
- struct vrf *vrf = NULL;
-
- vrf_build_key (vrf_id, &p);
- rn = route_node_lookup (vrf_table, &p);
- if (rn)
- {
- vrf = (struct vrf *)rn->info;
- route_unlock_node (rn); /* lookup */
- }
- return vrf;
+ struct vrf vrf;
+ vrf.vrf_id = vrf_id;
+ return (RB_FIND (vrf_id_head, &vrfs_by_id, &vrf));
}
/*
@@ -401,112 +367,15 @@ vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **))
}
}
-/* Return the iterator of the first VRF. */
-vrf_iter_t
-vrf_first (void)
-{
- struct route_node *rn;
-
- for (rn = route_top (vrf_table); rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* top/next */
- return (vrf_iter_t)rn;
- }
- return VRF_ITER_INVALID;
-}
-
-/* Return the next VRF iterator to the given iterator. */
-vrf_iter_t
-vrf_next (vrf_iter_t iter)
-{
- struct route_node *rn = NULL;
-
- /* Lock it first because route_next() will unlock it. */
- if (iter != VRF_ITER_INVALID)
- rn = route_next (route_lock_node ((struct route_node *)iter));
-
- for (; rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* next */
- return (vrf_iter_t)rn;
- }
- return VRF_ITER_INVALID;
-}
-
-/* Return the VRF iterator of the given VRF ID. If it does not exist,
- * the iterator of the next existing VRF is returned. */
-vrf_iter_t
-vrf_iterator (vrf_id_t vrf_id)
-{
- struct prefix p;
- struct route_node *rn;
-
- vrf_build_key (vrf_id, &p);
- rn = route_node_get (vrf_table, &p);
- if (rn->info)
- {
- /* OK, the VRF exists. */
- route_unlock_node (rn); /* get */
- return (vrf_iter_t)rn;
- }
-
- /* Find the next VRF. */
- for (rn = route_next (rn); rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* next */
- return (vrf_iter_t)rn;
- }
-
- return VRF_ITER_INVALID;
-}
-
-/* Obtain the VRF ID from the given VRF iterator. */
-vrf_id_t
-vrf_iter2id (vrf_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct vrf *)rn->info)->vrf_id : VRF_DEFAULT;
-}
-
-struct vrf *
-vrf_iter2vrf (vrf_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? (struct vrf *)rn->info : NULL;
-}
-
-/* Obtain the data pointer from the given VRF iterator. */
-void *
-vrf_iter2info (vrf_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct vrf *)rn->info)->info : NULL;
-}
-
-/* Obtain the interface list from the given VRF iterator. */
-struct list *
-vrf_iter2iflist (vrf_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct vrf *)rn->info)->iflist : NULL;
-}
-
/* Look up a VRF by name. */
struct vrf *
vrf_lookup_by_name (const char *name)
{
- struct vrf *vrf = NULL;
- vrf_iter_t iter;
+ struct vrf *vrf;
- for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
- {
- vrf = vrf_iter2vrf (iter);
- if (vrf && !strcmp(vrf->name, name))
- return vrf;
- }
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
+ if (!strcmp(vrf->name, name))
+ return vrf;
return NULL;
}
@@ -693,9 +562,6 @@ vrf_init (void)
vrf_list = list_new ();
vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func;
- /* Allocate VRF table. */
- vrf_table = route_table_init ();
-
/* The default VRF always exists. */
default_vrf = vrf_get (VRF_DEFAULT, VRF_DEFAULT_NAME);
if (!default_vrf)
@@ -716,18 +582,13 @@ vrf_init (void)
void
vrf_terminate (void)
{
- struct route_node *rn;
struct vrf *vrf;
if (debug_vrf)
zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__);
- for (rn = route_top (vrf_table); rn; rn = route_next (rn))
- if ((vrf = rn->info) != NULL)
- vrf_delete (vrf);
-
- route_table_finish (vrf_table);
- vrf_table = NULL;
+ while ((vrf = RB_ROOT (&vrfs_by_id)) != NULL)
+ vrf_delete (vrf);
}
/* Create a socket for the VRF. */