summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmanuele Di Pascale <emanuele@voltanet.io>2018-11-14 12:12:32 +0100
committerEmanuele Di Pascale <emanuele@voltanet.io>2018-12-18 15:23:49 +0100
commit8b104c10640892c645d34091fc1b13d98f99784d (patch)
tree53c2cece5902324e51896fbadc9dcec5d2ff9402
parentd1a80ef66012dfd858699d29af5addab73e454a8 (diff)
isisd: retrofit the 'default-originate' command
Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
-rw-r--r--isisd/isis_cli.c84
-rw-r--r--isisd/isis_cli.h4
-rw-r--r--isisd/isis_northbound.c90
-rw-r--r--isisd/isis_redist.c49
-rw-r--r--isisd/isis_redist.h4
5 files changed, 178 insertions, 53 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index fd309e6244..b2948de1ce 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -962,6 +962,88 @@ DEFPY(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd,
return CMD_SUCCESS;
}
+/*
+ * XPath: /frr-isisd:isis/instance/default-information-originate
+ */
+DEFPY(isis_default_originate, isis_default_originate_cmd,
+ "[no] default-information originate <ipv4|ipv6>$ip"
+ " <level-1|level-2>$level [always]$always"
+ " [<metric (0-16777215)$metric|route-map WORD$rmap>]",
+ NO_STR
+ "Control distribution of default information\n"
+ "Distribute a default route\n"
+ "Distribute default route for IPv4\n"
+ "Distribute default route for IPv6\n"
+ "Distribute default route into level-1\n"
+ "Distribute default route into level-2\n"
+ "Always advertise default route\n"
+ "Metric for default route\n"
+ "ISIS default metric\n"
+ "Route map reference\n"
+ "Pointer to route-map entries\n")
+{
+ if (no)
+ nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL);
+ else {
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+ nb_cli_enqueue_change(vty, "./always",
+ always ? NB_OP_CREATE : NB_OP_DELETE,
+ NULL);
+ nb_cli_enqueue_change(vty, "./route-map",
+ rmap ? NB_OP_MODIFY : NB_OP_DELETE,
+ rmap ? rmap : NULL);
+ nb_cli_enqueue_change(vty, "./metric",
+ metric ? NB_OP_MODIFY : NB_OP_DELETE,
+ metric ? metric_str : NULL);
+ if (strmatch(ip, "ipv6") && !always) {
+ vty_out(vty,
+ "Zebra doesn't implement default-originate for IPv6 yet\n");
+ vty_out(vty,
+ "so use with care or use default-originate always.\n");
+ }
+ }
+
+ return nb_cli_apply_changes(
+ vty, "./default-information-originate/%s[level='%s']", ip,
+ level);
+}
+
+static void vty_print_def_origin(struct vty *vty, struct lyd_node *dnode,
+ const char *family, const char *level, bool show_defaults)
+{
+ const char *metric;
+
+ vty_out(vty, " default-information originate %s %s", family, level);
+ if (yang_dnode_exists(dnode, "./always"))
+ vty_out(vty, " always");
+
+ if (yang_dnode_exists(dnode, "./route-map"))
+ vty_out(vty, " route-map %s",
+ yang_dnode_get_string(dnode, "./route-map"));
+ else if (yang_dnode_exists(dnode, "./metric")) {
+ metric = yang_dnode_get_string(dnode, "./metric");
+ if (show_defaults || !yang_dnode_is_default(dnode, "./metric"))
+ vty_out(vty, " metric %s", metric);
+ }
+ vty_out(vty, "\n");
+}
+
+void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ const char *level = yang_dnode_get_string(dnode, "./level");
+
+ vty_print_def_origin(vty, dnode, "ipv4", level, show_defaults);
+}
+
+void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ const char *level = yang_dnode_get_string(dnode, "./level");
+
+ vty_print_def_origin(vty, dnode, "ipv6", level, show_defaults);
+}
+
void isis_cli_init(void)
{
install_element(CONFIG_NODE, &router_isis_cmd);
@@ -1008,6 +1090,8 @@ void isis_cli_init(void)
install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd);
install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd);
install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd);
+
+ install_element(ISIS_NODE, &isis_default_originate_cmd);
}
#endif /* ifndef FABRICD */
diff --git a/isisd/isis_cli.h b/isisd/isis_cli.h
index d28302a71d..3cd4f3e4ad 100644
--- a/isisd/isis_cli.h
+++ b/isisd/isis_cli.h
@@ -61,5 +61,9 @@ void cli_show_isis_mpls_te(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
void cli_show_isis_mpls_te_router_addr(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
+void cli_show_isis_def_origin_ipv4(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
#endif /* ISISD_ISIS_CLI_H_ */
diff --git a/isisd/isis_northbound.c b/isisd/isis_northbound.c
index 43e2639b1b..e5ddadb44f 100644
--- a/isisd/isis_northbound.c
+++ b/isisd/isis_northbound.c
@@ -845,18 +845,63 @@ static int isis_instance_domain_password_authenticate_snp_modify(
/*
* XPath: /frr-isisd:isis/instance/default-information-originate/ipv4
*/
+static void default_info_origin_apply_finish(const struct lyd_node *dnode,
+ int family)
+{
+ int originate_type = DEFAULT_ORIGINATE;
+ unsigned long metric = 0;
+ const char *routemap = NULL;
+ struct isis_area *area = yang_dnode_get_entry(dnode, true);
+ int level = yang_dnode_get_enum(dnode, "./level");
+
+ if (yang_dnode_exists(dnode, "./always")) {
+ originate_type = DEFAULT_ORIGINATE_ALWAYS;
+ } else if (family == AF_INET6) {
+ zlog_warn(
+ "%s: Zebra doesn't implement default-originate for IPv6 yet, so use with care or use default-originate always.",
+ __func__);
+ }
+
+ if (yang_dnode_exists(dnode, "./metric"))
+ metric = yang_dnode_get_uint32(dnode, "./metric");
+ else if (yang_dnode_exists(dnode, "./route-map"))
+ routemap = yang_dnode_get_string(dnode, "./route-map");
+
+ isis_redist_set(area, level, family, DEFAULT_ROUTE, metric, routemap,
+ originate_type);
+}
+
+static void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode)
+{
+ default_info_origin_apply_finish(dnode, AF_INET);
+}
+
+static void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode)
+{
+ default_info_origin_apply_finish(dnode, AF_INET6);
+}
+
static int isis_instance_default_information_originate_ipv4_create(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv4_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ struct isis_area *area;
+ int level;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ area = yang_dnode_get_entry(dnode, true);
+ level = yang_dnode_get_enum(dnode, "./level");
+ isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE);
+
return NB_OK;
}
@@ -867,14 +912,14 @@ static int isis_instance_default_information_originate_ipv4_always_create(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv4_always_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
@@ -885,14 +930,14 @@ static int isis_instance_default_information_originate_ipv4_route_map_modify(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv4_route_map_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
@@ -903,14 +948,14 @@ static int isis_instance_default_information_originate_ipv4_metric_modify(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv4_metric_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
@@ -921,14 +966,23 @@ static int isis_instance_default_information_originate_ipv6_create(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv6_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ struct isis_area *area;
+ int level;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ area = yang_dnode_get_entry(dnode, true);
+ level = yang_dnode_get_enum(dnode, "./level");
+ isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE);
+
return NB_OK;
}
@@ -939,14 +993,14 @@ static int isis_instance_default_information_originate_ipv6_always_create(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv6_always_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
@@ -957,14 +1011,14 @@ static int isis_instance_default_information_originate_ipv6_route_map_modify(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv6_route_map_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
@@ -975,14 +1029,14 @@ static int isis_instance_default_information_originate_ipv6_metric_modify(
enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
static int isis_instance_default_information_originate_ipv6_metric_delete(
enum nb_event event, const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by default_info_origin_apply_finish */
return NB_OK;
}
@@ -2202,6 +2256,8 @@ const struct frr_yang_module_info frr_isisd_info = {
.xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4",
.cbs.create = isis_instance_default_information_originate_ipv4_create,
.cbs.delete = isis_instance_default_information_originate_ipv4_delete,
+ .cbs.apply_finish = default_info_origin_ipv4_apply_finish,
+ .cbs.cli_show = cli_show_isis_def_origin_ipv4,
},
{
.xpath = "/frr-isisd:isis/instance/default-information-originate/ipv4/always",
@@ -2222,6 +2278,8 @@ const struct frr_yang_module_info frr_isisd_info = {
.xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6",
.cbs.create = isis_instance_default_information_originate_ipv6_create,
.cbs.delete = isis_instance_default_information_originate_ipv6_delete,
+ .cbs.apply_finish = default_info_origin_ipv6_apply_finish,
+ .cbs.cli_show = cli_show_isis_def_origin_ipv6,
},
{
.xpath = "/frr-isisd:isis/instance/default-information-originate/ipv6/always",
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index 6564149a43..71540e9e0b 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -388,9 +388,8 @@ static void isis_redist_update_zebra_subscriptions(struct isis *isis)
}
}
-static void isis_redist_set(struct isis_area *area, int level, int family,
- int type, uint32_t metric, const char *routemap,
- int originate_type)
+void isis_redist_set(struct isis_area *area, int level, int family, int type,
+ uint32_t metric, const char *routemap, int originate_type)
{
int protocol = redist_protocol(family);
struct isis_redist *redist =
@@ -445,8 +444,7 @@ static void isis_redist_set(struct isis_area *area, int level, int family,
}
}
-static void isis_redist_unset(struct isis_area *area, int level, int family,
- int type)
+void isis_redist_unset(struct isis_area *area, int level, int family, int type)
{
struct isis_redist *redist =
get_redist_settings(area, family, type, level);
@@ -638,21 +636,15 @@ DEFUN (no_isis_redistribute,
return 0;
}
+#ifdef FABRICD
DEFUN (isis_default_originate,
isis_default_originate_cmd,
"default-information originate <ipv4|ipv6>"
-#ifndef FABRICD
- " <level-1|level-2>"
-#endif
" [always] [<metric (0-16777215)|route-map WORD>]",
"Control distribution of default information\n"
"Distribute a default route\n"
"Distribute default route for IPv4\n"
"Distribute default route for IPv6\n"
-#ifndef FABRICD
- "Distribute default route into level-1\n"
- "Distribute default route into level-2\n"
-#endif
"Always advertise default route\n"
"Metric for default route\n"
"ISIS default metric\n"
@@ -660,7 +652,6 @@ DEFUN (isis_default_originate,
"Pointer to route-map entries\n")
{
int idx_afi = 2;
- int idx_level = 3;
int idx_always = fabricd ? 3 : 4;
int idx_metric_rmap = fabricd ? 3 : 4;
VTY_DECLVAR_CONTEXT(isis_area, area);
@@ -674,10 +665,7 @@ DEFUN (isis_default_originate,
if (family < 0)
return CMD_WARNING_CONFIG_FAILED;
- if (fabricd)
- level = 2;
- else
- level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
+ level = 2;
if ((area->is_type & level) != level) {
vty_out(vty, "Node is not a level-%d IS\n", level);
@@ -711,23 +699,14 @@ DEFUN (isis_default_originate,
DEFUN (no_isis_default_originate,
no_isis_default_originate_cmd,
- "no default-information originate <ipv4|ipv6>"
-#ifndef FABRICD
- " <level-1|level-2>"
-#endif
- , NO_STR
+ "no default-information originate <ipv4|ipv6>",
+ NO_STR
"Control distribution of default information\n"
"Distribute a default route\n"
"Distribute default route for IPv4\n"
- "Distribute default route for IPv6\n"
-#ifndef FABRICD
- "Distribute default route into level-1\n"
- "Distribute default route into level-2\n"
-#endif
- )
+ "Distribute default route for IPv6\n")
{
int idx_afi = 3;
- int idx_level = 4;
VTY_DECLVAR_CONTEXT(isis_area, area);
int family;
int level;
@@ -736,18 +715,12 @@ DEFUN (no_isis_default_originate,
if (family < 0)
return CMD_WARNING_CONFIG_FAILED;
- if (fabricd)
- level = 2;
- else if (strmatch("level-1", argv[idx_level]->text))
- level = 1;
- else if (strmatch("level-2", argv[idx_level]->text))
- level = 2;
- else
- return CMD_WARNING_CONFIG_FAILED;
+ level = 2;
isis_redist_unset(area, level, family, DEFAULT_ROUTE);
return 0;
}
+#endif /* ifdef FABRICD */
int isis_redist_config_write(struct vty *vty, struct isis_area *area,
int family)
@@ -812,6 +785,8 @@ void isis_redist_init(void)
{
install_element(ROUTER_NODE, &isis_redistribute_cmd);
install_element(ROUTER_NODE, &no_isis_redistribute_cmd);
+#ifdef FABRICD
install_element(ROUTER_NODE, &isis_default_originate_cmd);
install_element(ROUTER_NODE, &no_isis_default_originate_cmd);
+#endif /* ifdef FABRICD */
}
diff --git a/isisd/isis_redist.h b/isisd/isis_redist.h
index 95f06f71ec..9c37c310ea 100644
--- a/isisd/isis_redist.h
+++ b/isisd/isis_redist.h
@@ -55,4 +55,8 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
void isis_redist_init(void);
void isis_redist_area_finish(struct isis_area *area);
+void isis_redist_set(struct isis_area *area, int level, int family, int type,
+ uint32_t metric, const char *routemap, int originate_type);
+void isis_redist_unset(struct isis_area *area, int level, int family, int type);
+
#endif