diff options
Diffstat (limited to 'lib/vrf.c')
| -rw-r--r-- | lib/vrf.c | 268 |
1 files changed, 34 insertions, 234 deletions
@@ -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 ------- */ /* |
