From cc48702b20fa8a6d69e52c1770a741b755828a02 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Thu, 29 Nov 2018 01:45:02 -0200 Subject: [PATCH] ripngd: retrofit the 'network' command to the new northbound model The frr-ripngd YANG module models the ripngd "network" command using two separate leaf-lists for simplicity: one leaf-list for interfaces and another leaf-list for actual networks. In the 'cli_show' callbacks, display the "network" command for entries of both leaf-lists. Signed-off-by: Renato Westphal --- ripngd/ripng_cli.c | 46 +++++++++++++++++++++ ripngd/ripng_cli.h | 6 +++ ripngd/ripng_interface.c | 84 ++++++--------------------------------- ripngd/ripng_northbound.c | 44 ++++++++++++++++---- ripngd/ripngd.c | 2 - ripngd/ripngd.h | 4 ++ 6 files changed, 105 insertions(+), 81 deletions(-) diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index 5a1c9bdca2..53ff3fd061 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -159,6 +159,50 @@ void cli_show_ripng_default_metric(struct vty *vty, struct lyd_node *dnode, yang_dnode_get_string(dnode, NULL)); } +/* + * XPath: /frr-ripngd:ripngd/instance/network + */ +DEFPY (ripng_network_prefix, + ripng_network_prefix_cmd, + "[no] network X:X::X:X/M", + NO_STR + "RIPng enable on specified interface or network.\n" + "IPv6 network\n") +{ + nb_cli_enqueue_change(vty, "./network", + no ? NB_OP_DELETE : NB_OP_CREATE, network_str); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_network_prefix(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL)); +} + +/* + * XPath: /frr-ripngd:ripngd/instance/interface + */ +DEFPY (ripng_network_if, + ripng_network_if_cmd, + "[no] network WORD", + NO_STR + "RIPng enable on specified interface or network.\n" + "Interface name\n") +{ + nb_cli_enqueue_change(vty, "./interface", + no ? NB_OP_DELETE : NB_OP_CREATE, network); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_ripng_network_interface(struct vty *vty, struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL)); +} + void ripng_cli_init(void) { install_element(CONFIG_NODE, &router_ripng_cmd); @@ -168,4 +212,6 @@ void ripng_cli_init(void) install_element(RIPNG_NODE, &ripng_default_information_originate_cmd); install_element(RIPNG_NODE, &ripng_default_metric_cmd); install_element(RIPNG_NODE, &no_ripng_default_metric_cmd); + install_element(RIPNG_NODE, &ripng_network_prefix_cmd); + install_element(RIPNG_NODE, &ripng_network_if_cmd); } diff --git a/ripngd/ripng_cli.h b/ripngd/ripng_cli.h index 0cdbc2d6a1..144f0afa2b 100644 --- a/ripngd/ripng_cli.h +++ b/ripngd/ripng_cli.h @@ -31,5 +31,11 @@ extern void cli_show_ripng_default_information_originate(struct vty *vty, extern void cli_show_ripng_default_metric(struct vty *vty, struct lyd_node *dnode, bool show_defaults); +extern void cli_show_ripng_network_prefix(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); +extern void cli_show_ripng_network_interface(struct vty *vty, + struct lyd_node *dnode, + bool show_defaults); #endif /* _FRR_RIPNG_CLI_H_ */ diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index a1d25f2961..14ca3a5907 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -543,7 +543,7 @@ static int ripng_enable_network_lookup2(struct connected *connected) } /* Add RIPng enable network. */ -static int ripng_enable_network_add(struct prefix *p) +int ripng_enable_network_add(struct prefix *p) { struct agg_node *node; @@ -551,18 +551,18 @@ static int ripng_enable_network_add(struct prefix *p) if (node->info) { agg_unlock_node(node); - return -1; + return NB_ERR_INCONSISTENCY; } else node->info = (void *)1; /* XXX: One should find a better solution than a generic one */ ripng_enable_apply_all(); - return 1; + return NB_OK; } /* Delete RIPng enable network. */ -static int ripng_enable_network_delete(struct prefix *p) +int ripng_enable_network_delete(struct prefix *p) { struct agg_node *node; @@ -576,9 +576,10 @@ static int ripng_enable_network_delete(struct prefix *p) /* Unlock lookup lock. */ agg_unlock_node(node); - return 1; + return NB_OK; } - return -1; + + return NB_ERR_INCONSISTENCY; } /* Lookup function. */ @@ -595,30 +596,30 @@ static int ripng_enable_if_lookup(const char *ifname) } /* Add interface to ripng_enable_if. */ -static int ripng_enable_if_add(const char *ifname) +int ripng_enable_if_add(const char *ifname) { int ret; ret = ripng_enable_if_lookup(ifname); if (ret >= 0) - return -1; + return NB_ERR_INCONSISTENCY; vector_set(ripng_enable_if, strdup(ifname)); ripng_enable_apply_all(); - return 1; + return NB_OK; } /* Delete interface from ripng_enable_if. */ -static int ripng_enable_if_delete(const char *ifname) +int ripng_enable_if_delete(const char *ifname) { int index; char *str; index = ripng_enable_if_lookup(ifname); if (index < 0) - return -1; + return NB_ERR_INCONSISTENCY; str = vector_slot(ripng_enable_if, index); free(str); @@ -626,7 +627,7 @@ static int ripng_enable_if_delete(const char *ifname) ripng_enable_apply_all(); - return 1; + return NB_OK; } /* Wake up interface. */ @@ -909,63 +910,6 @@ int ripng_network_write(struct vty *vty, int config_mode) return 0; } -/* RIPng enable on specified interface or matched network. */ -DEFUN (ripng_network, - ripng_network_cmd, - "network IF_OR_ADDR", - "RIPng enable on specified interface or network.\n" - "Interface or address\n") -{ - int idx_if_or_addr = 1; - int ret; - struct prefix p; - - ret = str2prefix(argv[idx_if_or_addr]->arg, &p); - - /* Given string is IPv6 network or interface name. */ - if (ret) - ret = ripng_enable_network_add(&p); - else - ret = ripng_enable_if_add(argv[idx_if_or_addr]->arg); - - if (ret < 0) { - vty_out(vty, "There is same network configuration %s\n", - argv[idx_if_or_addr]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - -/* RIPng enable on specified interface or matched network. */ -DEFUN (no_ripng_network, - no_ripng_network_cmd, - "no network IF_OR_ADDR", - NO_STR - "RIPng enable on specified interface or network.\n" - "Interface or address\n") -{ - int idx_if_or_addr = 2; - int ret; - struct prefix p; - - ret = str2prefix(argv[idx_if_or_addr]->arg, &p); - - /* Given string is interface name. */ - if (ret) - ret = ripng_enable_network_delete(&p); - else - ret = ripng_enable_if_delete(argv[idx_if_or_addr]->arg); - - if (ret < 0) { - vty_out(vty, "can't find network %s\n", - argv[idx_if_or_addr]->arg); - return CMD_WARNING_CONFIG_FAILED; - } - - return CMD_SUCCESS; -} - DEFUN (ipv6_ripng_split_horizon, ipv6_ripng_split_horizon_cmd, "ipv6 ripng split-horizon", @@ -1138,8 +1082,6 @@ void ripng_if_init() install_node(&interface_node, interface_config_write); if_cmd_init(); - install_element(RIPNG_NODE, &ripng_network_cmd); - install_element(RIPNG_NODE, &no_ripng_network_cmd); install_element(RIPNG_NODE, &ripng_passive_interface_cmd); install_element(RIPNG_NODE, &no_ripng_passive_interface_cmd); diff --git a/ripngd/ripng_northbound.c b/ripngd/ripng_northbound.c index 7a7c14cebc..ff03e8a91a 100644 --- a/ripngd/ripng_northbound.c +++ b/ripngd/ripng_northbound.c @@ -140,15 +140,29 @@ static int ripngd_instance_network_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { - /* TODO: implement me. */ - return NB_OK; + struct prefix p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6((struct prefix_ipv6 *)&p); + + return ripng_enable_network_add(&p); } static int ripngd_instance_network_delete(enum nb_event event, const struct lyd_node *dnode) { - /* TODO: implement me. */ - return NB_OK; + struct prefix p; + + if (event != NB_EV_APPLY) + return NB_OK; + + yang_dnode_get_ipv6p(&p, dnode, NULL); + apply_mask_ipv6((struct prefix_ipv6 *)&p); + + return ripng_enable_network_delete(&p); } /* @@ -158,15 +172,27 @@ static int ripngd_instance_interface_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { - /* TODO: implement me. */ - return NB_OK; + const char *ifname; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifname = yang_dnode_get_string(dnode, NULL); + + return ripng_enable_if_add(ifname); } static int ripngd_instance_interface_delete(enum nb_event event, const struct lyd_node *dnode) { - /* TODO: implement me. */ - return NB_OK; + const char *ifname; + + if (event != NB_EV_APPLY) + return NB_OK; + + ifname = yang_dnode_get_string(dnode, NULL); + + return ripng_enable_if_delete(ifname); } /* @@ -554,11 +580,13 @@ const struct frr_yang_module_info frr_ripngd_info = { .xpath = "/frr-ripngd:ripngd/instance/network", .cbs.create = ripngd_instance_network_create, .cbs.delete = ripngd_instance_network_delete, + .cbs.cli_show = cli_show_ripng_network_prefix, }, { .xpath = "/frr-ripngd:ripngd/instance/interface", .cbs.create = ripngd_instance_interface_create, .cbs.delete = ripngd_instance_interface_delete, + .cbs.cli_show = cli_show_ripng_network_interface, }, { .xpath = "/frr-ripngd:ripngd/instance/offset-list", diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 4d67aa2f68..ef32ed19e2 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2522,8 +2522,6 @@ static int ripng_config_write(struct vty *vty) if (dnode) { nb_cli_show_dnode_cmds(vty, dnode, false); - ripng_network_write(vty, 1); - ripng_redistribute_write(vty, 1); /* RIP offset-list configuration. */ diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h index 6ebc72dae5..95a0b25253 100644 --- a/ripngd/ripngd.h +++ b/ripngd/ripngd.h @@ -337,6 +337,10 @@ extern void ripng_clean(void); extern void ripng_clean_network(void); extern void ripng_interface_clean(void); extern void ripng_interface_reset(void); +extern int ripng_enable_network_add(struct prefix *p); +extern int ripng_enable_network_delete(struct prefix *p); +extern int ripng_enable_if_add(const char *ifname); +extern int ripng_enable_if_delete(const char *ifname); extern void ripng_passive_interface_clean(void); extern void ripng_if_init(void); extern void ripng_route_map_init(void); -- 2.39.5