summaryrefslogtreecommitdiff
path: root/lib/ns.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2017-12-13 11:04:31 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2018-02-27 11:11:24 +0100
commit697d3ec73157fde8a008738907fef94fdcd569bb (patch)
treeed168a01b0c4535f172cbcd437b676cece7fdc09 /lib/ns.c
parentfbb65ff50428eefba0653e8f3f6f33afa003c4cd (diff)
lib: externalise vrf and ns creation
In addition to have the possibility to create from vty vrf based on a netns backend, the API will be made accessible from external, especially for zebra that will handle the netns discovery part. This commit is externalising following functions: - netns_pathname - ns_handler_create - vrf_handler_create Also, the VRF initialisation case when under NETNS backend is changed, since the NS identifier may not be known at the configuration time,but may be known later, under discovery process. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'lib/ns.c')
-rw-r--r--lib/ns.c105
1 files changed, 79 insertions, 26 deletions
diff --git a/lib/ns.c b/lib/ns.c
index 170290a9e9..694a6dab9d 100644
--- a/lib/ns.c
+++ b/lib/ns.c
@@ -236,6 +236,7 @@ static int ns_is_enabled(struct ns *ns)
*/
static int ns_enable(struct ns *ns)
{
+ int vrf_on = 0;
if (!ns_is_enabled(ns)) {
if (have_netns()) {
@@ -252,13 +253,26 @@ static int ns_enable(struct ns *ns)
return 0;
}
+ /* Non default NS. leave */
+ if (ns->ns_id == NS_UNKNOWN) {
+ zlog_err("Can not enable NS %s %u: Invalid NSID",
+ ns->name, ns->ns_id);
+ return 0;
+ }
+ vrf_on = vrf_update_vrf_id((vrf_id_t)ns->ns_id,
+ (struct vrf *)ns->vrf_ctxt);
if (have_netns())
zlog_info("NS %u is associated with NETNS %s.",
ns->ns_id, ns->name);
zlog_info("NS %u is enabled.", ns->ns_id);
+ /* zebra first receives NS enable event,
+ * then VRF enable event
+ */
if (ns_master.ns_enable_hook)
(*ns_master.ns_enable_hook)(ns->ns_id, &ns->info);
+ if (vrf_on == 1)
+ vrf_enable((struct vrf *)ns->vrf_ctxt);
}
return 1;
@@ -310,7 +324,7 @@ void ns_add_hook(int type, int (*func)(ns_id_t, void **))
* NS realization with NETNS
*/
-static char *ns_netns_pathname(struct vty *vty, const char *name)
+char *ns_netns_pathname(struct vty *vty, const char *name)
{
static char pathname[PATH_MAX];
char *result;
@@ -325,7 +339,9 @@ static char *ns_netns_pathname(struct vty *vty, const char *name)
}
if (!result) {
- vty_out(vty, "Invalid pathname: %s\n", safe_strerror(errno));
+ if (vty)
+ vty_out(vty, "Invalid pathname: %s\n",
+ safe_strerror(errno));
return NULL;
}
return pathname;
@@ -413,34 +429,34 @@ DEFUN (no_ns_logicalrouter,
return CMD_SUCCESS;
}
-DEFUN_NOSH (ns_netns,
- ns_netns_cmd,
- "netns NAME",
- "Attach VRF to a Namespace\n"
- "The file name in " NS_RUN_DIR ", or a full pathname\n")
+int ns_handler_create(struct vty *vty, struct vrf *vrf,
+ char *pathname, ns_id_t ns_id)
{
- int idx_name = 1;
struct ns *ns = NULL;
- char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
-
- VTY_DECLVAR_CONTEXT(vrf, vrf);
-
- if (!pathname)
- return CMD_WARNING_CONFIG_FAILED;
if (!vrf)
return CMD_WARNING_CONFIG_FAILED;
if (vrf->vrf_id != VRF_UNKNOWN && vrf->ns_ctxt == NULL) {
- vty_out(vty, "VRF %u is already configured with VRF %s\n",
- vrf->vrf_id, vrf->name);
+ if (vty)
+ vty_out(vty,
+ "VRF %u is already configured with VRF %s\n",
+ vrf->vrf_id, vrf->name);
+ else
+ zlog_warn("VRF %u is already configured with VRF %s\n",
+ vrf->vrf_id, vrf->name);
return CMD_WARNING_CONFIG_FAILED;
}
if (vrf->ns_ctxt != NULL) {
ns = (struct ns *) vrf->ns_ctxt;
if (ns && 0 != strcmp(ns->name, pathname)) {
- vty_out(vty, "VRF %u is already configured"
- " with NETNS %s\n",
- vrf->vrf_id, ns->name);
+ if (vty)
+ vty_out(vty,
+ "VRF %u is already configured"
+ " with NETNS %s\n",
+ vrf->vrf_id, ns->name);
+ else
+ zlog_warn("VRF %u is already configured with NETNS %s",
+ vrf->vrf_id, ns->name);
return CMD_WARNING_CONFIG_FAILED;
}
}
@@ -448,24 +464,38 @@ DEFUN_NOSH (ns_netns,
if (ns && ns->vrf_ctxt) {
struct vrf *vrf2 = (struct vrf *)ns->vrf_ctxt;
- vty_out(vty, "NS %s is already configured"
- " with VRF %u(%s)\n",
- ns->name, vrf2->vrf_id, vrf2->name);
+ if (vty)
+ vty_out(vty, "NS %s is already configured"
+ " with VRF %u(%s)\n",
+ ns->name, vrf2->vrf_id, vrf2->name);
+ else
+ zlog_warn("NS %s is already configured with VRF %u(%s)",
+ ns->name, vrf2->vrf_id, vrf2->name);
return CMD_WARNING_CONFIG_FAILED;
} else if (!ns)
ns = ns_get_by_name(pathname);
+ if (ns_id != ns->ns_id) {
+ RB_REMOVE(ns_head, &ns_tree, ns);
+ ns->ns_id = ns_id;
+ RB_INSERT(ns_head, &ns_tree, ns);
+ }
+ ns->vrf_ctxt = (void *)vrf;
+ vrf->ns_ctxt = (void *)ns;
if (!ns_enable(ns)) {
- vty_out(vty, "Can not associate NS %u with NETNS %s\n",
- ns->ns_id, ns->name);
+ if (vty)
+ vty_out(vty, "Can not associate NS %u with NETNS %s\n",
+ ns->ns_id, ns->name);
+ else
+ zlog_warn("Can not associate NS %u with NETNS %s",
+ ns->ns_id, ns->name);
return CMD_WARNING_CONFIG_FAILED;
}
- vrf->ns_ctxt = (void *)ns;
- ns->vrf_ctxt = (void *)vrf;
return CMD_SUCCESS;
}
+
static int ns_logicalrouter_config_write(struct vty *vty)
{
struct ns *ns;
@@ -481,6 +511,22 @@ static int ns_logicalrouter_config_write(struct vty *vty)
return write;
}
+DEFUN_NOSH (ns_netns,
+ ns_netns_cmd,
+ "netns NAME",
+ "Attach VRF to a Namespace\n"
+ "The file name in " NS_RUN_DIR ", or a full pathname\n")
+{
+ int idx_name = 1;
+ char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
+
+ VTY_DECLVAR_CONTEXT(vrf, vrf);
+
+ if (!pathname)
+ return CMD_WARNING_CONFIG_FAILED;
+ return ns_handler_create(vty, vrf, pathname, NS_UNKNOWN);
+}
+
DEFUN (no_ns_netns,
no_ns_netns_cmd,
"no netns [NAME]",
@@ -505,6 +551,13 @@ DEFUN (no_ns_netns,
ns = (struct ns *)vrf->ns_ctxt;
ns->vrf_ctxt = NULL;
+ vrf_disable(vrf);
+ /* vrf ID from VRF is necessary for Zebra
+ * so that propagate to other clients is done
+ */
+ RB_REMOVE(ns_head, &ns_tree, ns);
+ ns->ns_id = NS_UNKNOWN;
+ RB_INSERT(ns_head, &ns_tree, ns);
ns_delete(ns);
vrf->ns_ctxt = NULL;
return CMD_SUCCESS;