diff options
| -rw-r--r-- | lib/vrf.c | 157 | ||||
| -rw-r--r-- | lib/vrf.h | 15 | ||||
| -rw-r--r-- | zebra/zebra_netns_notify.c | 22 | ||||
| -rw-r--r-- | zebra/zebra_vrf.c | 100 | ||||
| -rw-r--r-- | zebra/zebra_vrf.h | 8 | 
5 files changed, 143 insertions, 159 deletions
@@ -21,9 +21,6 @@  #include <zebra.h> -/* for basename */ -#include <libgen.h> -  #include "if.h"  #include "vrf.h"  #include "vrf_int.h" @@ -97,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; @@ -657,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, @@ -784,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; +	} -	return vrf_handler_create(vty, vrfname, NULL); +	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 ret;  }  DEFUN_YANG (no_vrf, @@ -301,21 +301,6 @@ extern int vrf_configure_backend(enum vrf_backend_type backend);  extern int vrf_get_backend(void);  extern int vrf_is_backend_netns(void); - -/* API to create a VRF. either from vty - * or through discovery - */ -extern int vrf_handler_create(struct vty *vty, const char *name, -			      struct vrf **vrf); - -/* API to associate a VRF with a NETNS. - * called either from vty or through discovery - * should be called from zebra only - */ -extern int vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, -				    char *pathname, ns_id_t ext_ns_id, -				    ns_id_t ns_id, ns_id_t rel_def_ns_id); -  /* used internally to enable or disable VRF.   * Notify a change in the VRF ID of the VRF   */ diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 2d25801590..0d260ad639 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -66,6 +66,18 @@ static int zebra_ns_continue_read(struct zebra_netns_info *zns_info,  				  int stop_retry);  static int zebra_ns_notify_read(struct thread *t); +static struct vrf *vrf_handler_create(struct vty *vty, const char *vrfname) +{ +	if (strlen(vrfname) > VRF_NAMSIZ) { +		flog_warn(EC_LIB_VRF_LENGTH, +			  "%% VRF name %s invalid: length exceeds %d bytes", +			  vrfname, VRF_NAMSIZ); +		return NULL; +	} + +	return vrf_get(VRF_UNKNOWN, vrfname); +} +  static void zebra_ns_notify_create_context_from_entry_name(const char *name)  {  	char *netnspath = ns_netns_pathname(NULL, name); @@ -91,7 +103,8 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name)  			vrf->name, netnspath);  		return;  	} -	if (vrf_handler_create(NULL, name, &vrf) != CMD_SUCCESS) { +	vrf = vrf_handler_create(NULL, name); +	if (!vrf) {  		flog_warn(EC_ZEBRA_NS_VRF_CREATION_FAILED,  			  "NS notify : failed to create VRF %s", name);  		ns_map_nsid_with_external(ns_id, false); @@ -108,10 +121,9 @@ static void zebra_ns_notify_create_context_from_entry_name(const char *name)  	}  	frr_with_privs(&zserv_privs) { -		ret = vrf_netns_handler_create(NULL, vrf, netnspath, -					       ns_id_external, -					       ns_id, -					       ns_id_relative); +		ret = zebra_vrf_netns_handler_create(NULL, vrf, netnspath, +						     ns_id_external, ns_id, +						     ns_id_relative);  	}  	if (ret != CMD_SUCCESS) {  		flog_warn(EC_ZEBRA_NS_VRF_CREATION_FAILED, diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index 4b00f3415c..d051ed67a0 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -20,6 +20,9 @@   */  #include <zebra.h> +/* for basename */ +#include <libgen.h> +  #include "log.h"  #include "linklist.h"  #include "command.h" @@ -565,10 +568,8 @@ DEFPY (vrf_netns,  		return CMD_WARNING_CONFIG_FAILED;  	frr_with_privs(&zserv_privs) { -		ret = vrf_netns_handler_create(vty, vrf, pathname, -					       NS_UNKNOWN, -					       NS_UNKNOWN, -					       NS_UNKNOWN); +		ret = zebra_vrf_netns_handler_create( +			vty, vrf, pathname, NS_UNKNOWN, NS_UNKNOWN, NS_UNKNOWN);  	}  	return ret; @@ -607,6 +608,97 @@ DEFUN (no_vrf_netns,  	return CMD_SUCCESS;  } +/* 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 zebra_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; +} +  /* Zebra VRF initialization. */  void zebra_vrf_init(void)  { diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index 3def27b79e..a24a008b76 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -260,6 +260,14 @@ extern struct zebra_vrf *zebra_vrf_lookup_by_name(const char *);  extern struct zebra_vrf *zebra_vrf_alloc(struct vrf *vrf);  extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t); +/* + * API to associate a VRF with a NETNS. + * Called either from vty or through discovery. + */ +extern int zebra_vrf_netns_handler_create(struct vty *vty, struct vrf *vrf, +					  char *pathname, ns_id_t ext_ns_id, +					  ns_id_t ns_id, ns_id_t rel_def_ns_id); +  extern void zebra_vrf_init(void);  extern void zebra_rtable_node_cleanup(struct route_table *table,  | 
