From 8b104c10640892c645d34091fc1b13d98f99784d Mon Sep 17 00:00:00 2001 From: Emanuele Di Pascale Date: Wed, 14 Nov 2018 12:12:32 +0100 Subject: [PATCH] isisd: retrofit the 'default-originate' command Signed-off-by: Emanuele Di Pascale --- isisd/isis_cli.c | 84 ++++++++++++++++++++++++++++++++++++++ isisd/isis_cli.h | 4 ++ isisd/isis_northbound.c | 90 +++++++++++++++++++++++++++++++++-------- isisd/isis_redist.c | 49 ++++++---------------- isisd/isis_redist.h | 4 ++ 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 $ip" + " $level [always]$always" + " []", + 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 " -#ifndef FABRICD - " " -#endif " [always] []", "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 " -#ifndef FABRICD - " " -#endif - , NO_STR + "no default-information originate ", + 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 -- 2.39.5