From db2038c7827f4214059481b0551c98d65178cef5 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 29 Nov 2018 03:06:38 -0200 Subject: [PATCH] ripngd: retrofit the 'redistribute' commands to the new northbound model Trivial conversion. As usual, combine multiple DEFUNs into a single DEFPY for simplicity. As a bonus of the northbound conversion, this commit fixes the redistribution of certain protocols into ripngd. The 'redist_type' array used by the "redistribute" commands was terribly outdated, which was preventing the CLI to parse correctly certain protocols like isis and babel. Signed-off-by: Renato Westphal --- ripngd/ripng_cli.c | 44 +++++++ ripngd/ripng_cli.h | 2 + ripngd/ripng_northbound.c | 73 ++++++++++- ripngd/ripng_zebra.c | 251 +++----------------------------------- ripngd/ripngd.c | 4 +- ripngd/ripngd.h | 8 +- 6 files changed, 137 insertions(+), 245 deletions(-) diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index 7d90867f1..f7c4514d0 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -269,6 +269,49 @@ void cli_show_ripng_passive_interface(struct vty *vty, struct lyd_node *dnode, yang_dnode_get_string(dnode, NULL)); } +/* + * XPath: /frr-ripngd:ripngd/instance/redistribute + */ +DEFPY (ripng_redistribute, + ripng_redistribute_cmd, + "[no] redistribute " FRR_REDIST_STR_RIPNGD "$protocol [{metric (0-16)|route-map WORD}]", + NO_STR + REDIST_STR + FRR_REDIST_HELP_STR_RIPNGD + "Metric\n" + "Metric value\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + if (!no) { + 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); + nb_cli_enqueue_change(vty, "./metric", + metric_str ? NB_OP_MODIFY : NB_OP_DELETE, + metric_str); + } else + nb_cli_enqueue_change(vty, ".", NB_OP_DELETE, NULL); + + return nb_cli_apply_changes(vty, "./redistribute[protocol='%s']", + protocol); +} + +void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " redistribute %s", + yang_dnode_get_string(dnode, "./protocol")); + if (yang_dnode_exists(dnode, "./metric")) + vty_out(vty, " metric %s", + yang_dnode_get_string(dnode, "./metric")); + 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 ripng_cli_init(void) { install_element(CONFIG_NODE, &router_ripng_cmd); @@ -282,4 +325,5 @@ void ripng_cli_init(void) install_element(RIPNG_NODE, &ripng_network_if_cmd); install_element(RIPNG_NODE, &ripng_offset_list_cmd); install_element(RIPNG_NODE, &ripng_passive_interface_cmd); + install_element(RIPNG_NODE, &ripng_redistribute_cmd); } diff --git a/ripngd/ripng_cli.h b/ripngd/ripng_cli.h index eef3cc248..dd782423f 100644 --- a/ripngd/ripng_cli.h +++ b/ripngd/ripng_cli.h @@ -42,5 +42,7 @@ extern void cli_show_ripng_offset_list(struct vty *vty, struct lyd_node *dnode, extern void cli_show_ripng_passive_interface(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +extern void cli_show_ripng_redistribute(struct vty *vty, struct lyd_node *dnode, + bool show_defaults); #endif /* _FRR_RIPNG_CLI_H_ */ diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c index 0b2948b5d..5c83b0990 100644 --- a/ripngd/ripng_northbound.c +++ b/ripngd/ripng_northbound.c @@ -328,17 +328,33 @@ static int ripngd_instance_redistribute_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { - /* TODO: implement me. */ return NB_OK; } static int ripngd_instance_redistribute_delete(enum nb_event event, const struct lyd_node *dnode) { - /* TODO: implement me. */ + int type; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "./protocol"); + + ripng_redistribute_conf_delete(type); + return NB_OK; } +static void +ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode) +{ + int type; + + type = yang_dnode_get_enum(dnode, "./protocol"); + ripng_redistribute_conf_update(type); +} + /* * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map */ @@ -347,7 +363,20 @@ ripngd_instance_redistribute_route_map_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { - /* TODO: implement me. */ + int type; + const char *rmap_name; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + rmap_name = yang_dnode_get_string(dnode, NULL); + + if (ripng->route_map[type].name) + free(ripng->route_map[type].name); + ripng->route_map[type].name = strdup(rmap_name); + ripng->route_map[type].map = route_map_lookup_by_name(rmap_name); + return NB_OK; } @@ -355,7 +384,17 @@ static int ripngd_instance_redistribute_route_map_delete(enum nb_event event, const struct lyd_node *dnode) { - /* TODO: implement me. */ + int type; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + + free(ripng->route_map[type].name); + ripng->route_map[type].name = NULL; + ripng->route_map[type].map = NULL; + return NB_OK; } @@ -367,7 +406,18 @@ ripngd_instance_redistribute_metric_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { - /* TODO: implement me. */ + int type; + uint8_t metric; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + metric = yang_dnode_get_uint8(dnode, NULL); + + ripng->route_map[type].metric_config = true; + ripng->route_map[type].metric = metric; + return NB_OK; } @@ -375,7 +425,16 @@ static int ripngd_instance_redistribute_metric_delete(enum nb_event event, const struct lyd_node *dnode) { - /* TODO: implement me. */ + int type; + + if (event != NB_EV_APPLY) + return NB_OK; + + type = yang_dnode_get_enum(dnode, "../protocol"); + + ripng->route_map[type].metric_config = false; + ripng->route_map[type].metric = 0; + return NB_OK; } @@ -676,6 +735,8 @@ const struct frr_yang_module_info frr_ripngd_info = { .xpath = "/frr-ripngd:ripngd/instance/redistribute", .cbs.create = ripngd_instance_redistribute_create, .cbs.delete = ripngd_instance_redistribute_delete, + .cbs.apply_finish = ripngd_instance_redistribute_apply_finish, + .cbs.cli_show = cli_show_ripng_redistribute, }, { .xpath = "/frr-ripngd:ripngd/instance/redistribute/route-map", diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index f2b69c85a..063b53cda 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -146,21 +146,19 @@ void ripng_zclient_reset(void) zclient_reset(zclient); } -static int ripng_redistribute_unset(int type) +void ripng_redistribute_conf_update(int type) { + zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, + VRF_DEFAULT); +} - if (!vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT)) - return CMD_SUCCESS; - - vrf_bitmap_set(zclient->redist[AFI_IP6][type], VRF_DEFAULT); - +void ripng_redistribute_conf_delete(int type) +{ if (zclient->sock > 0) zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT); ripng_redistribute_withdraw(type); - - return CMD_SUCCESS; } int ripng_redistribute_check(int type) @@ -168,206 +166,25 @@ int ripng_redistribute_check(int type) return vrf_bitmap_check(zclient->redist[AFI_IP6][type], VRF_DEFAULT); } -static void ripng_redistribute_metric_set(int type, int metric) -{ - ripng->route_map[type].metric_config = 1; - ripng->route_map[type].metric = metric; -} - -static int ripng_redistribute_metric_unset(int type) -{ - ripng->route_map[type].metric_config = 0; - ripng->route_map[type].metric = 0; - return 0; -} - -static void ripng_redistribute_routemap_set(int type, const char *name) -{ - if (ripng->route_map[type].name) - free(ripng->route_map[type].name); - - ripng->route_map[type].name = strdup(name); - ripng->route_map[type].map = route_map_lookup_by_name(name); -} - -static void ripng_redistribute_routemap_unset(int type) -{ - if (ripng->route_map[type].name) - free(ripng->route_map[type].name); - - ripng->route_map[type].name = NULL; - ripng->route_map[type].map = NULL; -} - -/* Redistribution types */ -static struct { - int type; - int str_min_len; - const char *str; -} redist_type[] = {{ZEBRA_ROUTE_KERNEL, 1, "kernel"}, - {ZEBRA_ROUTE_CONNECT, 1, "connected"}, - {ZEBRA_ROUTE_STATIC, 1, "static"}, - {ZEBRA_ROUTE_OSPF6, 1, "ospf6"}, - {ZEBRA_ROUTE_BGP, 2, "bgp"}, - {ZEBRA_ROUTE_VNC, 1, "vnc"}, - {0, 0, NULL}}; - void ripng_redistribute_clean() { - int i; - - for (i = 0; redist_type[i].str; i++) { - if (vrf_bitmap_check( - zclient->redist[AFI_IP6][redist_type[i].type], - VRF_DEFAULT)) { - if (zclient->sock > 0) - zebra_redistribute_send( - ZEBRA_REDISTRIBUTE_DELETE, zclient, - AFI_IP6, redist_type[i].type, 0, - VRF_DEFAULT); - - vrf_bitmap_unset( - zclient->redist[AFI_IP6][redist_type[i].type], - VRF_DEFAULT); - - /* Remove the routes from RIPng table. */ - ripng_redistribute_withdraw(redist_type[i].type); - } - } -} - -DEFUN (ripng_redistribute_type, - ripng_redistribute_type_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD, - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD) -{ - int type; - - char *proto = argv[argc - 1]->text; - type = proto_redistnum(AFI_IP6, proto); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; -} - -DEFUN (no_ripng_redistribute_type, - no_ripng_redistribute_type_cmd, - "no redistribute " FRR_REDIST_STR_RIPNGD " [metric (0-16)] [route-map WORD]", - NO_STR - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Metric\n" - "Metric value\n" - "Route map reference\n" - "Pointer to route-map entries\n") -{ - int type; - - char *proto = argv[2]->text; - type = proto_redistnum(AFI_IP6, proto); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", proto); - return CMD_WARNING_CONFIG_FAILED; - } - - ripng_redistribute_metric_unset(type); - ripng_redistribute_routemap_unset(type); - return ripng_redistribute_unset(type); -} - - -DEFUN (ripng_redistribute_type_metric, - ripng_redistribute_type_metric_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16)", - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Metric\n" - "Metric value\n") -{ - int idx_protocol = 1; - int idx_number = 3; - int type; - int metric; - - metric = atoi(argv[idx_number]->arg); - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); - return CMD_WARNING_CONFIG_FAILED; - } - - ripng_redistribute_metric_set(type, metric); - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; -} - -DEFUN (ripng_redistribute_type_routemap, - ripng_redistribute_type_routemap_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD " route-map WORD", - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Route map reference\n" - "Pointer to route-map entries\n") -{ - int idx_protocol = 1; - int idx_word = 3; - int type; - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); + for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (!vrf_bitmap_check(zclient->redist[AFI_IP6][i], VRF_DEFAULT)) + continue; - if (type < 0) { - vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); - return CMD_WARNING_CONFIG_FAILED; - } + if (zclient->sock > 0) + zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, + zclient, AFI_IP6, i, 0, + VRF_DEFAULT); - ripng_redistribute_routemap_set(type, argv[idx_word]->text); - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; -} + vrf_bitmap_unset(zclient->redist[AFI_IP6][i], VRF_DEFAULT); -DEFUN (ripng_redistribute_type_metric_routemap, - ripng_redistribute_type_metric_routemap_cmd, - "redistribute " FRR_REDIST_STR_RIPNGD " metric (0-16) route-map WORD", - "Redistribute\n" - FRR_REDIST_HELP_STR_RIPNGD - "Metric\n" - "Metric value\n" - "Route map reference\n" - "Pointer to route-map entries\n") -{ - int idx_protocol = 1; - int idx_number = 3; - int idx_word = 5; - int type; - int metric; - - type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text); - metric = atoi(argv[idx_number]->arg); - - if (type < 0) { - vty_out(vty, "Invalid type %s\n", argv[idx_protocol]->text); - return CMD_WARNING_CONFIG_FAILED; + /* Remove the routes from RIP table. */ + ripng_redistribute_withdraw(i); } - - ripng_redistribute_metric_set(type, metric); - ripng_redistribute_routemap_set(type, argv[idx_word]->text); - zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6, type, 0, - VRF_DEFAULT); - return CMD_SUCCESS; } -void ripng_redistribute_write(struct vty *vty, int config_mode) +void ripng_redistribute_write(struct vty *vty) { int i; @@ -377,31 +194,7 @@ void ripng_redistribute_write(struct vty *vty, int config_mode) VRF_DEFAULT)) continue; - if (!config_mode) { - vty_out(vty, " %s", zebra_route_string(i)); - continue; - } - - if (ripng->route_map[i].metric_config) { - if (ripng->route_map[i].name) - vty_out(vty, - " redistribute %s metric %d route-map %s\n", - zebra_route_string(i), - ripng->route_map[i].metric, - ripng->route_map[i].name); - else - vty_out(vty, " redistribute %s metric %d\n", - zebra_route_string(i), - ripng->route_map[i].metric); - } else { - if (ripng->route_map[i].name) - vty_out(vty, " redistribute %s route-map %s\n", - zebra_route_string(i), - ripng->route_map[i].name); - else - vty_out(vty, " redistribute %s\n", - zebra_route_string(i)); - } + vty_out(vty, " %s", zebra_route_string(i)); } } @@ -426,14 +219,6 @@ void zebra_init(struct thread_master *master) zclient->interface_address_delete = ripng_interface_address_delete; zclient->redistribute_route_add = ripng_zebra_read_route; zclient->redistribute_route_del = ripng_zebra_read_route; - - /* Install command elements to ripng node */ - install_element(RIPNG_NODE, &ripng_redistribute_type_cmd); - install_element(RIPNG_NODE, &ripng_redistribute_type_routemap_cmd); - install_element(RIPNG_NODE, &ripng_redistribute_type_metric_cmd); - install_element(RIPNG_NODE, - &ripng_redistribute_type_metric_routemap_cmd); - install_element(RIPNG_NODE, &no_ripng_redistribute_type_cmd); } void ripng_zebra_stop(void) diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 19be43703..7cb18c5f6 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2081,7 +2081,7 @@ DEFUN (show_ipv6_ripng_status, /* Redistribute information. */ vty_out(vty, " Redistributing:"); - ripng_redistribute_write(vty, 0); + ripng_redistribute_write(vty); vty_out(vty, "\n"); vty_out(vty, " Default version control: send version %d,", @@ -2522,8 +2522,6 @@ static int ripng_config_write(struct vty *vty) if (dnode) { nb_cli_show_dnode_cmds(vty, dnode, false); - ripng_redistribute_write(vty, 1); - /* RIPng aggregate routes. */ for (rp = agg_route_top(ripng->aggregate); rp; rp = agg_route_next(rp)) diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index 78215d0ed..f18c9758e 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -136,8 +136,8 @@ struct ripng { struct { char *name; struct route_map *map; - int metric_config; - uint32_t metric; + bool metric_config; + uint8_t metric; } route_map[ZEBRA_ROUTE_MAX]; }; @@ -366,6 +366,8 @@ extern void ripng_terminate(void); extern void zebra_init(struct thread_master *); extern void ripng_zebra_stop(void); extern void ripng_zclient_reset(void); +extern void ripng_redistribute_conf_update(int type); +extern void ripng_redistribute_conf_delete(int type); extern void ripng_peer_init(void); extern void ripng_peer_update(struct sockaddr_in6 *, uint8_t); @@ -405,7 +407,7 @@ extern void ripng_zebra_ipv6_delete(struct agg_node *node); extern void ripng_redistribute_clean(void); extern int ripng_redistribute_check(int); -extern void ripng_redistribute_write(struct vty *, int); +extern void ripng_redistribute_write(struct vty *); extern int ripng_write_rte(int num, struct stream *s, struct prefix_ipv6 *p, struct in6_addr *nexthop, uint16_t tag, -- 2.39.5