From 3347430b12ecccc4f03fb29111e9621a6e123b3c Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 7 Dec 2017 18:27:31 +0100 Subject: [PATCH] zebra: add the registration mechanism for netns If vrf backend is netns, then the zebra will create its own zebra_ns context for each new netns discovered. As consequence, a routing table, and other contexts will be created for each new namespace discovered. When it is enabled, a populate process will be done, consisting in learning new interfaces and routes, and addresses from other NETNS. Signed-off-by: Philippe Guibert --- lib/ns.c | 21 ++++++++-------- lib/ns.h | 5 ++-- zebra/zebra_ns.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++- zebra/zebra_ns.h | 3 +++ 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/lib/ns.c b/lib/ns.c index 694a6dab9d..1929104eeb 100644 --- a/lib/ns.c +++ b/lib/ns.c @@ -96,10 +96,10 @@ static int have_netns(void) /* Holding NS hooks */ struct ns_master { - int (*ns_new_hook)(ns_id_t, void **); - int (*ns_delete_hook)(ns_id_t, void **); - int (*ns_enable_hook)(ns_id_t, void **); - int (*ns_disable_hook)(ns_id_t, void **); + int (*ns_new_hook)(struct ns *ns); + int (*ns_delete_hook)(struct ns *ns); + int (*ns_enable_hook)(struct ns *ns); + int (*ns_disable_hook)(struct ns *ns); } ns_master = { 0, }; @@ -129,7 +129,8 @@ static void ns_get_created(struct ns *ns) else zlog_info("NS %s is created.", ns->name); if (ns_master.ns_new_hook) - (*ns_master.ns_new_hook)(ns->ns_id, &ns->info); + (*ns_master.ns_new_hook) (ns); + return; } /* Get a NS. If not found, create one. */ @@ -177,7 +178,7 @@ static void ns_delete(struct ns *ns) ns_disable(ns); if (ns_master.ns_delete_hook) - (*ns_master.ns_delete_hook)(ns->ns_id, &ns->info); + (*ns_master.ns_delete_hook)(ns); /* * I'm not entirely sure if the vrf->iflist @@ -270,7 +271,7 @@ static int ns_enable(struct ns *ns) * then VRF enable event */ if (ns_master.ns_enable_hook) - (*ns_master.ns_enable_hook)(ns->ns_id, &ns->info); + (*ns_master.ns_enable_hook)(ns); if (vrf_on == 1) vrf_enable((struct vrf *)ns->vrf_ctxt); } @@ -289,7 +290,7 @@ static void ns_disable(struct ns *ns) zlog_info("NS %u is to be disabled.", ns->ns_id); if (ns_master.ns_disable_hook) - (*ns_master.ns_disable_hook)(ns->ns_id, &ns->info); + (*ns_master.ns_disable_hook)(ns); if (have_netns()) close(ns->fd); @@ -300,7 +301,7 @@ static void ns_disable(struct ns *ns) /* Add a NS hook. Please add hooks before calling ns_init(). */ -void ns_add_hook(int type, int (*func)(ns_id_t, void **)) +void ns_add_hook(int type, int (*func)(struct ns *)) { switch (type) { case NS_NEW_HOOK: @@ -564,7 +565,7 @@ DEFUN (no_ns_netns, } /* Initialize NS module. */ -void ns_init(void) +void ns_init_zebra(void) { struct ns *default_ns; diff --git a/lib/ns.h b/lib/ns.h index fda062e65f..590e1f2c20 100644 --- a/lib/ns.h +++ b/lib/ns.h @@ -79,13 +79,12 @@ extern struct ns_head ns_tree; * - param 2: the address of the user data pointer (the user data * can be stored in or freed from there) */ -extern void ns_add_hook(int, int (*)(ns_id_t, void **)); +extern void ns_add_hook(int type, int (*)(struct ns *)); /* * NS initializer/destructor */ -/* Please add hooks before calling ns_init(). */ -extern void ns_init(void); +extern void ns_init_zebra(void); extern void ns_terminate(void); /* diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 80847518a7..6ce64b3a33 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -32,6 +32,7 @@ #include "zebra_memory.h" #include "rt.h" #include "zebra_vxlan.h" +#include "debug.h" DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") @@ -59,6 +60,58 @@ struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id) return dzns; } +static struct zebra_ns *zebra_ns_alloc(void) +{ + return XCALLOC(MTYPE_ZEBRA_NS, sizeof(struct zebra_ns)); +} + +static int zebra_ns_new(struct ns *ns) +{ + struct zebra_ns *zns; + + if (IS_ZEBRA_DEBUG_EVENT) + zlog_info("ZNS %s with id %u (created)", ns->name, ns->ns_id); + + zns = zebra_ns_alloc(); + ns->info = zns; + zns->ns = ns; + return 0; +} + +static int zebra_ns_delete(struct ns *ns) +{ + struct zebra_ns *zns = (struct zebra_ns *) ns->info; + + if (IS_ZEBRA_DEBUG_EVENT) + zlog_info("ZNS %s with id %u (deleted)", ns->name, ns->ns_id); + if (!zns) + return 0; + XFREE(MTYPE_ZEBRA_NS, zns); + return 0; +} + +static int zebra_ns_enabled(struct ns *ns) +{ + struct zebra_ns *zns = ns->info; + + if (IS_ZEBRA_DEBUG_EVENT) + zlog_info("ZNS %s with id %u (enabled)", ns->name, ns->ns_id); + if (!zns) + return 0; + return zebra_ns_enable(ns->ns_id, (void **)&zns); +} + +static int zebra_ns_disabled(struct ns *ns) +{ + struct zebra_ns *zns = ns->info; + + if (IS_ZEBRA_DEBUG_EVENT) + zlog_info("ZNS %s with id %u (disabled)", ns->name, ns->ns_id); + if (!zns) + return 0; + return zebra_ns_disable(ns->ns_id, (void **)&zns); +} + /* Do global enable actions - open sockets, read kernel config etc. */ int zebra_ns_enable(ns_id_t ns_id, void **info) { @@ -162,7 +215,9 @@ int zebra_ns_disable(ns_id_t ns_id, void **info) int zebra_ns_init(void) { - dzns = XCALLOC(MTYPE_ZEBRA_NS, sizeof(struct zebra_ns)); + dzns = zebra_ns_alloc(); + + ns_init_zebra(); ns_init(); @@ -176,6 +231,12 @@ int zebra_ns_init(void) /* Default NS is activated */ zebra_ns_enable(NS_DEFAULT, (void **)&dzns); + if (vrf_is_backend_netns()) { + ns_add_hook(NS_NEW_HOOK, zebra_ns_new); + ns_add_hook(NS_ENABLE_HOOK, zebra_ns_enabled); + ns_add_hook(NS_DISABLE_HOOK, zebra_ns_disabled); + ns_add_hook(NS_DELETE_HOOK, zebra_ns_delete); + } return 0; } diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index 99e4984164..aaf5abaa26 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -69,6 +69,9 @@ struct zebra_ns { #endif /* HAVE_RTADV */ struct zebra_ns_table_head ns_tables; + + /* Back pointer */ + struct ns *ns; }; struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id); -- 2.39.5