mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-28 16:06:20 +00:00
lib: convert namespace code to use red-black trees
We definitely need to stop abusing the route table data structure when it's not necessary. Convert the namespace code to use red-black trees instead. This greatly improves code readability. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
51bdc5f85c
commit
c7fdd84f36
81
lib/ns.c
81
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"
|
||||
|
||||
@ -43,6 +41,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) */
|
||||
#endif
|
||||
@ -100,44 +105,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.
|
||||
@ -172,6 +163,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);
|
||||
|
||||
@ -182,18 +174,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));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -414,17 +397,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;
|
||||
}
|
||||
@ -435,9 +418,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)
|
||||
@ -469,15 +449,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. */
|
||||
|
9
lib/ns.h
9
lib/ns.h
@ -23,6 +23,7 @@
|
||||
#ifndef _ZEBRA_NS_H
|
||||
#define _ZEBRA_NS_H
|
||||
|
||||
#include "openbsd-tree.h"
|
||||
#include "linklist.h"
|
||||
|
||||
typedef u_int16_t ns_id_t;
|
||||
@ -35,10 +36,14 @@ typedef u_int16_t ns_id_t;
|
||||
|
||||
struct ns
|
||||
{
|
||||
RB_ENTRY(ns) entry;
|
||||
|
||||
/* Identifier, same as the vector index */
|
||||
ns_id_t ns_id;
|
||||
|
||||
/* Name */
|
||||
char *name;
|
||||
|
||||
/* File descriptor */
|
||||
int fd;
|
||||
|
||||
@ -48,6 +53,10 @@ struct ns
|
||||
/* User data */
|
||||
void *info;
|
||||
};
|
||||
RB_HEAD (ns_head, ns);
|
||||
RB_PROTOTYPE (ns_head, ns, entry, ns_compare)
|
||||
|
||||
extern struct ns_head ns_tree;
|
||||
|
||||
/*
|
||||
* NS hooks
|
||||
|
Loading…
Reference in New Issue
Block a user