diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2023-07-03 17:15:05 +0200 | 
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2023-07-12 14:06:00 +0200 | 
| commit | 2150647069903840ef76353a5085eb5afc96cfaf (patch) | |
| tree | b11af3cd650d0c7743e858d78d443a94fbd200d8 /isisd | |
| parent | 6934a1d31d832e423376c49a10646dd9f4336cd3 (diff) | |
isisd: add redistribute table identifier in nb configuration
The yang model does not handle the table identifier in IS-IS.
For each redistributed each address family, a new list of
table elements is added to store the table identifier to
redistribute, and also the optional metric and route-map values
for each table identifier.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'isisd')
| -rw-r--r-- | isisd/isis_cli.c | 128 | ||||
| -rw-r--r-- | isisd/isis_nb.c | 46 | ||||
| -rw-r--r-- | isisd/isis_nb.h | 19 | ||||
| -rw-r--r-- | isisd/isis_nb_config.c | 51 | ||||
| -rw-r--r-- | isisd/isis_redist.c | 47 | ||||
| -rw-r--r-- | isisd/isis_redist.h | 13 | 
6 files changed, 292 insertions, 12 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 7c7a8d2389..6f53ab479f 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -1430,20 +1430,99 @@ DEFPY_YANG(isis_redistribute, isis_redistribute_cmd,  		level);  } -static void vty_print_redistribute(struct vty *vty, -				   const struct lyd_node *dnode, -				   bool show_defaults, const char *family) -{ -	const char *level = yang_dnode_get_string(dnode, "./level"); -	const char *protocol = yang_dnode_get_string(dnode, "./protocol"); +/* + * XPath: /frr-isisd:isis/instance/redistribute/table + */ +DEFPY_YANG(isis_redistribute_table, isis_redistribute_table_cmd, +	   "[no] redistribute <ipv4|ipv6>$ip table (1-65535)$table" +	   "<level-1|level-2>$level [{metric (0-16777215)|route-map WORD}]", +	   NO_STR REDIST_STR "Redistribute IPv4 routes\n" +			     "Redistribute IPv6 routes\n" +			     "Non-main Kernel Routing Table\n" +			     "Table Id\n" +			     "Redistribute into level-1\n" +			     "Redistribute into level-2\n" +			     "Metric for redistributed routes\n" +			     "IS-IS default metric\n" +			     "Route map reference\n" +			     "Pointer to route-map entries\n") +{ +	struct isis_redist_table_present_args rtda = {}; +	char xpath[XPATH_MAXLEN]; +	char xpath_entry[XPATH_MAXLEN + 128]; +	int rv; + +	rtda.rtda_table = table_str; +	rtda.rtda_ip = ip; +	rtda.rtda_level = level; -	vty_out(vty, " redistribute %s %s %s", family, protocol, level); +	if (no) { +		if (!isis_redist_table_is_present(vty, &rtda)) +			return CMD_WARNING_CONFIG_FAILED; + +		snprintf(xpath, sizeof(xpath), "./table[table='%s']", table_str); +		nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); +		rv = nb_cli_apply_changes(vty, +					  "./redistribute/%s[protocol='table'][level='%s']", +					  ip, level); +		if (rv == CMD_SUCCESS) { +			if (isis_redist_table_get_first(vty, &rtda) > 0) +				return CMD_SUCCESS; +			nb_cli_enqueue_change(vty, "./table", NB_OP_DESTROY, +					      NULL); +			nb_cli_apply_changes(vty, +					     "./redistribute/%s[protocol='table'][level='%s']", +					     ip, level); +		} +		return CMD_SUCCESS; +	} +	if (isis_redist_table_is_present(vty, &rtda)) +		return CMD_SUCCESS; + +	snprintf(xpath, sizeof(xpath), "./table[table='%s']", table_str); +	nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); +	nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); +	snprintf(xpath_entry, sizeof(xpath_entry), "%s/route-map", xpath); +	nb_cli_enqueue_change(vty, xpath_entry, +			      route_map ? NB_OP_MODIFY : NB_OP_DESTROY, +			      route_map ? route_map : NULL); +	snprintf(xpath_entry, sizeof(xpath_entry), "%s/metric", xpath); +	nb_cli_enqueue_change(vty, xpath_entry, NB_OP_MODIFY, +			      metric_str ? metric_str : NULL); +	return nb_cli_apply_changes(vty, +				    "./redistribute/%s[protocol='table'][level='%s']", +				    ip, level); +} + +static void vty_print_redistribute(struct vty *vty, const struct lyd_node *dnode, +				   bool show_defaults, const char *family, +				   bool table) +{ +	const char *level; +	const char *protocol = NULL; +	const char *routemap = NULL; +	uint16_t tableid; + +	if (table) { +		level = yang_dnode_get_string(dnode, "../level"); +		tableid = yang_dnode_get_uint16(dnode, "./table"); +		vty_out(vty, " redistribute %s table %d ", family, tableid); +	} else { +		protocol = yang_dnode_get_string(dnode, "./protocol"); +		if (!table && strmatch(protocol, "table")) +			return; +		level = yang_dnode_get_string(dnode, "./level"); +		vty_out(vty, " redistribute %s %s ", family, protocol); +	} +	vty_out(vty, "%s", level);  	if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))  		vty_out(vty, " metric %s", -			yang_dnode_get_string(dnode, "./metric")); +			yang_dnode_get_string(dnode, "%s", "./metric")); +  	if (yang_dnode_exists(dnode, "./route-map")) -		vty_out(vty, " route-map %s", -			yang_dnode_get_string(dnode, "./route-map")); +		routemap = yang_dnode_get_string(dnode, "./route-map"); +	if (routemap) +		vty_out(vty, " route-map %s", routemap);  	vty_out(vty, "\n");  } @@ -1451,13 +1530,37 @@ void cli_show_isis_redistribute_ipv4(struct vty *vty,  				     const struct lyd_node *dnode,  				     bool show_defaults)  { -	vty_print_redistribute(vty, dnode, show_defaults, "ipv4"); +	vty_print_redistribute(vty, dnode, show_defaults, "ipv4", false);  } +  void cli_show_isis_redistribute_ipv6(struct vty *vty,  				     const struct lyd_node *dnode,  				     bool show_defaults)  { -	vty_print_redistribute(vty, dnode, show_defaults, "ipv6"); +	vty_print_redistribute(vty, dnode, show_defaults, "ipv6", false); +} + +void cli_show_isis_redistribute_ipv4_table(struct vty *vty, +					   const struct lyd_node *dnode, +					   bool show_defaults) +{ +	vty_print_redistribute(vty, dnode, show_defaults, "ipv4", true); +} + +void cli_show_isis_redistribute_ipv6_table(struct vty *vty, +					   const struct lyd_node *dnode, +					   bool show_defaults) +{ +	vty_print_redistribute(vty, dnode, show_defaults, "ipv6", true); +} + +int cli_cmp_isis_redistribute_table(const struct lyd_node *dnode1, +				    const struct lyd_node *dnode2) +{ +	uint16_t table1 = yang_dnode_get_uint16(dnode1, "./table"); +	uint16_t table2 = yang_dnode_get_uint16(dnode2, "./table"); + +	return table1 - table2;  }  /* @@ -3681,6 +3784,7 @@ void isis_cli_init(void)  	install_element(ISIS_NODE, &isis_default_originate_cmd);  	install_element(ISIS_NODE, &isis_redistribute_cmd); +	install_element(ISIS_NODE, &isis_redistribute_table_cmd);  	install_element(ISIS_NODE, &isis_topology_cmd); diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index 6da8fa2d28..c81412d24a 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -382,6 +382,29 @@ const struct frr_yang_module_info frr_isisd_info = {  		{  			.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/metric",  			.cbs = { +				.destroy = isis_instance_redistribute_ipv4_metric_destroy, +				.modify = isis_instance_redistribute_ipv4_metric_modify, +			}, +		}, +		{ +			.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/table", +			.cbs = { +				.cli_show = cli_show_isis_redistribute_ipv4_table, +                                .cli_cmp = cli_cmp_isis_redistribute_table, +				.create = isis_instance_redistribute_ipv4_table_create, +				.destroy = isis_instance_redistribute_ipv4_table_destroy, +			}, +		}, +		{ +			.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/table/route-map", +			.cbs = { +				.destroy = isis_instance_redistribute_ipv4_route_map_destroy, +				.modify = isis_instance_redistribute_ipv4_route_map_modify, +			}, +		}, +		{ +			.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/table/metric", +			.cbs = {  				.modify = isis_instance_redistribute_ipv4_metric_modify,  			},  		}, @@ -404,6 +427,29 @@ const struct frr_yang_module_info frr_isisd_info = {  		{  			.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/metric",  			.cbs = { +				.destroy = isis_instance_redistribute_ipv6_metric_destroy, +				.modify = isis_instance_redistribute_ipv6_metric_modify, +			}, +		}, +		{ +			.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/table", +			.cbs = { +				.cli_show = cli_show_isis_redistribute_ipv6_table, +				.cli_cmp = cli_cmp_isis_redistribute_table, +				.create = isis_instance_redistribute_ipv6_table_create, +				.destroy = isis_instance_redistribute_ipv6_table_destroy, +			}, +		}, +		{ +			.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/table/route-map", +			.cbs = { +				.destroy = isis_instance_redistribute_ipv6_route_map_destroy, +				.modify = isis_instance_redistribute_ipv6_route_map_modify, +			}, +		}, +		{ +			.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/table/metric", +			.cbs = {  				.modify = isis_instance_redistribute_ipv6_metric_modify,  			},  		}, diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index 13efa36d78..3b8ddca4f8 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -121,6 +121,11 @@ int isis_instance_redistribute_ipv4_route_map_destroy(  	struct nb_cb_destroy_args *args);  int isis_instance_redistribute_ipv4_metric_modify(  	struct nb_cb_modify_args *args); +int isis_instance_redistribute_ipv4_metric_destroy( +	struct nb_cb_destroy_args *args); +int isis_instance_redistribute_ipv4_table_create(struct nb_cb_create_args *args); +int isis_instance_redistribute_ipv4_table_destroy( +	struct nb_cb_destroy_args *args);  int isis_instance_redistribute_ipv6_create(struct nb_cb_create_args *args);  int isis_instance_redistribute_ipv6_destroy(struct nb_cb_destroy_args *args);  int isis_instance_redistribute_ipv6_route_map_modify( @@ -129,6 +134,11 @@ int isis_instance_redistribute_ipv6_route_map_destroy(  	struct nb_cb_destroy_args *args);  int isis_instance_redistribute_ipv6_metric_modify(  	struct nb_cb_modify_args *args); +int isis_instance_redistribute_ipv6_metric_destroy( +	struct nb_cb_destroy_args *args); +int isis_instance_redistribute_ipv6_table_create(struct nb_cb_create_args *args); +int isis_instance_redistribute_ipv6_table_destroy( +	struct nb_cb_destroy_args *args);  int isis_instance_multi_topology_ipv4_multicast_create(  	struct nb_cb_create_args *args);  int isis_instance_multi_topology_ipv4_multicast_destroy( @@ -587,6 +597,12 @@ void cli_show_isis_redistribute_ipv6(struct vty *vty,  void cli_show_isis_mt_ipv4_multicast(struct vty *vty,  				     const struct lyd_node *dnode,  				     bool show_defaults); +void cli_show_isis_redistribute_ipv4_table(struct vty *vty, +					   const struct lyd_node *dnode, +					   bool show_defaults); +void cli_show_isis_redistribute_ipv6_table(struct vty *vty, +					   const struct lyd_node *dnode, +					   bool show_defaults);  void cli_show_isis_mt_ipv4_mgmt(struct vty *vty, const struct lyd_node *dnode,  				bool show_defaults);  void cli_show_isis_mt_ipv6_unicast(struct vty *vty, @@ -742,6 +758,9 @@ void isis_notif_seqno_skipped(const struct isis_circuit *circuit,  			      const uint8_t *lsp_id);  void isis_notif_own_lsp_purge(const struct isis_circuit *circuit,  			      const uint8_t *lsp_id); +/* cmp */ +int cli_cmp_isis_redistribute_table(const struct lyd_node *dnode1, +				    const struct lyd_node *dnode2);  /* We also declare hook for every notification */ diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 8a111b301d..278d4a8d85 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -1281,6 +1281,7 @@ int isis_instance_redistribute_ipv4_destroy(struct nb_cb_destroy_args *args)  /*   * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map + * XPath: /frr-isisd:isis/instance/redistribute/ipv4/table/route-map   */  int isis_instance_redistribute_ipv4_route_map_modify(  	struct nb_cb_modify_args *args) @@ -1298,6 +1299,7 @@ int isis_instance_redistribute_ipv4_route_map_destroy(  /*   * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric + * XPath: /frr-isisd:isis/instance/redistribute/ipv4/table/metric   */  int isis_instance_redistribute_ipv4_metric_modify(  	struct nb_cb_modify_args *args) @@ -1306,6 +1308,28 @@ int isis_instance_redistribute_ipv4_metric_modify(  	return NB_OK;  } +int isis_instance_redistribute_ipv4_metric_destroy(struct nb_cb_destroy_args *args) +{ +	/* It's all done by redistribute_apply_finish */ +	return NB_OK; +} + +/* + * XPath: /frr-isisd:isis/instance/redistribute/ipv4/table + */ +int isis_instance_redistribute_ipv4_table_create(struct nb_cb_create_args *args) +{ +	if (args->event != NB_EV_APPLY) +		return NB_OK; + +	/* TODO */ +	return NB_OK; +} +int isis_instance_redistribute_ipv4_table_destroy(struct nb_cb_destroy_args *args) +{ +	return NB_OK; +} +  /*   * XPath: /frr-isisd:isis/instance/redistribute/ipv6   */ @@ -1358,6 +1382,33 @@ int isis_instance_redistribute_ipv6_metric_modify(  	return NB_OK;  } +int isis_instance_redistribute_ipv6_metric_destroy(struct nb_cb_destroy_args *args) +{ +	/* It's all done by redistribute_apply_finish */ +	return NB_OK; +} + +/* + * XPath: /frr-isisd:isis/instance/redistribute/ipv6/table + */ +int isis_instance_redistribute_ipv6_table_create(struct nb_cb_create_args *args) +{ +	if (args->event != NB_EV_APPLY) +		return NB_OK; + +	/* TODO */ +	return NB_OK; +} + +int isis_instance_redistribute_ipv6_table_destroy(struct nb_cb_destroy_args *args) +{ +	if (args->event != NB_EV_APPLY) +		return NB_OK; + +	/* TODO */ +	return NB_OK; +} +  /*   * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast   */ diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c index 6a822f02fe..2b3facc436 100644 --- a/isisd/isis_redist.c +++ b/isisd/isis_redist.c @@ -206,6 +206,53 @@ static void isis_redist_ensure_default(struct isis *isis, int family)  	info->metric = MAX_WIDE_PATH_METRIC;  } +static int _isis_redist_table_is_present(const struct lyd_node *dnode, void *arg) +{ +	struct isis_redist_table_present_args *rtda = arg; + +	/* This entry is the caller, so skip it. */ +	if (yang_dnode_get_uint16(dnode, "table") != +	    (uint16_t)atoi(rtda->rtda_table)) +		return YANG_ITER_CONTINUE; + +	/* found */ +	rtda->rtda_found = true; +	return YANG_ITER_CONTINUE; +} + +static int _isis_redist_table_get_first_cb(const struct lyd_node *dnode, +					   void *arg) +{ +	uint16_t *table = arg; + +	*table = yang_dnode_get_uint16(dnode, "table"); +	return YANG_ITER_STOP; +} + +uint16_t isis_redist_table_get_first(const struct vty *vty, +				     struct isis_redist_table_present_args *rtda) +{ +	uint16_t table = 0; + +	yang_dnode_iterate(_isis_redist_table_get_first_cb, &table, +			   vty->candidate_config->dnode, +			   "%s/redistribute/%s[protocol='table'][level='%s']/table", +			   VTY_CURR_XPATH, rtda->rtda_ip, rtda->rtda_level); +	return table; +} + +bool isis_redist_table_is_present(const struct vty *vty, +				  struct isis_redist_table_present_args *rtda) +{ +	rtda->rtda_found = false; +	yang_dnode_iterate(_isis_redist_table_is_present, rtda, +			   vty->candidate_config->dnode, +			   "%s/redistribute/%s[protocol='table'][level='%s']/table", +			   VTY_CURR_XPATH, rtda->rtda_ip, rtda->rtda_level); + +	return rtda->rtda_found; +} +  /* Handle notification about route being added */  void isis_redist_add(struct isis *isis, int type, struct prefix *p,  		     struct prefix_ipv6 *src_p, uint8_t distance, diff --git a/isisd/isis_redist.h b/isisd/isis_redist.h index ae5ec2b3b3..eb82f3083a 100644 --- a/isisd/isis_redist.h +++ b/isisd/isis_redist.h @@ -28,6 +28,14 @@ struct isis_redist {  	struct route_map *map;  }; +struct isis_redist_table_present_args { +	/* from filter.h, struct acl_dup_args */ +	const char *rtda_ip; +	const char *rtda_level; +	const char *rtda_table; +	bool rtda_found; +}; +  struct isis;  struct isis_area;  struct prefix; @@ -53,4 +61,9 @@ void isis_redist_set(struct isis_area *area, int level, int family, int type,  void isis_redist_unset(struct isis_area *area, int level, int family, int type);  void isis_redist_free(struct isis *isis); + +bool isis_redist_table_is_present(const struct vty *vty, +				  struct isis_redist_table_present_args *rtda); +uint16_t isis_redist_table_get_first(const struct vty *vty, +				     struct isis_redist_table_present_args *rtda);  #endif  | 
