summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmanuele Di Pascale <emanuele@voltanet.io>2018-11-14 12:19:33 +0100
committerEmanuele Di Pascale <emanuele@voltanet.io>2018-12-18 15:23:49 +0100
commita041ac8ef6404602c96599c6546e3fbc4f4fc85a (patch)
tree438002a5c4443f46d31117f553139aae5d7748a1
parent8b104c10640892c645d34091fc1b13d98f99784d (diff)
isisd: retrofit the 'redistribute' command
Signed-off-by: Emanuele Di Pascale <emanuele@voltanet.io>
-rw-r--r--isisd/isis_cli.c63
-rw-r--r--isisd/isis_cli.h4
-rw-r--r--isisd/isis_northbound.c78
-rw-r--r--isisd/isis_redist.c42
4 files changed, 141 insertions, 46 deletions
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index b2948de1ce..92e700ca46 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -1044,6 +1044,68 @@ void cli_show_isis_def_origin_ipv6(struct vty *vty, struct lyd_node *dnode,
vty_print_def_origin(vty, dnode, "ipv6", level, show_defaults);
}
+/*
+ * XPath: /frr-isisd:isis/instance/redistribute
+ */
+DEFPY(isis_redistribute, isis_redistribute_cmd,
+ "[no] redistribute <ipv4|ipv6>$ip " PROTO_REDIST_STR
+ "$proto"
+ " <level-1|level-2>$level"
+ " [<metric (0-16777215)|route-map WORD>]",
+ NO_STR REDIST_STR
+ "Redistribute IPv4 routes\n"
+ "Redistribute IPv6 routes\n" PROTO_REDIST_HELP
+ "Redistribute into level-1\n"
+ "Redistribute into level-2\n"
+ "Metric for redistributed routes\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, "./route-map",
+ route_map ? NB_OP_MODIFY : NB_OP_DELETE,
+ route_map ? route_map : NULL);
+ nb_cli_enqueue_change(vty, "./metric",
+ metric ? NB_OP_MODIFY : NB_OP_DELETE,
+ metric ? metric_str : NULL);
+ }
+
+ return nb_cli_apply_changes(
+ vty, "./redistribute/%s[protocol='%s'][level='%s']", ip, proto,
+ level);
+}
+
+static void vty_print_redistribute(struct vty *vty, struct lyd_node *dnode,
+ const char *family)
+{
+ const char *level = yang_dnode_get_string(dnode, "./level");
+ const char *protocol = yang_dnode_get_string(dnode, "./protocol");
+
+ vty_out(vty, " redistribute %s %s %s", family, protocol, level);
+ if (yang_dnode_exists(dnode, "./metric"))
+ vty_out(vty, " metric %s",
+ yang_dnode_get_string(dnode, "./metric"));
+ else if (yang_dnode_exists(dnode, "./route-map"))
+ vty_out(vty, " route-map %s",
+ yang_dnode_get_string(dnode, "./route-map"));
+ vty_out(vty, "\n");
+}
+
+void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ vty_print_redistribute(vty, dnode, "ipv4");
+}
+void cli_show_isis_redistribute_ipv6(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ vty_print_redistribute(vty, dnode, "ipv6");
+}
+
void isis_cli_init(void)
{
install_element(CONFIG_NODE, &router_isis_cmd);
@@ -1092,6 +1154,7 @@ void isis_cli_init(void)
install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd);
install_element(ISIS_NODE, &isis_default_originate_cmd);
+ install_element(ISIS_NODE, &isis_redistribute_cmd);
}
#endif /* ifndef FABRICD */
diff --git a/isisd/isis_cli.h b/isisd/isis_cli.h
index 3cd4f3e4ad..3b06202b4e 100644
--- a/isisd/isis_cli.h
+++ b/isisd/isis_cli.h
@@ -65,5 +65,9 @@ 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);
+void cli_show_isis_redistribute_ipv4(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+void cli_show_isis_redistribute_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 e5ddadb44f..0d22e870cf 100644
--- a/isisd/isis_northbound.c
+++ b/isisd/isis_northbound.c
@@ -1043,18 +1043,58 @@ static int isis_instance_default_information_originate_ipv6_metric_delete(
/*
* XPath: /frr-isisd:isis/instance/redistribute/ipv4
*/
+static void redistribute_apply_finish(const struct lyd_node *dnode, int family)
+{
+ assert(family == AF_INET || family == AF_INET6);
+ int type, level;
+ unsigned long metric = 0;
+ const char *routemap = NULL;
+ struct isis_area *area;
+
+ type = yang_dnode_get_enum(dnode, "./protocol");
+ level = yang_dnode_get_enum(dnode, "./level");
+ area = yang_dnode_get_entry(dnode, true);
+
+ 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, type, metric, routemap, 0);
+}
+
+static void redistribute_ipv4_apply_finish(const struct lyd_node *dnode)
+{
+ redistribute_apply_finish(dnode, AF_INET);
+}
+
+static void redistribute_ipv6_apply_finish(const struct lyd_node *dnode)
+{
+ redistribute_apply_finish(dnode, AF_INET6);
+}
+
static int isis_instance_redistribute_ipv4_create(enum nb_event event,
const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
static int isis_instance_redistribute_ipv4_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ struct isis_area *area;
+ int level, type;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ area = yang_dnode_get_entry(dnode, true);
+ level = yang_dnode_get_enum(dnode, "./level");
+ type = yang_dnode_get_enum(dnode, "./protocol");
+ isis_redist_unset(area, level, AF_INET, type);
+
return NB_OK;
}
@@ -1066,7 +1106,7 @@ isis_instance_redistribute_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 redistribute_apply_finish */
return NB_OK;
}
@@ -1074,7 +1114,7 @@ static int
isis_instance_redistribute_ipv4_route_map_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
@@ -1086,7 +1126,7 @@ isis_instance_redistribute_ipv4_metric_modify(enum nb_event event,
const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
@@ -1094,7 +1134,7 @@ static int
isis_instance_redistribute_ipv4_metric_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
@@ -1105,14 +1145,24 @@ static int isis_instance_redistribute_ipv6_create(enum nb_event event,
const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
static int isis_instance_redistribute_ipv6_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ struct isis_area *area;
+ int level, type;
+
+ if (event != NB_EV_APPLY)
+ return NB_OK;
+
+ area = yang_dnode_get_entry(dnode, true);
+ level = yang_dnode_get_enum(dnode, "./level");
+ type = yang_dnode_get_enum(dnode, "./protocol");
+ isis_redist_unset(area, level, AF_INET6, type);
+
return NB_OK;
}
@@ -1124,7 +1174,7 @@ isis_instance_redistribute_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 redistribute_apply_finish */
return NB_OK;
}
@@ -1132,7 +1182,7 @@ static int
isis_instance_redistribute_ipv6_route_map_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
@@ -1144,7 +1194,7 @@ isis_instance_redistribute_ipv6_metric_modify(enum nb_event event,
const struct lyd_node *dnode,
union nb_resource *resource)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
@@ -1152,7 +1202,7 @@ static int
isis_instance_redistribute_ipv6_metric_delete(enum nb_event event,
const struct lyd_node *dnode)
{
- /* TODO: implement me. */
+ /* It's all done by redistribute_apply_finish */
return NB_OK;
}
@@ -2300,6 +2350,8 @@ const struct frr_yang_module_info frr_isisd_info = {
.xpath = "/frr-isisd:isis/instance/redistribute/ipv4",
.cbs.create = isis_instance_redistribute_ipv4_create,
.cbs.delete = isis_instance_redistribute_ipv4_delete,
+ .cbs.apply_finish = redistribute_ipv4_apply_finish,
+ .cbs.cli_show = cli_show_isis_redistribute_ipv4,
},
{
.xpath = "/frr-isisd:isis/instance/redistribute/ipv4/route-map",
@@ -2315,6 +2367,8 @@ const struct frr_yang_module_info frr_isisd_info = {
.xpath = "/frr-isisd:isis/instance/redistribute/ipv6",
.cbs.create = isis_instance_redistribute_ipv6_create,
.cbs.delete = isis_instance_redistribute_ipv6_delete,
+ .cbs.apply_finish = redistribute_ipv6_apply_finish,
+ .cbs.cli_show = cli_show_isis_redistribute_ipv6,
},
{
.xpath = "/frr-isisd:isis/instance/redistribute/ipv6/route-map",
diff --git a/isisd/isis_redist.c b/isisd/isis_redist.c
index 71540e9e0b..815de513fc 100644
--- a/isisd/isis_redist.c
+++ b/isisd/isis_redist.c
@@ -511,21 +511,15 @@ void isis_redist_area_finish(struct isis_area *area)
isis_redist_update_zebra_subscriptions(area->isis);
}
+#ifdef FABRICD
DEFUN (isis_redistribute,
isis_redistribute_cmd,
"redistribute <ipv4|ipv6> " PROTO_REDIST_STR
-#ifndef FABRICD
- " <level-1|level-2>"
-#endif
" [<metric (0-16777215)|route-map WORD>]",
REDIST_STR
"Redistribute IPv4 routes\n"
"Redistribute IPv6 routes\n"
PROTO_REDIST_HELP
-#ifndef FABRICD
- "Redistribute into level-1\n"
- "Redistribute into level-2\n"
-#endif
"Metric for redistributed routes\n"
"ISIS default metric\n"
"Route map reference\n"
@@ -533,7 +527,6 @@ DEFUN (isis_redistribute,
{
int idx_afi = 1;
int idx_protocol = 2;
- int idx_level = 3;
int idx_metric_rmap = fabricd ? 3 : 4;
VTY_DECLVAR_CONTEXT(isis_area, area);
int family;
@@ -555,14 +548,7 @@ DEFUN (isis_redistribute,
if (type < 0)
return CMD_WARNING_CONFIG_FAILED;
- if (fabricd)
- level = 2;
- else if (!strcmp("level-1", argv[idx_level]->arg))
- level = 1;
- else if (!strcmp("level-2", argv[idx_level]->arg))
- level = 2;
- else
- return CMD_WARNING_CONFIG_FAILED;
+ level = 2;
if ((area->is_type & level) != level) {
vty_out(vty, "Node is not a level-%d IS\n", level);
@@ -591,24 +577,15 @@ DEFUN (isis_redistribute,
DEFUN (no_isis_redistribute,
no_isis_redistribute_cmd,
- "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR
-#ifndef FABRICD
- " <level-1|level-2>"
-#endif
- , NO_STR
+ "no redistribute <ipv4|ipv6> " PROTO_REDIST_STR,
+ NO_STR
REDIST_STR
"Redistribute IPv4 routes\n"
"Redistribute IPv6 routes\n"
- PROTO_REDIST_HELP
-#ifndef FABRICD
- "Redistribute into level-1\n"
- "Redistribute into level-2\n"
-#endif
- )
+ PROTO_REDIST_HELP)
{
int idx_afi = 2;
int idx_protocol = 3;
- int idx_level = 4;
VTY_DECLVAR_CONTEXT(isis_area, area);
int type;
int level;
@@ -627,16 +604,12 @@ DEFUN (no_isis_redistribute,
if (type < 0)
return CMD_WARNING_CONFIG_FAILED;
- if (fabricd)
- level = 2;
- else
- level = strmatch("level-1", argv[idx_level]->text) ? 1 : 2;
+ level = 2;
isis_redist_unset(area, level, family, type);
return 0;
}
-#ifdef FABRICD
DEFUN (isis_default_originate,
isis_default_originate_cmd,
"default-information originate <ipv4|ipv6>"
@@ -783,9 +756,10 @@ int isis_redist_config_write(struct vty *vty, struct isis_area *area,
void isis_redist_init(void)
{
+#ifdef FABRICD
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 */