summaryrefslogtreecommitdiff
path: root/lib/ns.c
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2016-12-05 19:43:38 +0100
committerDavid Lamparter <equinox@opensourcerouting.org>2016-12-05 19:48:38 +0100
commit53dc2b05c76f4f5cd6a72373fb241afdcedb2ee1 (patch)
treed43e2f4f851f368dcc943a9b30e73ff603ea5bc1 /lib/ns.c
parent0577b824e137f143c899a567b1bbeb109841c796 (diff)
parent8793176b5a180bff8e637ce7cba6005f880e8915 (diff)
Merge branch 'stable/2.0'
Conflicts: bgpd/bgp_route.c lib/if.c ripd/rip_interface.c zebra/interface.c zebra/zebra_vty.c
Diffstat (limited to 'lib/ns.c')
-rw-r--r--lib/ns.c309
1 files changed, 28 insertions, 281 deletions
diff --git a/lib/ns.c b/lib/ns.c
index d8db1e45a1..1673ac0a66 100644
--- a/lib/ns.c
+++ b/lib/ns.c
@@ -31,8 +31,6 @@
#include "if.h"
#include "ns.h"
-#include "prefix.h"
-#include "table.h"
#include "log.h"
#include "memory.h"
@@ -41,7 +39,13 @@
DEFINE_MTYPE_STATIC(LIB, NS, "Logical-Router")
DEFINE_MTYPE_STATIC(LIB, NS_NAME, "Logical-Router Name")
-DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map")
+
+static __inline int ns_compare (struct ns *, struct ns *);
+static struct ns *ns_lookup (ns_id_t);
+
+RB_GENERATE (ns_head, ns, entry, ns_compare)
+
+struct ns_head ns_tree = RB_INITIALIZER (&ns_tree);
#ifndef CLONE_NEWNET
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
@@ -91,22 +95,6 @@ static int have_netns(void)
#endif
}
-struct ns
-{
- /* Identifier, same as the vector index */
- ns_id_t ns_id;
- /* Name */
- char *name;
- /* File descriptor */
- int fd;
-
- /* Master list of interfaces belonging to this NS */
- struct list *iflist;
-
- /* User data */
- void *info;
-};
-
/* Holding NS hooks */
struct ns_master
{
@@ -116,44 +104,30 @@ struct ns_master
int (*ns_disable_hook) (ns_id_t, void **);
} ns_master = {0,};
-/* NS table */
-struct route_table *ns_table = NULL;
-
static int ns_is_enabled (struct ns *ns);
static int ns_enable (struct ns *ns);
static void ns_disable (struct ns *ns);
-
-/* Build the table key */
-static void
-ns_build_key (ns_id_t ns_id, struct prefix *p)
+static __inline int
+ns_compare(struct ns *a, struct ns *b)
{
- p->family = AF_INET;
- p->prefixlen = IPV4_MAX_BITLEN;
- p->u.prefix4.s_addr = ns_id;
+ return (a->ns_id - b->ns_id);
}
/* Get a NS. If not found, create one. */
static struct ns *
ns_get (ns_id_t ns_id)
{
- struct prefix p;
- struct route_node *rn;
struct ns *ns;
- ns_build_key (ns_id, &p);
- rn = route_node_get (ns_table, &p);
- if (rn->info)
- {
- ns = (struct ns *)rn->info;
- route_unlock_node (rn); /* get */
- return ns;
- }
+ ns = ns_lookup (ns_id);
+ if (ns)
+ return (ns);
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
ns->ns_id = ns_id;
ns->fd = -1;
- rn->info = ns;
+ RB_INSERT (ns_head, &ns_tree, ns);
/*
* Initialize interfaces.
@@ -188,6 +162,7 @@ ns_delete (struct ns *ns)
*/
//if_terminate (&ns->iflist);
+ RB_REMOVE (ns_head, &ns_tree, ns);
if (ns->name)
XFREE (MTYPE_NS_NAME, ns->name);
@@ -198,18 +173,9 @@ ns_delete (struct ns *ns)
static struct ns *
ns_lookup (ns_id_t ns_id)
{
- struct prefix p;
- struct route_node *rn;
- struct ns *ns = NULL;
-
- ns_build_key (ns_id, &p);
- rn = route_node_lookup (ns_table, &p);
- if (rn)
- {
- ns = (struct ns *)rn->info;
- route_unlock_node (rn); /* lookup */
- }
- return ns;
+ struct ns ns;
+ ns.ns_id = ns_id;
+ return (RB_FIND (ns_head, &ns_tree, &ns));
}
/*
@@ -310,217 +276,6 @@ ns_add_hook (int type, int (*func)(ns_id_t, void **))
}
}
-/* Return the iterator of the first NS. */
-ns_iter_t
-ns_first (void)
-{
- struct route_node *rn;
-
- for (rn = route_top (ns_table); rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* top/next */
- return (ns_iter_t)rn;
- }
- return NS_ITER_INVALID;
-}
-
-/* Return the next NS iterator to the given iterator. */
-ns_iter_t
-ns_next (ns_iter_t iter)
-{
- struct route_node *rn = NULL;
-
- /* Lock it first because route_next() will unlock it. */
- if (iter != NS_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 (ns_iter_t)rn;
- }
- return NS_ITER_INVALID;
-}
-
-/* Return the NS iterator of the given NS ID. If it does not exist,
- * the iterator of the next existing NS is returned. */
-ns_iter_t
-ns_iterator (ns_id_t ns_id)
-{
- struct prefix p;
- struct route_node *rn;
-
- ns_build_key (ns_id, &p);
- rn = route_node_get (ns_table, &p);
- if (rn->info)
- {
- /* OK, the NS exists. */
- route_unlock_node (rn); /* get */
- return (ns_iter_t)rn;
- }
-
- /* Find the next NS. */
- for (rn = route_next (rn); rn; rn = route_next (rn))
- if (rn->info)
- {
- route_unlock_node (rn); /* next */
- return (ns_iter_t)rn;
- }
-
- return NS_ITER_INVALID;
-}
-
-/* Obtain the NS ID from the given NS iterator. */
-ns_id_t
-ns_iter2id (ns_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct ns *)rn->info)->ns_id : NS_DEFAULT;
-}
-
-/* Obtain the data pointer from the given NS iterator. */
-void *
-ns_iter2info (ns_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct ns *)rn->info)->info : NULL;
-}
-
-/* Obtain the interface list from the given NS iterator. */
-struct list *
-ns_iter2iflist (ns_iter_t iter)
-{
- struct route_node *rn = (struct route_node *) iter;
- return (rn && rn->info) ? ((struct ns *)rn->info)->iflist : NULL;
-}
-
-/* Get the data pointer of the specified NS. If not found, create one. */
-void *
-ns_info_get (ns_id_t ns_id)
-{
- struct ns *ns = ns_get (ns_id);
- return ns->info;
-}
-
-/* Look up the data pointer of the specified NS. */
-void *
-ns_info_lookup (ns_id_t ns_id)
-{
- struct ns *ns = ns_lookup (ns_id);
- return ns ? ns->info : NULL;
-}
-
-/* Look up the interface list in a NS. */
-struct list *
-ns_iflist (ns_id_t ns_id)
-{
- struct ns * ns = ns_lookup (ns_id);
- return ns ? ns->iflist : NULL;
-}
-
-/* Get the interface list of the specified NS. Create one if not find. */
-struct list *
-ns_iflist_get (ns_id_t ns_id)
-{
- struct ns * ns = ns_get (ns_id);
- return ns->iflist;
-}
-
-/*
- * NS bit-map
- */
-
-#define NS_BITMAP_NUM_OF_GROUPS 8
-#define NS_BITMAP_NUM_OF_BITS_IN_GROUP \
- (UINT16_MAX / NS_BITMAP_NUM_OF_GROUPS)
-#define NS_BITMAP_NUM_OF_BYTES_IN_GROUP \
- (NS_BITMAP_NUM_OF_BITS_IN_GROUP / CHAR_BIT + 1) /* +1 for ensure */
-
-#define NS_BITMAP_GROUP(_id) \
- ((_id) / NS_BITMAP_NUM_OF_BITS_IN_GROUP)
-#define NS_BITMAP_BIT_OFFSET(_id) \
- ((_id) % NS_BITMAP_NUM_OF_BITS_IN_GROUP)
-
-#define NS_BITMAP_INDEX_IN_GROUP(_bit_offset) \
- ((_bit_offset) / CHAR_BIT)
-#define NS_BITMAP_FLAG(_bit_offset) \
- (((u_char)1) << ((_bit_offset) % CHAR_BIT))
-
-struct ns_bitmap
-{
- u_char *groups[NS_BITMAP_NUM_OF_GROUPS];
-};
-
-ns_bitmap_t
-ns_bitmap_init (void)
-{
- return (ns_bitmap_t) XCALLOC (MTYPE_NS_BITMAP, sizeof (struct ns_bitmap));
-}
-
-void
-ns_bitmap_free (ns_bitmap_t bmap)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- int i;
-
- if (bmap == NS_BITMAP_NULL)
- return;
-
- for (i = 0; i < NS_BITMAP_NUM_OF_GROUPS; i++)
- if (bm->groups[i])
- XFREE (MTYPE_NS_BITMAP, bm->groups[i]);
-
- XFREE (MTYPE_NS_BITMAP, bm);
-}
-
-void
-ns_bitmap_set (ns_bitmap_t bmap, ns_id_t ns_id)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- u_char group = NS_BITMAP_GROUP (ns_id);
- u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
-
- if (bmap == NS_BITMAP_NULL)
- return;
-
- if (bm->groups[group] == NULL)
- bm->groups[group] = XCALLOC (MTYPE_NS_BITMAP,
- NS_BITMAP_NUM_OF_BYTES_IN_GROUP);
-
- SET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
- NS_BITMAP_FLAG (offset));
-}
-
-void
-ns_bitmap_unset (ns_bitmap_t bmap, ns_id_t ns_id)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- u_char group = NS_BITMAP_GROUP (ns_id);
- u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
-
- if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL)
- return;
-
- UNSET_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
- NS_BITMAP_FLAG (offset));
-}
-
-int
-ns_bitmap_check (ns_bitmap_t bmap, ns_id_t ns_id)
-{
- struct ns_bitmap *bm = (struct ns_bitmap *) bmap;
- u_char group = NS_BITMAP_GROUP (ns_id);
- u_char offset = NS_BITMAP_BIT_OFFSET (ns_id);
-
- if (bmap == NS_BITMAP_NULL || bm->groups[group] == NULL)
- return 0;
-
- return CHECK_FLAG (bm->groups[group][NS_BITMAP_INDEX_IN_GROUP (offset)],
- NS_BITMAP_FLAG (offset)) ? 1 : 0;
-}
-
/*
* NS realization with NETNS
*/
@@ -645,17 +400,17 @@ static struct cmd_node ns_node =
static int
ns_config_write (struct vty *vty)
{
- struct route_node *rn;
struct ns *ns;
int write = 0;
- for (rn = route_top (ns_table); rn; rn = route_next (rn))
- if ((ns = rn->info) != NULL &&
- ns->ns_id != NS_DEFAULT && ns->name)
- {
- vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE);
- write++;
- }
+ RB_FOREACH (ns, ns_head, &ns_tree) {
+ if (ns->ns_id == NS_DEFAULT || ns->name == NULL)
+ continue;
+
+ vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name,
+ VTY_NEWLINE);
+ write = 1;
+ }
return write;
}
@@ -666,9 +421,6 @@ ns_init (void)
{
struct ns *default_ns;
- /* Allocate NS table. */
- ns_table = route_table_init ();
-
/* The default NS always exists. */
default_ns = ns_get (NS_DEFAULT);
if (!default_ns)
@@ -700,15 +452,10 @@ ns_init (void)
void
ns_terminate (void)
{
- struct route_node *rn;
struct ns *ns;
- for (rn = route_top (ns_table); rn; rn = route_next (rn))
- if ((ns = rn->info) != NULL)
- ns_delete (ns);
-
- route_table_finish (ns_table);
- ns_table = NULL;
+ while ((ns = RB_ROOT (&ns_tree)) != NULL)
+ ns_delete (ns);
}
/* Create a socket for the NS. */