mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-30 17:11:42 +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 "if.h"
|
||||||
#include "ns.h"
|
#include "ns.h"
|
||||||
#include "prefix.h"
|
|
||||||
#include "table.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.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_NAME, "Logical-Router Name")
|
||||||
DEFINE_MTYPE_STATIC(LIB, NS_BITMAP, "Logical-Router bit-map")
|
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
|
#ifndef CLONE_NEWNET
|
||||||
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
|
#define CLONE_NEWNET 0x40000000 /* New network namespace (lo, device, names sockets, etc) */
|
||||||
#endif
|
#endif
|
||||||
@ -100,44 +105,30 @@ struct ns_master
|
|||||||
int (*ns_disable_hook) (ns_id_t, void **);
|
int (*ns_disable_hook) (ns_id_t, void **);
|
||||||
} ns_master = {0,};
|
} ns_master = {0,};
|
||||||
|
|
||||||
/* NS table */
|
|
||||||
struct route_table *ns_table = NULL;
|
|
||||||
|
|
||||||
static int ns_is_enabled (struct ns *ns);
|
static int ns_is_enabled (struct ns *ns);
|
||||||
static int ns_enable (struct ns *ns);
|
static int ns_enable (struct ns *ns);
|
||||||
static void ns_disable (struct ns *ns);
|
static void ns_disable (struct ns *ns);
|
||||||
|
|
||||||
|
static __inline int
|
||||||
/* Build the table key */
|
ns_compare(struct ns *a, struct ns *b)
|
||||||
static void
|
|
||||||
ns_build_key (ns_id_t ns_id, struct prefix *p)
|
|
||||||
{
|
{
|
||||||
p->family = AF_INET;
|
return (a->ns_id - b->ns_id);
|
||||||
p->prefixlen = IPV4_MAX_BITLEN;
|
|
||||||
p->u.prefix4.s_addr = ns_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a NS. If not found, create one. */
|
/* Get a NS. If not found, create one. */
|
||||||
static struct ns *
|
static struct ns *
|
||||||
ns_get (ns_id_t ns_id)
|
ns_get (ns_id_t ns_id)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
|
||||||
struct route_node *rn;
|
|
||||||
struct ns *ns;
|
struct ns *ns;
|
||||||
|
|
||||||
ns_build_key (ns_id, &p);
|
ns = ns_lookup (ns_id);
|
||||||
rn = route_node_get (ns_table, &p);
|
if (ns)
|
||||||
if (rn->info)
|
return (ns);
|
||||||
{
|
|
||||||
ns = (struct ns *)rn->info;
|
|
||||||
route_unlock_node (rn); /* get */
|
|
||||||
return ns;
|
|
||||||
}
|
|
||||||
|
|
||||||
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
|
ns = XCALLOC (MTYPE_NS, sizeof (struct ns));
|
||||||
ns->ns_id = ns_id;
|
ns->ns_id = ns_id;
|
||||||
ns->fd = -1;
|
ns->fd = -1;
|
||||||
rn->info = ns;
|
RB_INSERT (ns_head, &ns_tree, ns);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize interfaces.
|
* Initialize interfaces.
|
||||||
@ -172,6 +163,7 @@ ns_delete (struct ns *ns)
|
|||||||
*/
|
*/
|
||||||
//if_terminate (&ns->iflist);
|
//if_terminate (&ns->iflist);
|
||||||
|
|
||||||
|
RB_REMOVE (ns_head, &ns_tree, ns);
|
||||||
if (ns->name)
|
if (ns->name)
|
||||||
XFREE (MTYPE_NS_NAME, ns->name);
|
XFREE (MTYPE_NS_NAME, ns->name);
|
||||||
|
|
||||||
@ -182,18 +174,9 @@ ns_delete (struct ns *ns)
|
|||||||
static struct ns *
|
static struct ns *
|
||||||
ns_lookup (ns_id_t ns_id)
|
ns_lookup (ns_id_t ns_id)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct ns ns;
|
||||||
struct route_node *rn;
|
ns.ns_id = ns_id;
|
||||||
struct ns *ns = NULL;
|
return (RB_FIND (ns_head, &ns_tree, &ns));
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -414,17 +397,17 @@ static struct cmd_node ns_node =
|
|||||||
static int
|
static int
|
||||||
ns_config_write (struct vty *vty)
|
ns_config_write (struct vty *vty)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
|
||||||
struct ns *ns;
|
struct ns *ns;
|
||||||
int write = 0;
|
int write = 0;
|
||||||
|
|
||||||
for (rn = route_top (ns_table); rn; rn = route_next (rn))
|
RB_FOREACH (ns, ns_head, &ns_tree) {
|
||||||
if ((ns = rn->info) != NULL &&
|
if (ns->ns_id == NS_DEFAULT || ns->name == NULL)
|
||||||
ns->ns_id != NS_DEFAULT && ns->name)
|
continue;
|
||||||
{
|
|
||||||
vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name, VTY_NEWLINE);
|
vty_out (vty, "logical-router %u netns %s%s", ns->ns_id, ns->name,
|
||||||
write++;
|
VTY_NEWLINE);
|
||||||
}
|
write = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return write;
|
return write;
|
||||||
}
|
}
|
||||||
@ -435,9 +418,6 @@ ns_init (void)
|
|||||||
{
|
{
|
||||||
struct ns *default_ns;
|
struct ns *default_ns;
|
||||||
|
|
||||||
/* Allocate NS table. */
|
|
||||||
ns_table = route_table_init ();
|
|
||||||
|
|
||||||
/* The default NS always exists. */
|
/* The default NS always exists. */
|
||||||
default_ns = ns_get (NS_DEFAULT);
|
default_ns = ns_get (NS_DEFAULT);
|
||||||
if (!default_ns)
|
if (!default_ns)
|
||||||
@ -469,15 +449,10 @@ ns_init (void)
|
|||||||
void
|
void
|
||||||
ns_terminate (void)
|
ns_terminate (void)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
|
||||||
struct ns *ns;
|
struct ns *ns;
|
||||||
|
|
||||||
for (rn = route_top (ns_table); rn; rn = route_next (rn))
|
while ((ns = RB_ROOT (&ns_tree)) != NULL)
|
||||||
if ((ns = rn->info) != NULL)
|
ns_delete (ns);
|
||||||
ns_delete (ns);
|
|
||||||
|
|
||||||
route_table_finish (ns_table);
|
|
||||||
ns_table = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a socket for the NS. */
|
/* Create a socket for the NS. */
|
||||||
|
9
lib/ns.h
9
lib/ns.h
@ -23,6 +23,7 @@
|
|||||||
#ifndef _ZEBRA_NS_H
|
#ifndef _ZEBRA_NS_H
|
||||||
#define _ZEBRA_NS_H
|
#define _ZEBRA_NS_H
|
||||||
|
|
||||||
|
#include "openbsd-tree.h"
|
||||||
#include "linklist.h"
|
#include "linklist.h"
|
||||||
|
|
||||||
typedef u_int16_t ns_id_t;
|
typedef u_int16_t ns_id_t;
|
||||||
@ -35,10 +36,14 @@ typedef u_int16_t ns_id_t;
|
|||||||
|
|
||||||
struct ns
|
struct ns
|
||||||
{
|
{
|
||||||
|
RB_ENTRY(ns) entry;
|
||||||
|
|
||||||
/* Identifier, same as the vector index */
|
/* Identifier, same as the vector index */
|
||||||
ns_id_t ns_id;
|
ns_id_t ns_id;
|
||||||
|
|
||||||
/* Name */
|
/* Name */
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
/* File descriptor */
|
/* File descriptor */
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -48,6 +53,10 @@ struct ns
|
|||||||
/* User data */
|
/* User data */
|
||||||
void *info;
|
void *info;
|
||||||
};
|
};
|
||||||
|
RB_HEAD (ns_head, ns);
|
||||||
|
RB_PROTOTYPE (ns_head, ns, entry, ns_compare)
|
||||||
|
|
||||||
|
extern struct ns_head ns_tree;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NS hooks
|
* NS hooks
|
||||||
|
Loading…
Reference in New Issue
Block a user