summaryrefslogtreecommitdiff
path: root/lib/vrf.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/vrf.c')
-rw-r--r--lib/vrf.c268
1 files changed, 34 insertions, 234 deletions
diff --git a/lib/vrf.c b/lib/vrf.c
index 03d9a62c0f..847899f0ba 100644
--- a/lib/vrf.c
+++ b/lib/vrf.c
@@ -21,9 +21,6 @@
#include <zebra.h>
-/* for basename */
-#include <libgen.h>
-
#include "if.h"
#include "vrf.h"
#include "vrf_int.h"
@@ -58,7 +55,6 @@ struct vrf_name_head vrfs_by_name = RB_INITIALIZER(&vrfs_by_name);
static int vrf_backend;
static int vrf_backend_configured;
-static struct zebra_privs_t *vrf_daemon_privs;
static char vrf_default_name[VRF_NAMSIZ] = VRF_DEFAULT_NAME_INTERNAL;
/*
@@ -98,28 +94,6 @@ static int vrf_name_compare(const struct vrf *a, const struct vrf *b)
return strcmp(a->name, b->name);
}
-/* if ns_id is different and not VRF_UNKNOWN,
- * then update vrf identifier, and enable VRF
- */
-static void vrf_update_vrf_id(ns_id_t ns_id, void *opaqueptr)
-{
- ns_id_t vrf_id = (vrf_id_t)ns_id;
- vrf_id_t old_vrf_id;
- struct vrf *vrf = (struct vrf *)opaqueptr;
-
- if (!vrf)
- return;
- old_vrf_id = vrf->vrf_id;
- if (vrf_id == vrf->vrf_id)
- return;
- if (vrf->vrf_id != VRF_UNKNOWN)
- RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
- vrf->vrf_id = vrf_id;
- RB_INSERT(vrf_id_head, &vrfs_by_id, vrf);
- if (old_vrf_id == VRF_UNKNOWN)
- vrf_enable(vrf);
-}
-
int vrf_switch_to_netns(vrf_id_t vrf_id)
{
char *name;
@@ -273,31 +247,29 @@ void vrf_delete(struct vrf *vrf)
if (vrf_is_enabled(vrf))
vrf_disable(vrf);
+ if (vrf->vrf_id != VRF_UNKNOWN) {
+ RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
+ vrf->vrf_id = VRF_UNKNOWN;
+ }
+
/* If the VRF is user configured, it'll stick around, just remove
* the ID mapping. Interfaces assigned to this VRF should've been
* removed already as part of the VRF going down.
*/
if (vrf_is_user_cfged(vrf)) {
- if (vrf->vrf_id != VRF_UNKNOWN) {
- /* Delete any VRF interfaces - should be only
- * the VRF itself, other interfaces should've
- * been moved out of the VRF.
- */
- if_terminate(vrf);
- RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
- vrf->vrf_id = VRF_UNKNOWN;
- }
+ vrf->ns_ctxt = NULL;
return;
}
+ /* Do not delete the VRF if it has interfaces configured in it. */
+ if (!RB_EMPTY(if_name_head, &vrf->ifaces_by_name))
+ return;
+
if (vrf_master.vrf_delete_hook)
(*vrf_master.vrf_delete_hook)(vrf);
QOBJ_UNREG(vrf);
- if_terminate(vrf);
- if (vrf->vrf_id != VRF_UNKNOWN)
- RB_REMOVE(vrf_id_head, &vrfs_by_id, vrf);
if (vrf->name[0] != '\0')
RB_REMOVE(vrf_name_head, &vrfs_by_name, vrf);
@@ -384,21 +356,6 @@ const char *vrf_id_to_name(vrf_id_t vrf_id)
return VRF_LOGNAME(vrf);
}
-vrf_id_t vrf_name_to_id(const char *name)
-{
- struct vrf *vrf;
- vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid
- // id/ routine not used.
-
- if (!name)
- return vrf_id;
- vrf = vrf_lookup_by_name(name);
- if (vrf)
- vrf_id = vrf->vrf_id;
-
- return vrf_id;
-}
-
/* Get the data pointer of the specified VRF. If not found, create one. */
void *vrf_info_get(vrf_id_t vrf_id)
{
@@ -586,6 +543,7 @@ static void vrf_terminate_single(struct vrf *vrf)
{
/* Clear configured flag and invoke delete. */
UNSET_FLAG(vrf->status, VRF_CONFIGURED);
+ if_terminate(vrf);
vrf_delete(vrf);
}
@@ -674,115 +632,6 @@ int vrf_configure_backend(enum vrf_backend_type backend)
return 0;
}
-int vrf_handler_create(struct vty *vty, const char *vrfname,
- struct vrf **vrf)
-{
- struct vrf *vrfp;
- char xpath_list[XPATH_MAXLEN];
- int ret;
-
- if (strlen(vrfname) > VRF_NAMSIZ) {
- if (vty)
- vty_out(vty,
- "%% VRF name %s invalid: length exceeds %d bytes\n",
- vrfname, VRF_NAMSIZ);
- else
- flog_warn(
- EC_LIB_VRF_LENGTH,
- "%% VRF name %s invalid: length exceeds %d bytes",
- vrfname, VRF_NAMSIZ);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (vty) {
- snprintf(xpath_list, sizeof(xpath_list), FRR_VRF_KEY_XPATH,
- vrfname);
-
- nb_cli_enqueue_change(vty, xpath_list, NB_OP_CREATE, NULL);
- ret = nb_cli_apply_changes_clear_pending(vty, xpath_list);
- if (ret == CMD_SUCCESS) {
- VTY_PUSH_XPATH(VRF_NODE, xpath_list);
- vrfp = vrf_lookup_by_name(vrfname);
- if (vrfp)
- VTY_PUSH_CONTEXT(VRF_NODE, vrfp);
- }
- } else {
- vrfp = vrf_get(VRF_UNKNOWN, vrfname);
-
- if (vrf)
- *vrf = vrfp;
- }
- return CMD_SUCCESS;
-}
-
-int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, char *pathname,
- ns_id_t ns_id, ns_id_t internal_ns_id,
- ns_id_t rel_def_ns_id)
-{
- struct ns *ns = NULL;
-
- if (!vrf)
- return CMD_WARNING_CONFIG_FAILED;
- if (vrf->vrf_id != VRF_UNKNOWN && vrf->ns_ctxt == NULL) {
- if (vty)
- vty_out(vty,
- "VRF %u is already configured with VRF %s\n",
- vrf->vrf_id, vrf->name);
- else
- zlog_info("VRF %u is already configured with VRF %s",
- vrf->vrf_id, vrf->name);
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (vrf->ns_ctxt != NULL) {
- ns = (struct ns *)vrf->ns_ctxt;
- if (!strcmp(ns->name, pathname)) {
- if (vty)
- vty_out(vty,
- "VRF %u already configured with NETNS %s\n",
- vrf->vrf_id, ns->name);
- else
- zlog_info(
- "VRF %u already configured with NETNS %s",
- vrf->vrf_id, ns->name);
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
- ns = ns_lookup_name(pathname);
- if (ns && ns->vrf_ctxt) {
- struct vrf *vrf2 = (struct vrf *)ns->vrf_ctxt;
-
- if (vrf2 == vrf)
- return CMD_SUCCESS;
- if (vty)
- vty_out(vty,
- "NS %s is already configured with VRF %u(%s)\n",
- ns->name, vrf2->vrf_id, vrf2->name);
- else
- zlog_info("NS %s is already configured with VRF %u(%s)",
- ns->name, vrf2->vrf_id, vrf2->name);
- return CMD_WARNING_CONFIG_FAILED;
- }
- ns = ns_get_created(ns, pathname, ns_id);
- ns->internal_ns_id = internal_ns_id;
- ns->relative_default_ns = rel_def_ns_id;
- ns->vrf_ctxt = (void *)vrf;
- vrf->ns_ctxt = (void *)ns;
- /* update VRF netns NAME */
- strlcpy(vrf->data.l.netns_name, basename(pathname), NS_NAMSIZ);
-
- if (!ns_enable(ns, vrf_update_vrf_id)) {
- if (vty)
- vty_out(vty, "Can not associate NS %u with NETNS %s\n",
- ns->ns_id, ns->name);
- else
- zlog_info("Can not associate NS %u with NETNS %s",
- ns->ns_id, ns->name);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return CMD_SUCCESS;
-}
-
/* vrf CLI commands */
DEFUN_NOSH(vrf_exit,
vrf_exit_cmd,
@@ -801,8 +650,29 @@ DEFUN_YANG_NOSH (vrf,
{
int idx_name = 1;
const char *vrfname = argv[idx_name]->arg;
+ char xpath_list[XPATH_MAXLEN];
+ struct vrf *vrf;
+ int ret;
+
+ if (strlen(vrfname) > VRF_NAMSIZ) {
+ vty_out(vty,
+ "%% VRF name %s invalid: length exceeds %d bytes\n",
+ vrfname, VRF_NAMSIZ);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ snprintf(xpath_list, sizeof(xpath_list), FRR_VRF_KEY_XPATH, vrfname);
+
+ nb_cli_enqueue_change(vty, xpath_list, NB_OP_CREATE, NULL);
+ ret = nb_cli_apply_changes_clear_pending(vty, xpath_list);
+ if (ret == CMD_SUCCESS) {
+ VTY_PUSH_XPATH(VRF_NODE, xpath_list);
+ vrf = vrf_lookup_by_name(vrfname);
+ if (vrf)
+ VTY_PUSH_CONTEXT(VRF_NODE, vrf);
+ }
- return vrf_handler_create(vty, vrfname, NULL);
+ return ret;
}
DEFUN_YANG (no_vrf,
@@ -855,62 +725,6 @@ static struct cmd_node vrf_node = {
.prompt = "%s(config-vrf)# ",
};
-DEFUN_NOSH (vrf_netns,
- vrf_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, ret;
- char *pathname = ns_netns_pathname(vty, argv[idx_name]->arg);
-
- VTY_DECLVAR_CONTEXT(vrf, vrf);
-
- if (!pathname)
- return CMD_WARNING_CONFIG_FAILED;
-
- frr_with_privs(vrf_daemon_privs) {
- ret = vrf_netns_handler_create(vty, vrf, pathname,
- NS_UNKNOWN,
- NS_UNKNOWN,
- NS_UNKNOWN);
- }
- return ret;
-}
-
-DEFUN_NOSH (no_vrf_netns,
- no_vrf_netns_cmd,
- "no netns [NAME]",
- NO_STR
- "Detach VRF from a Namespace\n"
- "The file name in " NS_RUN_DIR ", or a full pathname\n")
-{
- struct ns *ns = NULL;
-
- VTY_DECLVAR_CONTEXT(vrf, vrf);
-
- if (!vrf_is_backend_netns()) {
- vty_out(vty, "VRF backend is not Netns. Aborting\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
- if (!vrf->ns_ctxt) {
- vty_out(vty, "VRF %s(%u) is not configured with NetNS\n",
- vrf->name, vrf->vrf_id);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- 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
- */
- ns_delete(ns);
- vrf->ns_ctxt = NULL;
- return CMD_SUCCESS;
-}
-
/*
* Debug CLI for vrf's
*/
@@ -963,8 +777,7 @@ void vrf_install_commands(void)
install_element(ENABLE_NODE, &no_vrf_debug_cmd);
}
-void vrf_cmd_init(int (*writefunc)(struct vty *vty),
- struct zebra_privs_t *daemon_privs)
+void vrf_cmd_init(int (*writefunc)(struct vty *vty))
{
install_element(CONFIG_NODE, &vrf_cmd);
install_element(CONFIG_NODE, &no_vrf_cmd);
@@ -972,12 +785,6 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty),
install_node(&vrf_node);
install_default(VRF_NODE);
install_element(VRF_NODE, &vrf_exit_cmd);
- if (vrf_is_backend_netns() && ns_have_netns()) {
- /* Install NS commands. */
- vrf_daemon_privs = daemon_privs;
- install_element(VRF_NODE, &vrf_netns_cmd);
- install_element(VRF_NODE, &no_vrf_netns_cmd);
- }
}
void vrf_set_default_name(const char *default_name, bool force)
@@ -1131,13 +938,6 @@ int vrf_sockunion_socket(const union sockunion *su, vrf_id_t vrf_id,
return ret;
}
-vrf_id_t vrf_generate_id(void)
-{
- static int vrf_id_local;
-
- return ++vrf_id_local;
-}
-
/* ------- Northbound callbacks ------- */
/*