diff options
425 files changed, 16016 insertions, 8670 deletions
diff --git a/Makefile.am b/Makefile.am index 6dc8e0d354..1e3311fa7b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -110,6 +110,7 @@ dist_examples_DATA = dist_yangmodels_DATA = man_MANS = vtysh_scan = +clippy_scan = ## libtool, the self-made GNU scourge ## ... this should fix relinking @@ -183,6 +184,8 @@ EXTRA_DIST += \ \ python/clidef.py \ python/clippy/__init__.py \ + python/makevars.py \ + python/makefile.py \ \ redhat/frr.logrotate \ redhat/frr.pam \ diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 7f9a13c271..772aec1234 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -28,6 +28,7 @@ THE SOFTWARE. #include "vector.h" #include "distribute.h" #include "lib_errors.h" +#include "network.h" #include "babel_main.h" #include "util.h" @@ -58,11 +59,13 @@ static void babel_interface_free (babel_interface_nfo *bi); static vector babel_enable_if; /* enable interfaces (by cmd). */ -static struct cmd_node babel_interface_node = /* babeld's interface node. */ -{ - INTERFACE_NODE, - "%s(config-if)# ", - 1 /* VTYSH */ +static int interface_config_write(struct vty *vty); +static struct cmd_node babel_interface_node = { + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = interface_config_write, }; @@ -969,7 +972,7 @@ show_babel_routes_sub(struct babel_route *route, struct vty *vty, channels[0] = '\0'; else { int k, j = 0; - snprintf(channels, 100, " chan ("); + snprintf(channels, sizeof(channels), " chan ("); j = strlen(channels); for(k = 0; k < DIVERSITY_HOPS; k++) { if(route->channels[k] == 0) @@ -1247,7 +1250,7 @@ babel_if_init(void) babel_enable_if = vector_init (1); /* install interface node and commands */ - install_node (&babel_interface_node, interface_config_write); + install_node(&babel_interface_node); if_cmd_init(); install_element(BABEL_NODE, &babel_network_cmd); @@ -1394,7 +1397,7 @@ babel_interface_allocate (void) /* All flags are unset */ babel_ifp->bucket_time = babel_now.tv_sec; babel_ifp->bucket = BUCKET_TOKENS_MAX; - babel_ifp->hello_seqno = (random() & 0xFFFF); + babel_ifp->hello_seqno = (frr_weak_random() & 0xFFFF); babel_ifp->rtt_min = 10000; babel_ifp->rtt_max = 120000; babel_ifp->max_rtt_penalty = 150; diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 6f4b905c15..e7ba29ed06 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -136,10 +136,10 @@ struct option longopts[] = { 0 } }; -static const struct frr_yang_module_info *const babeld_yang_modules[] = - { - &frr_interface_info, - }; +static const struct frr_yang_module_info *const babeld_yang_modules[] = { + &frr_interface_info, + &frr_vrf_info, +}; FRR_DAEMON_INFO(babeld, BABELD, .vty_port = BABEL_VTY_PORT, diff --git a/babeld/babeld.c b/babeld/babeld.c index a7a3481998..09955cfbef 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -30,6 +30,7 @@ THE SOFTWARE. #include "filter.h" #include "plist.h" #include "lib_errors.h" +#include "network.h" #include "babel_main.h" #include "babeld.h" @@ -69,11 +70,14 @@ static time_t expiry_time; static time_t source_expiry_time; /* Babel node structure. */ +static int babel_config_write (struct vty *vty); static struct cmd_node cmd_babel_node = { + .name = "babel", .node = BABEL_NODE, + .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", - .vtysh = 1, + .config_write = babel_config_write, }; /* print current babel configuration on vty */ @@ -210,7 +214,7 @@ babel_read_protocol (struct thread *thread) static int babel_init_routing_process(struct thread *thread) { - myseqno = (random() & 0xFFFF); + myseqno = (frr_weak_random() & 0xFFFF); babel_get_myid(); babel_load_state_file(); debugf(BABEL_DEBUG_COMMON, "My ID is : %s.", format_eui64(myid)); @@ -719,7 +723,7 @@ void babeld_quagga_init(void) { - install_node(&cmd_babel_node, &babel_config_write); + install_node(&cmd_babel_node); install_element(CONFIG_NODE, &router_babel_cmd); install_element(CONFIG_NODE, &no_router_babel_cmd); diff --git a/babeld/subdir.am b/babeld/subdir.am index dd46675f22..7827e7dc58 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -7,9 +7,9 @@ noinst_LIBRARIES += babeld/libbabel.a sbin_PROGRAMS += babeld/babeld dist_examples_DATA += babeld/babeld.conf.sample vtysh_scan += \ - $(top_srcdir)/babeld/babel_interface.c \ - $(top_srcdir)/babeld/babel_zebra.c \ - $(top_srcdir)/babeld/babeld.c \ + babeld/babel_interface.c \ + babeld/babel_zebra.c \ + babeld/babeld.c \ # end endif diff --git a/babeld/util.c b/babeld/util.c index c6606e4f0e..e99bd861dc 100644 --- a/babeld/util.c +++ b/babeld/util.c @@ -39,6 +39,8 @@ THE SOFTWARE. #include <netinet/in.h> #include <arpa/inet.h> +#include "lib/network.h" + #include "babel_main.h" #include "babeld.h" #include "util.h" @@ -51,7 +53,7 @@ roughly(int value) else if(value <= 1) return value; else - return value * 3 / 4 + random() % (value / 2); + return value * 3 / 4 + frr_weak_random() % (value / 2); } /* d = s1 - s2 */ @@ -145,7 +147,7 @@ timeval_min_sec(struct timeval *d, time_t secs) { if(d->tv_sec == 0 || d->tv_sec > secs) { d->tv_sec = secs; - d->tv_usec = random() % 1000000; + d->tv_usec = frr_weak_random() % 1000000; } } diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 49cb586db1..f9e572db4d 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -28,6 +28,7 @@ #include <zebra.h> #include "lib/jhash.h" +#include "lib/network.h" #include "bfd.h" @@ -236,8 +237,8 @@ static uint32_t ptm_bfd_gen_ID(void) * random session identification numbers. */ do { - session_id = ((random() << 16) & 0xFFFF0000) - | (random() & 0x0000FFFF); + session_id = ((frr_weak_random() << 16) & 0xFFFF0000) + | (frr_weak_random() & 0x0000FFFF); } while (session_id == 0 || bfd_id_lookup(session_id) != NULL); return session_id; @@ -258,7 +259,7 @@ void ptm_bfd_start_xmt_timer(struct bfd_session *bfd, bool is_echo) * between 75% and 90%. */ maxpercent = (bfd->detect_mult == 1) ? 16 : 26; - jitter = (xmt_TO * (75 + (random() % maxpercent))) / 100; + jitter = (xmt_TO * (75 + (frr_weak_random() % maxpercent))) / 100; /* XXX remove that division above */ if (is_echo) diff --git a/bfdd/bfdd.c b/bfdd/bfdd.c index bed6ccd142..39d51eb649 100644 --- a/bfdd/bfdd.c +++ b/bfdd/bfdd.c @@ -25,6 +25,7 @@ #include "bfd.h" #include "bfdd_nb.h" #include "lib/version.h" +#include "lib/command.h" /* @@ -112,6 +113,7 @@ static struct quagga_signal_t bfd_signals[] = { static const struct frr_yang_module_info *const bfdd_yang_modules[] = { &frr_interface_info, &frr_bfdd_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(bfdd, BFD, .vty_port = 2617, diff --git a/bfdd/bfdd_nb.h b/bfdd/bfdd_nb.h index 8377c87bb7..4fba3a0d30 100644 --- a/bfdd/bfdd_nb.h +++ b/bfdd/bfdd_nb.h @@ -26,171 +26,145 @@ extern const struct frr_yang_module_info frr_bfdd_info; /* Mandatory callbacks. */ -int bfdd_bfd_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int bfdd_bfd_destroy(enum nb_event event, const struct lyd_node *dnode); -int bfdd_bfd_sessions_single_hop_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int bfdd_bfd_sessions_single_hop_destroy(enum nb_event event, - const struct lyd_node *dnode); -const void *bfdd_bfd_sessions_single_hop_get_next(const void *parent_list_entry, - const void *list_entry); -int bfdd_bfd_sessions_single_hop_get_keys(const void *list_entry, - struct yang_list_keys *keys); +int bfdd_bfd_create(struct nb_cb_create_args *args); +int bfdd_bfd_destroy(struct nb_cb_destroy_args *args); +int bfdd_bfd_sessions_single_hop_create(struct nb_cb_create_args *args); +int bfdd_bfd_sessions_single_hop_destroy(struct nb_cb_destroy_args *args); const void * -bfdd_bfd_sessions_single_hop_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys); +bfdd_bfd_sessions_single_hop_get_next(struct nb_cb_get_next_args *args); +int bfdd_bfd_sessions_single_hop_get_keys(struct nb_cb_get_keys_args *args); +const void * +bfdd_bfd_sessions_single_hop_lookup_entry(struct nb_cb_lookup_entry_args *args); int bfdd_bfd_sessions_single_hop_source_addr_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_source_addr_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int bfdd_bfd_sessions_single_hop_detection_multiplier_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_desired_transmission_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_required_receive_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_administrative_down_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int bfdd_bfd_sessions_single_hop_echo_mode_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int bfdd_bfd_sessions_single_hop_echo_mode_modify( + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_local_discriminator_get_elem( - const char *xpath, const void *list_entry); -struct yang_data * -bfdd_bfd_sessions_single_hop_stats_local_state_get_elem(const char *xpath, - const void *list_entry); + struct nb_cb_get_elem_args *args); +struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_state_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_diagnostic_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_multiplier_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_remote_discriminator_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_state_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_diagnostic_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_multiplier_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_negotiated_transmission_interval_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_negotiated_receive_interval_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_detection_mode_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_down_time_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_up_time_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_session_down_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_single_hop_stats_session_up_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_control_packet_input_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_control_packet_output_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_negotiated_echo_transmission_interval_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_echo_packet_input_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_single_hop_stats_echo_packet_output_count_get_elem( - const char *xpath, const void *list_entry); -int bfdd_bfd_sessions_multi_hop_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int bfdd_bfd_sessions_multi_hop_destroy(enum nb_event event, - const struct lyd_node *dnode); -const void *bfdd_bfd_sessions_multi_hop_get_next(const void *parent_list_entry, - const void *list_entry); -int bfdd_bfd_sessions_multi_hop_get_keys(const void *list_entry, - struct yang_list_keys *keys); + struct nb_cb_get_elem_args *args); +int bfdd_bfd_sessions_multi_hop_create(struct nb_cb_create_args *args); +int bfdd_bfd_sessions_multi_hop_destroy(struct nb_cb_destroy_args *args); +const void * +bfdd_bfd_sessions_multi_hop_get_next(struct nb_cb_get_next_args *args); +int bfdd_bfd_sessions_multi_hop_get_keys(struct nb_cb_get_keys_args *args); const void * -bfdd_bfd_sessions_multi_hop_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys); +bfdd_bfd_sessions_multi_hop_lookup_entry(struct nb_cb_lookup_entry_args *args); int bfdd_bfd_sessions_multi_hop_detection_multiplier_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_multi_hop_desired_transmission_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_multi_hop_required_receive_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int bfdd_bfd_sessions_multi_hop_administrative_down_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_local_discriminator_get_elem( - const char *xpath, const void *list_entry); -struct yang_data * -bfdd_bfd_sessions_multi_hop_stats_local_state_get_elem(const char *xpath, - const void *list_entry); + struct nb_cb_get_elem_args *args); +struct yang_data *bfdd_bfd_sessions_multi_hop_stats_local_state_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_local_diagnostic_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_local_multiplier_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_remote_discriminator_get_elem( - const char *xpath, const void *list_entry); -struct yang_data * -bfdd_bfd_sessions_multi_hop_stats_remote_state_get_elem(const char *xpath, - const void *list_entry); + struct nb_cb_get_elem_args *args); +struct yang_data *bfdd_bfd_sessions_multi_hop_stats_remote_state_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_remote_diagnostic_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_remote_multiplier_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_negotiated_transmission_interval_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_negotiated_receive_interval_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_detection_mode_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_last_down_time_get_elem( - const char *xpath, const void *list_entry); -struct yang_data * -bfdd_bfd_sessions_multi_hop_stats_last_up_time_get_elem(const char *xpath, - const void *list_entry); + struct nb_cb_get_elem_args *args); +struct yang_data *bfdd_bfd_sessions_multi_hop_stats_last_up_time_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_session_down_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *bfdd_bfd_sessions_multi_hop_stats_session_up_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_control_packet_input_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_control_packet_output_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_negotiated_echo_transmission_interval_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_echo_packet_input_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * bfdd_bfd_sessions_multi_hop_stats_echo_packet_output_count_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); /* Optional 'cli_show' callbacks. */ void bfd_cli_show_header(struct vty *vty, struct lyd_node *dnode, diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c index 7b95bd23c6..9e136c3fc5 100644 --- a/bfdd/bfdd_nb_config.c +++ b/bfdd/bfdd_nb_config.c @@ -185,17 +185,15 @@ static int bfd_session_destroy(enum nb_event event, /* * XPath: /frr-bfdd:bfdd/bfd */ -int bfdd_bfd_create(enum nb_event event, - const struct lyd_node *dnode __attribute__((__unused__)), - union nb_resource *resource __attribute__((__unused__))) +int bfdd_bfd_create(struct nb_cb_create_args *args) { /* NOTHING */ return NB_OK; } -int bfdd_bfd_destroy(enum nb_event event, const struct lyd_node *dnode) +int bfdd_bfd_destroy(struct nb_cb_destroy_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* NOTHING */ return NB_OK; @@ -219,35 +217,28 @@ int bfdd_bfd_destroy(enum nb_event event, const struct lyd_node *dnode) /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop */ -int bfdd_bfd_sessions_single_hop_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int bfdd_bfd_sessions_single_hop_create(struct nb_cb_create_args *args) { - return bfd_session_create(event, dnode, resource, false); + return bfd_session_create(args->event, args->dnode, args->resource, + false); } -int bfdd_bfd_sessions_single_hop_destroy(enum nb_event event, - const struct lyd_node *dnode) +int bfdd_bfd_sessions_single_hop_destroy(struct nb_cb_destroy_args *args) { - return bfd_session_destroy(event, dnode, false); + return bfd_session_destroy(args->event, args->dnode, false); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/source-addr */ -int bfdd_bfd_sessions_single_hop_source_addr_modify(enum nb_event event - __attribute__((__unused__)), - const struct lyd_node *dnode - __attribute__((__unused__)), - union nb_resource *resource - __attribute__((__unused__))) +int bfdd_bfd_sessions_single_hop_source_addr_modify( + struct nb_cb_modify_args *args) { return NB_OK; } int bfdd_bfd_sessions_single_hop_source_addr_destroy( - enum nb_event event __attribute__((__unused__)), - const struct lyd_node *dnode __attribute__((__unused__))) + struct nb_cb_destroy_args *args) { return NB_OK; } @@ -256,13 +247,12 @@ int bfdd_bfd_sessions_single_hop_source_addr_destroy( * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/detection-multiplier */ int bfdd_bfd_sessions_single_hop_detection_multiplier_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource __attribute__((__unused__))) + struct nb_cb_modify_args *args) { - uint8_t detection_multiplier = yang_dnode_get_uint8(dnode, NULL); + uint8_t detection_multiplier = yang_dnode_get_uint8(args->dnode, NULL); struct bfd_session *bs; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: break; @@ -271,7 +261,7 @@ int bfdd_bfd_sessions_single_hop_detection_multiplier_modify( break; case NB_EV_APPLY: - bs = nb_running_get_entry(dnode, NULL, true); + bs = nb_running_get_entry(args->dnode, NULL, true); bs->detect_mult = detection_multiplier; break; @@ -287,13 +277,12 @@ int bfdd_bfd_sessions_single_hop_detection_multiplier_modify( * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-transmission-interval */ int bfdd_bfd_sessions_single_hop_desired_transmission_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource __attribute__((__unused__))) + struct nb_cb_modify_args *args) { - uint32_t tx_interval = yang_dnode_get_uint32(dnode, NULL); + uint32_t tx_interval = yang_dnode_get_uint32(args->dnode, NULL); struct bfd_session *bs; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: if (tx_interval < 10000 || tx_interval > 60000000) return NB_ERR_VALIDATION; @@ -304,7 +293,7 @@ int bfdd_bfd_sessions_single_hop_desired_transmission_interval_modify( break; case NB_EV_APPLY: - bs = nb_running_get_entry(dnode, NULL, true); + bs = nb_running_get_entry(args->dnode, NULL, true); if (tx_interval == bs->timers.desired_min_tx) return NB_OK; @@ -324,13 +313,12 @@ int bfdd_bfd_sessions_single_hop_desired_transmission_interval_modify( * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/required-receive-interval */ int bfdd_bfd_sessions_single_hop_required_receive_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource __attribute__((__unused__))) + struct nb_cb_modify_args *args) { - uint32_t rx_interval = yang_dnode_get_uint32(dnode, NULL); + uint32_t rx_interval = yang_dnode_get_uint32(args->dnode, NULL); struct bfd_session *bs; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: if (rx_interval < 10000 || rx_interval > 60000000) return NB_ERR_VALIDATION; @@ -341,7 +329,7 @@ int bfdd_bfd_sessions_single_hop_required_receive_interval_modify( break; case NB_EV_APPLY: - bs = nb_running_get_entry(dnode, NULL, true); + bs = nb_running_get_entry(args->dnode, NULL, true); if (rx_interval == bs->timers.required_min_rx) return NB_OK; @@ -361,13 +349,12 @@ int bfdd_bfd_sessions_single_hop_required_receive_interval_modify( * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/administrative-down */ int bfdd_bfd_sessions_single_hop_administrative_down_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource __attribute__((__unused__))) + struct nb_cb_modify_args *args) { - bool shutdown = yang_dnode_get_bool(dnode, NULL); + bool shutdown = yang_dnode_get_bool(args->dnode, NULL); struct bfd_session *bs; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: return NB_OK; @@ -379,7 +366,7 @@ int bfdd_bfd_sessions_single_hop_administrative_down_modify( return NB_OK; } - bs = nb_running_get_entry(dnode, NULL, true); + bs = nb_running_get_entry(args->dnode, NULL, true); if (!shutdown) { if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN)) @@ -423,15 +410,13 @@ int bfdd_bfd_sessions_single_hop_administrative_down_modify( /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/echo-mode */ -int bfdd_bfd_sessions_single_hop_echo_mode_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource - __attribute__((__unused__))) +int bfdd_bfd_sessions_single_hop_echo_mode_modify( + struct nb_cb_modify_args *args) { - bool echo = yang_dnode_get_bool(dnode, NULL); + bool echo = yang_dnode_get_bool(args->dnode, NULL); struct bfd_session *bs; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: return NB_OK; @@ -443,7 +428,7 @@ int bfdd_bfd_sessions_single_hop_echo_mode_modify(enum nb_event event, return NB_OK; } - bs = nb_running_get_entry(dnode, NULL, true); + bs = nb_running_get_entry(args->dnode, NULL, true); if (!echo) { if (!CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO)) @@ -469,13 +454,12 @@ int bfdd_bfd_sessions_single_hop_echo_mode_modify(enum nb_event event, * /frr-bfdd:bfdd/bfd/sessions/single-hop/desired-echo-transmission-interval */ int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource __attribute__((__unused__))) + struct nb_cb_modify_args *args) { - uint32_t echo_interval = yang_dnode_get_uint32(dnode, NULL); + uint32_t echo_interval = yang_dnode_get_uint32(args->dnode, NULL); struct bfd_session *bs; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: if (echo_interval < 10000 || echo_interval > 60000000) return NB_ERR_VALIDATION; @@ -486,7 +470,7 @@ int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify( break; case NB_EV_APPLY: - bs = nb_running_get_entry(dnode, NULL, true); + bs = nb_running_get_entry(args->dnode, NULL, true); if (echo_interval == bs->timers.required_min_echo) return NB_OK; @@ -504,15 +488,13 @@ int bfdd_bfd_sessions_single_hop_desired_echo_transmission_interval_modify( /* * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop */ -int bfdd_bfd_sessions_multi_hop_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int bfdd_bfd_sessions_multi_hop_create(struct nb_cb_create_args *args) { - return bfd_session_create(event, dnode, resource, true); + return bfd_session_create(args->event, args->dnode, args->resource, + true); } -int bfdd_bfd_sessions_multi_hop_destroy(enum nb_event event, - const struct lyd_node *dnode) +int bfdd_bfd_sessions_multi_hop_destroy(struct nb_cb_destroy_args *args) { - return bfd_session_destroy(event, dnode, true); + return bfd_session_destroy(args->event, args->dnode, true); } diff --git a/bfdd/bfdd_nb_state.c b/bfdd/bfdd_nb_state.c index 2a44d46c41..043f850afa 100644 --- a/bfdd/bfdd_nb_state.c +++ b/bfdd/bfdd_nb_state.c @@ -31,37 +31,34 @@ /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop */ -const void *bfdd_bfd_sessions_single_hop_get_next(const void *parent_list_entry - __attribute__((__unused__)), - const void *list_entry) +const void * +bfdd_bfd_sessions_single_hop_get_next(struct nb_cb_get_next_args *args) { - return bfd_session_next(list_entry, false); + return bfd_session_next(args->list_entry, false); } -int bfdd_bfd_sessions_single_hop_get_keys(const void *list_entry, - struct yang_list_keys *keys) +int bfdd_bfd_sessions_single_hop_get_keys(struct nb_cb_get_keys_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; char dstbuf[INET6_ADDRSTRLEN]; inet_ntop(bs->key.family, &bs->key.peer, dstbuf, sizeof(dstbuf)); - keys->num = 3; - strlcpy(keys->key[0], dstbuf, sizeof(keys->key[0])); - strlcpy(keys->key[1], bs->key.ifname, sizeof(keys->key[1])); - strlcpy(keys->key[2], bs->key.vrfname, sizeof(keys->key[2])); + args->keys->num = 3; + strlcpy(args->keys->key[0], dstbuf, sizeof(args->keys->key[0])); + strlcpy(args->keys->key[1], bs->key.ifname, sizeof(args->keys->key[1])); + strlcpy(args->keys->key[2], bs->key.vrfname, + sizeof(args->keys->key[2])); return NB_OK; } const void * -bfdd_bfd_sessions_single_hop_lookup_entry(const void *parent_list_entry - __attribute__((__unused__)), - const struct yang_list_keys *keys) +bfdd_bfd_sessions_single_hop_lookup_entry(struct nb_cb_lookup_entry_args *args) { - const char *dest_addr = keys->key[0]; - const char *ifname = keys->key[1]; - const char *vrf = keys->key[2]; + const char *dest_addr = args->keys->key[0]; + const char *ifname = args->keys->key[1]; + const char *vrf = args->keys->key[2]; struct sockaddr_any psa, lsa; struct bfd_key bk; @@ -77,45 +74,44 @@ bfdd_bfd_sessions_single_hop_lookup_entry(const void *parent_list_entry */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_local_discriminator_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint32(xpath, bs->discrs.my_discr); + return yang_data_new_uint32(args->xpath, bs->discrs.my_discr); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-state */ -struct yang_data * -bfdd_bfd_sessions_single_hop_stats_local_state_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_state_get_elem( + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_enum(xpath, bs->ses_state); + return yang_data_new_enum(args->xpath, bs->ses_state); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-diagnostic */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_diagnostic_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_enum(xpath, bs->local_diag); + return yang_data_new_enum(args->xpath, bs->local_diag); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/local-multiplier */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_multiplier_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_int8(xpath, bs->detect_mult); + return yang_data_new_int8(args->xpath, bs->detect_mult); } /* @@ -123,48 +119,47 @@ struct yang_data *bfdd_bfd_sessions_single_hop_stats_local_multiplier_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_remote_discriminator_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; if (bs->discrs.remote_discr == 0) return NULL; - return yang_data_new_uint32(xpath, bs->discrs.remote_discr); + return yang_data_new_uint32(args->xpath, bs->discrs.remote_discr); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-state */ -struct yang_data * -bfdd_bfd_sessions_single_hop_stats_remote_state_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_state_get_elem( + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_enum(xpath, bs->ses_state); + return yang_data_new_enum(args->xpath, bs->ses_state); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-diagnostic */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_diagnostic_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_enum(xpath, bs->remote_diag); + return yang_data_new_enum(args->xpath, bs->remote_diag); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/remote-multiplier */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_multiplier_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_int8(xpath, bs->remote_detect_mult); + return yang_data_new_int8(args->xpath, bs->remote_detect_mult); } /* @@ -173,11 +168,12 @@ struct yang_data *bfdd_bfd_sessions_single_hop_stats_remote_multiplier_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_negotiated_transmission_interval_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint32(xpath, bs->remote_timers.desired_min_tx); + return yang_data_new_uint32(args->xpath, + bs->remote_timers.desired_min_tx); } /* @@ -186,20 +182,21 @@ bfdd_bfd_sessions_single_hop_stats_negotiated_transmission_interval_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_negotiated_receive_interval_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint32(xpath, bs->remote_timers.required_min_rx); + return yang_data_new_uint32(args->xpath, + bs->remote_timers.required_min_rx); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/detection-mode */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_detection_mode_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; int detection_mode; /* @@ -216,15 +213,14 @@ struct yang_data *bfdd_bfd_sessions_single_hop_stats_detection_mode_get_elem( else detection_mode = 2; - return yang_data_new_enum(xpath, detection_mode); + return yang_data_new_enum(args->xpath, detection_mode); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/last-down-time */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_down_time_get_elem( - const char *xpath __attribute__((__unused__)), - const void *list_entry __attribute__((__unused__))) + struct nb_cb_get_elem_args *args) { /* * TODO: implement me. @@ -238,8 +234,7 @@ struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_down_time_get_elem( * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/last-up-time */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_up_time_get_elem( - const char *xpath __attribute__((__unused__)), - const void *list_entry __attribute__((__unused__))) + struct nb_cb_get_elem_args *args) { /* * TODO: implement me. @@ -254,22 +249,22 @@ struct yang_data *bfdd_bfd_sessions_single_hop_stats_last_up_time_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_session_down_count_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint64(xpath, bs->stats.session_down); + return yang_data_new_uint64(args->xpath, bs->stats.session_down); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/single-hop/stats/session-up-count */ struct yang_data *bfdd_bfd_sessions_single_hop_stats_session_up_count_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint64(xpath, bs->stats.session_up); + return yang_data_new_uint64(args->xpath, bs->stats.session_up); } /* @@ -278,11 +273,11 @@ struct yang_data *bfdd_bfd_sessions_single_hop_stats_session_up_count_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_control_packet_input_count_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint64(xpath, bs->stats.rx_ctrl_pkt); + return yang_data_new_uint64(args->xpath, bs->stats.rx_ctrl_pkt); } /* @@ -291,11 +286,11 @@ bfdd_bfd_sessions_single_hop_stats_control_packet_input_count_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_control_packet_output_count_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint64(xpath, bs->stats.tx_ctrl_pkt); + return yang_data_new_uint64(args->xpath, bs->stats.tx_ctrl_pkt); } /* @@ -304,11 +299,12 @@ bfdd_bfd_sessions_single_hop_stats_control_packet_output_count_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_negotiated_echo_transmission_interval_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint32(xpath, bs->remote_timers.required_min_echo); + return yang_data_new_uint32(args->xpath, + bs->remote_timers.required_min_echo); } /* @@ -316,11 +312,11 @@ bfdd_bfd_sessions_single_hop_stats_negotiated_echo_transmission_interval_get_ele */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_echo_packet_input_count_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint64(xpath, bs->stats.rx_echo_pkt); + return yang_data_new_uint64(args->xpath, bs->stats.rx_echo_pkt); } /* @@ -328,50 +324,47 @@ bfdd_bfd_sessions_single_hop_stats_echo_packet_input_count_get_elem( */ struct yang_data * bfdd_bfd_sessions_single_hop_stats_echo_packet_output_count_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; - return yang_data_new_uint64(xpath, bs->stats.tx_echo_pkt); + return yang_data_new_uint64(args->xpath, bs->stats.tx_echo_pkt); } /* * XPath: /frr-bfdd:bfdd/bfd/sessions/multi-hop */ -const void *bfdd_bfd_sessions_multi_hop_get_next(const void *parent_list_entry - __attribute__((__unused__)), - const void *list_entry) +const void * +bfdd_bfd_sessions_multi_hop_get_next(struct nb_cb_get_next_args *args) { - return bfd_session_next(list_entry, true); + return bfd_session_next(args->list_entry, true); } -int bfdd_bfd_sessions_multi_hop_get_keys(const void *list_entry, - struct yang_list_keys *keys) +int bfdd_bfd_sessions_multi_hop_get_keys(struct nb_cb_get_keys_args *args) { - const struct bfd_session *bs = list_entry; + const struct bfd_session *bs = args->list_entry; char dstbuf[INET6_ADDRSTRLEN], srcbuf[INET6_ADDRSTRLEN]; inet_ntop(bs->key.family, &bs->key.peer, dstbuf, sizeof(dstbuf)); inet_ntop(bs->key.family, &bs->key.local, srcbuf, sizeof(srcbuf)); - keys->num = 4; - strlcpy(keys->key[0], srcbuf, sizeof(keys->key[0])); - strlcpy(keys->key[1], dstbuf, sizeof(keys->key[1])); - strlcpy(keys->key[2], bs->key.ifname, sizeof(keys->key[2])); - strlcpy(keys->key[3], bs->key.vrfname, sizeof(keys->key[3])); + args->keys->num = 4; + strlcpy(args->keys->key[0], srcbuf, sizeof(args->keys->key[0])); + strlcpy(args->keys->key[1], dstbuf, sizeof(args->keys->key[1])); + strlcpy(args->keys->key[2], bs->key.ifname, sizeof(args->keys->key[2])); + strlcpy(args->keys->key[3], bs->key.vrfname, + sizeof(args->keys->key[3])); return NB_OK; } const void * -bfdd_bfd_sessions_multi_hop_lookup_entry(const void *parent_list_entry - __attribute__((__unused__)), - const struct yang_list_keys *keys) +bfdd_bfd_sessions_multi_hop_lookup_entry(struct nb_cb_lookup_entry_args *args) { - const char *source_addr = keys->key[0]; - const char *dest_addr = keys->key[1]; - const char *ifname = keys->key[2]; - const char *vrf = keys->key[3]; + const char *source_addr = args->keys->key[0]; + const char *dest_addr = args->keys->key[1]; + const char *ifname = args->keys->key[2]; + const char *vrf = args->keys->key[3]; struct sockaddr_any psa, lsa; struct bfd_key bk; diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index ddfef214d2..f22e9277a1 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -888,16 +888,20 @@ DEFUN_NOSH(show_debugging_bfd, return CMD_SUCCESS; } +static int bfdd_write_config(struct vty *vty); struct cmd_node bfd_node = { - BFD_NODE, - "%s(config-bfd)# ", - 1, + .name = "bfd", + .node = BFD_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-bfd)# ", + .config_write = bfdd_write_config, }; struct cmd_node bfd_peer_node = { - BFD_PEER_NODE, - "%s(config-bfd-peer)# ", - 1, + .name = "bfd peer", + .node = BFD_PEER_NODE, + .parent_node = BFD_NODE, + .prompt = "%s(config-bfd-peer)# ", }; static int bfdd_write_config(struct vty *vty) @@ -948,11 +952,11 @@ void bfdd_vty_init(void) install_element(CONFIG_NODE, &bfd_debug_network_cmd); /* Install BFD node and commands. */ - install_node(&bfd_node, bfdd_write_config); + install_node(&bfd_node); install_default(BFD_NODE); /* Install BFD peer node. */ - install_node(&bfd_peer_node, NULL); + install_node(&bfd_peer_node); install_default(BFD_PEER_NODE); bfdd_cli_init(); diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 4c88922b8a..7efbd2c7b8 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -24,6 +24,7 @@ #include "lib/queue.h" #include "lib/stream.h" #include "lib/zclient.h" +#include "lib/printfrr.h" #include "lib/bfd.h" @@ -105,12 +106,12 @@ static void debug_printbpc(const struct bfd_peer_cfg *bpc, const char *fmt, ...) snprintf(addr[2], sizeof(addr[2]), " vrf:%s", bpc->bpc_vrfname); if (bpc->bpc_has_recvinterval) - snprintf(timers[0], sizeof(timers[0]), " rx:%" PRIu64, - bpc->bpc_recvinterval); + snprintfrr(timers[0], sizeof(timers[0]), " rx:%" PRIu64, + bpc->bpc_recvinterval); if (bpc->bpc_has_txinterval) - snprintf(timers[1], sizeof(timers[1]), " tx:%" PRIu64, - bpc->bpc_recvinterval); + snprintfrr(timers[1], sizeof(timers[1]), " tx:%" PRIu64, + bpc->bpc_recvinterval); if (bpc->bpc_has_detectmultiplier) snprintf(timers[2], sizeof(timers[2]), " detect-multiplier:%d", diff --git a/bfdd/subdir.am b/bfdd/subdir.am index 254329e221..a79620c45c 100644 --- a/bfdd/subdir.am +++ b/bfdd/subdir.am @@ -6,8 +6,8 @@ if BFDD noinst_LIBRARIES += bfdd/libbfd.a sbin_PROGRAMS += bfdd/bfdd dist_examples_DATA += bfdd/bfdd.conf.sample -vtysh_scan += $(top_srcdir)/bfdd/bfdd_vty.c -vtysh_scan += $(top_srcdir)/bfdd/bfdd_cli.c +vtysh_scan += bfdd/bfdd_vty.c +vtysh_scan += bfdd/bfdd_cli.c man8 += $(MANBUILD)/frr-bfdd.8 endif @@ -25,11 +25,10 @@ bfdd_libbfd_a_SOURCES = \ bfdd/ptm_adapter.c \ # end -bfdd/bfdd_vty_clippy.c: $(CLIPPY_DEPS) -bfdd/bfdd_vty.$(OBJEXT): bfdd/bfdd_vty_clippy.c - -bfdd/bfdd_cli_clippy.c: $(CLIPPY_DEPS) -bfdd/bfdd_cli.$(OBJEXT): bfdd/bfdd_cli_clippy.c +clippy_scan += \ + bfdd/bfdd_cli.c \ + bfdd/bfdd_vty.c \ + # end noinst_HEADERS += \ bfdd/bfdctl.h \ diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index a6fc4ebd03..8902a8789a 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -1772,7 +1772,12 @@ static void bmp_active_setup(struct bmp_active *ba) } } -static struct cmd_node bmp_node = {BMP_NODE, "%s(config-bgp-bmp)# "}; +static struct cmd_node bmp_node = { + .name = "bmp", + .node = BMP_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-bgp-bmp)# " +}; #define BMP_STR "BGP Monitoring Protocol\n" @@ -2266,7 +2271,7 @@ static int bmp_config_write(struct bgp *bgp, struct vty *vty) static int bgp_bmp_init(struct thread_master *tm) { - install_node(&bmp_node, NULL); + install_node(&bmp_node); install_default(BMP_NODE); install_element(BGP_NODE, &bmp_targets_cmd); install_element(BGP_NODE, &no_bmp_targets_cmd); diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 1361ef99be..5b3908442c 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -546,24 +546,20 @@ static char *lcommunity_str_get(struct lcommunity *lcom, int i) uint32_t localdata2; char *str; const uint8_t *ptr; - char *pnt; ptr = lcom->val + (i * LCOMMUNITY_SIZE); memcpy(&lcomval, ptr, LCOMMUNITY_SIZE); /* Allocate memory. 48 bytes taken off bgp_lcommunity.c */ - str = pnt = XMALLOC(MTYPE_LCOMMUNITY_STR, 48); - ptr = (uint8_t *)lcomval.val; ptr = ptr_get_be32(ptr, &globaladmin); ptr = ptr_get_be32(ptr, &localdata1); ptr = ptr_get_be32(ptr, &localdata2); (void)ptr; /* consume value */ - sprintf(pnt, "%u:%u:%u", globaladmin, localdata1, localdata2); - pnt += strlen(pnt); - *pnt = '\0'; + str = XMALLOC(MTYPE_LCOMMUNITY_STR, 48); + snprintf(str, 48, "%u:%u:%u", globaladmin, localdata1, localdata2); return str; } @@ -972,7 +968,7 @@ int community_list_set(struct community_list_handler *ch, const char *name, entry = community_entry_new(); entry->direct = direct; entry->style = style; - entry->any = (str ? 0 : 1); + entry->any = (str ? false : true); entry->u.com = com; entry->reg = regex; entry->seq = seqnum; @@ -1169,7 +1165,7 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name, entry = community_entry_new(); entry->direct = direct; entry->style = style; - entry->any = (str ? 0 : 1); + entry->any = (str ? false : true); entry->u.lcom = lcom; entry->reg = regex; entry->seq = seqnum; @@ -1290,7 +1286,7 @@ int extcommunity_list_set(struct community_list_handler *ch, const char *name, entry = community_entry_new(); entry->direct = direct; entry->style = style; - entry->any = 0; + entry->any = false; if (ecom) entry->config = ecommunity_ecom2str( ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST, 0); diff --git a/bgpd/bgp_clist.h b/bgpd/bgp_clist.h index 4cb5d7c593..f7d46525a0 100644 --- a/bgpd/bgp_clist.h +++ b/bgpd/bgp_clist.h @@ -81,7 +81,7 @@ struct community_entry { uint8_t style; /* Any match. */ - uint8_t any; + bool any; /* Sequence number. */ int64_t seq; diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 5104e23515..396b7ba702 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -570,34 +570,39 @@ static void bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc, if (p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE) { if (is_evpn_prefix_ipaddr_none((struct prefix_evpn *)p)) { - sprintf(evpn_desc, "l2vpn evpn type macip mac %s", - prefix_mac2str( - &p->u.prefix_evpn.macip_addr.mac, - buf2, sizeof(buf2))); + snprintf( + evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type macip mac %s", + prefix_mac2str(&p->u.prefix_evpn.macip_addr.mac, + buf2, sizeof(buf2))); } else { uint8_t family = is_evpn_prefix_ipaddr_v4( (struct prefix_evpn *)p) ? AF_INET : AF_INET6; - sprintf(evpn_desc, "l2vpn evpn type macip mac %s ip %s", - prefix_mac2str( - &p->u.prefix_evpn.macip_addr.mac, - buf2, sizeof(buf2)), - inet_ntop(family, + snprintf( + evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type macip mac %s ip %s", + prefix_mac2str(&p->u.prefix_evpn.macip_addr.mac, + buf2, sizeof(buf2)), + inet_ntop( + family, &p->u.prefix_evpn.macip_addr.ip.ip.addr, buf, PREFIX2STR_BUFFER)); } } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IMET_ROUTE) { - sprintf(evpn_desc, "l2vpn evpn type multicast ip %s", - inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4)); + snprintf(evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type multicast ip %s", + inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4)); } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IP_PREFIX_ROUTE) { uint8_t family = is_evpn_prefix_ipaddr_v4( (struct prefix_evpn *)p) ? AF_INET : AF_INET6; - sprintf(evpn_desc, "l2vpn evpn type prefix ip %s/%d", - inet_ntop(family, - &p->u.prefix_evpn.prefix_addr.ip.ip.addr, buf, - PREFIX2STR_BUFFER), - p->u.prefix_evpn.prefix_addr.ip_prefix_length); + snprintf(evpn_desc, sizeof(evpn_desc), + "l2vpn evpn type prefix ip %s/%d", + inet_ntop(family, + &p->u.prefix_evpn.prefix_addr.ip.ip.addr, + buf, PREFIX2STR_BUFFER), + p->u.prefix_evpn.prefix_addr.ip_prefix_length); } vty_out(vty, "%s %s\n", desc, evpn_desc); @@ -2282,11 +2287,17 @@ static int bgp_config_write_debug(struct vty *vty) return write; } -static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; +static int bgp_config_write_debug(struct vty *vty); +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = bgp_config_write_debug, +}; void bgp_debug_init(void) { - install_node(&debug_node, bgp_config_write_debug); + install_node(&debug_node); install_element(ENABLE_NODE, &show_debugging_bgp_cmd); @@ -2586,12 +2597,14 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, char tag_buf2[20]; bgp_evpn_label2str(label, num_labels, tag_buf2, 20); - sprintf(tag_buf, " label %s", tag_buf2); + snprintf(tag_buf, sizeof(tag_buf), " label %s", + tag_buf2); } else { uint32_t label_value; label_value = decode_label(label); - sprintf(tag_buf, " label %u", label_value); + snprintf(tag_buf, sizeof(tag_buf), " label %u", + label_value); } } diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index cd1722ccca..c87849ad71 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -115,7 +115,8 @@ static FILE *bgp_dump_open_file(struct bgp_dump *bgp_dump) localtime_r(&clock, &tm); if (bgp_dump->filename[0] != DIRECTORY_SEP) { - sprintf(fullpath, "%s/%s", vty_get_cwd(), bgp_dump->filename); + snprintf(fullpath, sizeof(fullpath), "%s/%s", vty_get_cwd(), + bgp_dump->filename); ret = strftime(realpath, MAXPATHLEN, fullpath, &tm); } else ret = strftime(realpath, MAXPATHLEN, bgp_dump->filename, &tm); @@ -777,34 +778,14 @@ DEFUN (no_dump_bgp_all, return bgp_dump_unset(bgp_dump_struct); } +static int config_write_bgp_dump(struct vty *vty); /* BGP node structure. */ -static struct cmd_node bgp_dump_node = {DUMP_NODE, "", 1}; - -#if 0 -char * -config_time2str (unsigned int interval) -{ - static char buf[BUFSIZ]; - - buf[0] = '\0'; - - if (interval / 3600) - { - sprintf (buf, "%dh", interval / 3600); - interval %= 3600; - } - if (interval / 60) - { - sprintf (buf + strlen (buf), "%dm", interval /60); - interval %= 60; - } - if (interval) - { - sprintf (buf + strlen (buf), "%d", interval); - } - return buf; -} -#endif +static struct cmd_node bgp_dump_node = { + .name = "dump", + .node = DUMP_NODE, + .prompt = "", + .config_write = config_write_bgp_dump, +}; static int config_write_bgp_dump(struct vty *vty) { @@ -857,7 +838,7 @@ void bgp_dump_init(void) stream_new((BGP_MAX_PACKET_SIZE << 1) + BGP_DUMP_MSG_HEADER + BGP_DUMP_HEADER_SIZE); - install_node(&bgp_dump_node, config_write_bgp_dump); + install_node(&bgp_dump_node); install_element(CONFIG_NODE, &dump_bgp_all_cmd); install_element(CONFIG_NODE, &no_dump_bgp_all_cmd); diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index fe09aab956..062a6477fa 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -652,13 +652,16 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) as |= (*pnt++); (void)ptr_get_be32(pnt, &bw); if (bw >= ONE_GBPS_BYTES) - sprintf(bps_buf, "%.3f Gbps", (float)(bw/ONE_GBPS_BYTES)); + snprintf(bps_buf, sizeof(bps_buf), "%.3f Gbps", + (float)(bw / ONE_GBPS_BYTES)); else if (bw >= ONE_MBPS_BYTES) - sprintf(bps_buf, "%.3f Mbps", (float)(bw/ONE_MBPS_BYTES)); + snprintf(bps_buf, sizeof(bps_buf), "%.3f Mbps", + (float)(bw / ONE_MBPS_BYTES)); else if (bw >= ONE_KBPS_BYTES) - sprintf(bps_buf, "%.3f Kbps", (float)(bw/ONE_KBPS_BYTES)); + snprintf(bps_buf, sizeof(bps_buf), "%.3f Kbps", + (float)(bw / ONE_KBPS_BYTES)); else - sprintf(bps_buf, "%u bps", bw * 8); + snprintf(bps_buf, sizeof(bps_buf), "%u bps", bw * 8); len = snprintf(buf, bufsz, "LB:%u:%u (%s)", as, bw, bps_buf); return len; diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index fadccc5026..a10686189d 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -5386,7 +5386,8 @@ void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn) vpn->prd.family = AF_UNSPEC; vpn->prd.prefixlen = 64; - sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), vpn->rd_id); + snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id), + vpn->rd_id); (void)str2prefix_rd(buf, &vpn->prd); UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD); } @@ -5529,7 +5530,8 @@ struct evpnes *bgp_evpn_es_new(struct bgp *bgp, bf_assign_index(bm->rd_idspace, es->rd_id); es->prd.family = AF_UNSPEC; es->prd.prefixlen = 64; - sprintf(buf, "%s:%hu", inet_ntoa(bgp->router_id), es->rd_id); + snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id), + es->rd_id); (void)str2prefix_rd(buf, &es->prd); /* Initialize the ES route table */ diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 769872f2e3..85604d856d 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -87,7 +87,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt, eas.as |= (*pnt++); ptr_get_be32(pnt, &eas.val); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -102,7 +102,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt, eip.val = (*pnt++ << 8); eip.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%s:%u", inet_ntoa(eip.ip), + snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip), eip.val); if (json) @@ -117,7 +117,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt, eas.val = (*pnt++ << 8); eas.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -197,7 +197,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, eas.as |= (*pnt++); ptr_get_be32(pnt, &eas.val); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -212,7 +212,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, eip.val = (*pnt++ << 8); eip.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%s:%u", inet_ntoa(eip.ip), + snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip), eip.val); if (json) @@ -227,7 +227,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt, eas.val = (*pnt++ << 8); eas.val |= (*pnt++); - snprintf(rt_buf, RT_ADDRSTRLEN, "%u:%u", eas.as, eas.val); + snprintf(rt_buf, sizeof(rt_buf), "%u:%u", eas.as, eas.val); if (json) json_object_string_add(json_rt, "rt", rt_buf); @@ -841,7 +841,7 @@ static void show_vni_routes_hash(struct hash_bucket *bucket, void *arg) json_object *json_vni = NULL; char vni_str[VNI_STR_LEN]; - snprintf(vni_str, VNI_STR_LEN, "%d", vpn->vni); + snprintf(vni_str, sizeof(vni_str), "%d", vpn->vni); if (json) { json_vni = json_object_new_object(); json_object_int_add(json_vni, "vni", vpn->vni); @@ -880,7 +880,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, /* if an l3vni is present in bgp it is live */ buf1[0] = '\0'; - sprintf(buf1, "*"); + snprintf(buf1, sizeof(buf1), "*"); if (json) { json_object_int_add(json_vni, "vni", bgp->l3vni); @@ -921,9 +921,11 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, json_object_new_string(ecom_str)); } else { if (listcount(bgp->vrf_import_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -947,9 +949,11 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, json_object_new_string(ecom_str)); } else { if (listcount(bgp->vrf_export_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -968,7 +972,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp, char vni_str[VNI_STR_LEN]; json_object_object_add(json_vni, "exportRTs", json_export_rtl); - snprintf(vni_str, VNI_STR_LEN, "%u", bgp->l3vni); + snprintf(vni_str, sizeof(vni_str), "%u", bgp->l3vni); json_object_object_add(json, vni_str, json_vni); } else { vty_out(vty, "\n"); @@ -1046,7 +1050,7 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) buf1[0] = '\0'; if (is_vni_live(vpn)) - sprintf(buf1, "*"); + snprintf(buf1, sizeof(buf1), "*"); if (json) { json_object_int_add(json_vni, "vni", vpn->vni); @@ -1098,9 +1102,11 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) json_object_new_string(ecom_str)); } else { if (listcount(vpn->import_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -1124,9 +1130,11 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) json_object_new_string(ecom_str)); } else { if (listcount(vpn->export_rtl) > 1) - sprintf(rt_buf, "%s, ...", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s, ...", + ecom_str); else - sprintf(rt_buf, "%s", ecom_str); + snprintf(rt_buf, sizeof(rt_buf), "%s", + ecom_str); vty_out(vty, " %-25s", rt_buf); } @@ -1145,7 +1153,7 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[]) char vni_str[VNI_STR_LEN]; json_object_object_add(json_vni, "exportRTs", json_export_rtl); - snprintf(vni_str, VNI_STR_LEN, "%u", vpn->vni); + snprintf(vni_str, sizeof(vni_str), "%u", vpn->vni); json_object_object_add(json, vni_str, json_vni); } else { vty_out(vty, "\n"); @@ -4098,7 +4106,7 @@ DEFUN(show_bgp_l2vpn_evpn_summary, */ DEFUN(show_bgp_l2vpn_evpn_route, show_bgp_l2vpn_evpn_route_cmd, - "show bgp l2vpn evpn route [detail] [type <macip|multicast|es|prefix>] [json]", + "show bgp l2vpn evpn route [detail] [type <macip|2|multicast|3|es|4|prefix|5>] [json]", SHOW_STR BGP_STR L2VPN_HELP_STR @@ -4107,9 +4115,13 @@ DEFUN(show_bgp_l2vpn_evpn_route, "Display Detailed Information\n" "Specify Route type\n" "MAC-IP (Type-2) route\n" + "MAC-IP (Type-2) route\n" + "Multicast (Type-3) route\n" "Multicast (Type-3) route\n" - "Ethernet Segment (type-4) route \n" - "Prefix (type-5 )route\n" + "Ethernet Segment (Type-4) route\n" + "Ethernet Segment (Type-4) route\n" + "Prefix (Type-5) route\n" + "Prefix (Type-5) route\n" JSON_STR) { struct bgp *bgp; @@ -4131,13 +4143,17 @@ DEFUN(show_bgp_l2vpn_evpn_route, /* get the type */ if (argv_find(argv, argc, "type", &type_idx)) { /* Specific type is requested */ - if (strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0) + if ((strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0) + || (strmatch(argv[type_idx + 1]->arg, "2"))) type = BGP_EVPN_MAC_IP_ROUTE; - else if (strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0) + else if ((strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0) + || (strmatch(argv[type_idx + 1]->arg, "3"))) type = BGP_EVPN_IMET_ROUTE; - else if (strncmp(argv[type_idx + 1]->arg, "e", 1) == 0) + else if ((strncmp(argv[type_idx + 1]->arg, "e", 1) == 0) + || (strmatch(argv[type_idx + 1]->arg, "4"))) type = BGP_EVPN_ES_ROUTE; - else if (strncmp(argv[type_idx + 1]->arg, "p", 1) == 0) + else if ((strncmp(argv[type_idx + 1]->arg, "p", 1) == 0) + || (strmatch(argv[type_idx + 1]->arg, "5"))) type = BGP_EVPN_IP_PREFIX_ROUTE; else return CMD_WARNING; diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index 7de8dc2c80..3e26263df1 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -667,12 +667,18 @@ static int config_write_as_list(struct vty *vty) return write; } -static struct cmd_node as_list_node = {AS_LIST_NODE, "", 1}; +static int config_write_as_list(struct vty *vty); +static struct cmd_node as_list_node = { + .name = "as list", + .node = AS_LIST_NODE, + .prompt = "", + .config_write = config_write_as_list, +}; /* Register functions. */ void bgp_filter_init(void) { - install_node(&as_list_node, config_write_as_list); + install_node(&as_list_node); install_element(CONFIG_NODE, &bgp_as_path_cmd); install_element(CONFIG_NODE, &no_bgp_as_path_cmd); diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c index 9554638735..17c41636de 100644 --- a/bgpd/bgp_flowspec.c +++ b/bgpd/bgp_flowspec.c @@ -108,7 +108,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, return BGP_NLRI_PARSE_ERROR_FLOWSPEC_IPV6_NOT_SUPPORTED; } - if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT) { + if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT_EXTENDED) { flog_err(EC_BGP_FLOWSPEC_PACKET, "BGP flowspec nlri length maximum reached (%u)", packet->length); @@ -124,7 +124,11 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr, return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW; psize = *pnt++; - + if (psize >= FLOWSPEC_NLRI_SIZELIMIT) { + psize &= 0x0f; + psize = psize << 8; + psize |= *pnt++; + } /* When packet overflow occur return immediately. */ if (pnt + psize > lim) { flog_err( diff --git a/bgpd/bgp_flowspec_private.h b/bgpd/bgp_flowspec_private.h index dede4e03d3..cec244c165 100644 --- a/bgpd/bgp_flowspec_private.h +++ b/bgpd/bgp_flowspec_private.h @@ -20,6 +20,7 @@ #define _FRR_BGP_FLOWSPEC_PRIVATE_H #define FLOWSPEC_NLRI_SIZELIMIT 240 +#define FLOWSPEC_NLRI_SIZELIMIT_EXTENDED 4095 /* Flowspec raffic action bit*/ #define FLOWSPEC_TRAFFIC_ACTION_TERMINAL 1 diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index fdffe374c0..ce5747dc2b 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1321,7 +1321,8 @@ int bgp_stop(struct peer *peer) if ((peer->status == OpenConfirm) || (peer->status == Established)) { /* ORF received prefix-filter pnt */ - sprintf(orf_name, "%s.%d.%d", peer->host, afi, safi); + snprintf(orf_name, sizeof(orf_name), "%s.%d.%d", + peer->host, afi, safi); prefix_bgp_orf_remove_all(afi, orf_name); } } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 8f0ccca742..04be8d83eb 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -361,6 +361,7 @@ static void bgp_vrf_terminate(void) static const struct frr_yang_module_info *const bgpd_yang_modules[] = { &frr_interface_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT, diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 0531542a38..1af9be46f1 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -745,8 +745,16 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc) bnc_is_valid_nexthop = bgp_isvalid_labeled_nexthop(bnc) ? 1 : 0; } else { - bnc_is_valid_nexthop = - bgp_isvalid_nexthop(bnc) ? 1 : 0; + if (bgp_update_martian_nexthop( + bnc->bgp, afi, safi, path->type, + path->sub_type, path->attr, rn)) { + if (BGP_DEBUG(nht, NHT)) + zlog_debug( + "%s: prefix %pRN (vrf %s), ignoring path due to martian or self-next-hop", + __func__, rn, bgp_path->name); + } else + bnc_is_valid_nexthop = + bgp_isvalid_nexthop(bnc) ? 1 : 0; } if (BGP_DEBUG(nht, NHT)) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 7137c1a784..29c03f4014 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1960,8 +1960,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) break; /* ORF prefix-list name */ - sprintf(name, "%s.%d.%d", peer->host, afi, - safi); + snprintf(name, sizeof(name), "%s.%d.%d", + peer->host, afi, safi); while (p_pnt < p_end) { /* If the ORF entry is malformed, want diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index ab134b15c4..535a45690b 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -605,13 +605,15 @@ static int bgp_pbr_validate_policy_route(struct bgp_pbr_entry_main *api) api->fragment[i].value != 4 && api->fragment[i].value != 8) { success = false; - sprintf(fail_str, + snprintf( + fail_str, sizeof(fail_str), "Value not valid (%d) for this implementation", api->fragment[i].value); } } } else - sprintf(fail_str, "too complex. ignoring"); + snprintf(fail_str, sizeof(fail_str), + "too complex. ignoring"); if (!success) { if (BGP_DEBUG(pbr, PBR)) zlog_debug("BGP: match fragment operation (%d) %s", diff --git a/bgpd/bgp_rd.c b/bgpd/bgp_rd.c index 66d64066c4..e7f1108057 100644 --- a/bgpd/bgp_rd.c +++ b/bgpd/bgp_rd.c @@ -210,6 +210,6 @@ void form_auto_rd(struct in_addr router_id, prd->family = AF_UNSPEC; prd->prefixlen = 64; - sprintf(buf, "%s:%hu", inet_ntoa(router_id), rd_id); + snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(router_id), rd_id); (void)str2prefix_rd(buf, prd); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index d5f903f6e2..78f077eaca 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1925,8 +1925,7 @@ bool subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi, * benefit from consistent behavior across different BGP * implementations. */ - if (peer->bgp->ebgp_requires_policy - == DEFAULT_EBGP_POLICY_ENABLED) + if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY)) if (!bgp_outbound_policy_exists(peer, filter)) return false; @@ -1936,7 +1935,7 @@ bool subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi, * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types, * and obsoletes RFC 6472. */ - if (peer->bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) + if (peer->bgp->reject_as_sets) if (aspath_check_as_sets(attr->aspath)) return false; @@ -2265,7 +2264,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn, bgp_path_info_path_with_addpath_rx_str(new_select, path_buf); else - sprintf(path_buf, "NONE"); + snprintf(path_buf, sizeof(path_buf), "NONE"); zlog_debug( "%s: After path selection, newbest is %s oldbest was %s", pfx_buf, path_buf, @@ -3235,9 +3234,9 @@ static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, } /* Check if received nexthop is valid or not. */ -static bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, - uint8_t type, uint8_t stype, - struct attr *attr, struct bgp_node *rn) +bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, + uint8_t type, uint8_t stype, struct attr *attr, + struct bgp_node *rn) { bool ret = false; @@ -3258,6 +3257,10 @@ static bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop; * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if * it is not an IPv6 link-local address. + * + * If we receive an UPDATE with nexthop length set to 32 bytes + * we shouldn't discard an UPDATE if it's set to (::). + * The link-local (2st) is validated along the code path later. */ if (attr->mp_nexthop_len) { switch (attr->mp_nexthop_len) { @@ -3271,7 +3274,6 @@ static bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, break; case BGP_ATTR_NHLEN_IPV6_GLOBAL: - case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: case BGP_ATTR_NHLEN_VPNV6_GLOBAL: ret = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global) || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global) @@ -3280,6 +3282,13 @@ static bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, || bgp_nexthop_self(bgp, afi, type, stype, attr, rn)); break; + case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: + ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global) + || IN6_IS_ADDR_MULTICAST( + &attr->mp_nexthop_global) + || bgp_nexthop_self(bgp, afi, type, stype, attr, + rn)); + break; default: ret = true; @@ -3413,7 +3422,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * benefit from consistent behavior across different BGP * implementations. */ - if (peer->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED) + if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY)) if (!bgp_inbound_policy_exists(peer, &peer->filter[afi][safi])) { reason = "inbound policy missing"; @@ -3426,7 +3435,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types, * and obsoletes RFC 6472. */ - if (peer->bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) + if (peer->bgp->reject_as_sets) if (aspath_check_as_sets(attr->aspath)) { reason = "as-path contains AS_SET or AS_CONFED_SET type;"; @@ -6891,7 +6900,7 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, * subsumed by the previously aggregated route) without AS_SET * or AS_CONFED_SET in the updates. */ - if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) { + if (bgp->reject_as_sets) { if (as_set == AGGREGATE_AS_SET) { as_set_new = AGGREGATE_AS_UNSET; zlog_warn( @@ -7540,11 +7549,12 @@ static void route_vty_short_status_out(struct vty *vty, vty_out(vty, " "); } -static char *bgp_nexthop_hostname(struct peer *peer, struct attr *attr) +static char *bgp_nexthop_hostname(struct peer *peer, + struct bgp_nexthop_cache *bnc) { if (peer->hostname - && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME) - && !(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) + && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME) && bnc + && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) return peer->hostname; return NULL; } @@ -7566,7 +7576,8 @@ void route_vty_out(struct vty *vty, const struct prefix *p, bool nexthop_othervrf = false; vrf_id_t nexthop_vrfid = VRF_DEFAULT; const char *nexthop_vrfname = VRF_DEFAULT_NAME; - char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr); + char *nexthop_hostname = + bgp_nexthop_hostname(path->peer, path->nexthop); if (json_paths) json_path = json_object_new_object(); @@ -7634,17 +7645,17 @@ void route_vty_out(struct vty *vty, const struct prefix *p, switch (af) { case AF_INET: - sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global_in, buf, - BUFSIZ)); + snprintf(nexthop, sizeof(nexthop), "%s", + inet_ntop(af, &attr->mp_nexthop_global_in, buf, + BUFSIZ)); break; case AF_INET6: - sprintf(nexthop, "%s", - inet_ntop(af, &attr->mp_nexthop_global, buf, - BUFSIZ)); + snprintf(nexthop, sizeof(nexthop), "%s", + inet_ntop(af, &attr->mp_nexthop_global, buf, + BUFSIZ)); break; default: - sprintf(nexthop, "?"); + snprintf(nexthop, sizeof(nexthop), "?"); break; } @@ -8637,7 +8648,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, bool nexthop_self = CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false; int i; - char *nexthop_hostname = bgp_nexthop_hostname(path->peer, attr); + char *nexthop_hostname = + bgp_nexthop_hostname(path->peer, path->nexthop); if (json_paths) { json_path = json_object_new_object(); @@ -12354,7 +12366,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, } } - sprintf(name, "%s.%d.%d", peer->host, afi, safi); + snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi); count = prefix_bgp_show_prefix_list(NULL, afi, name, uj); if (count) { if (!uj) @@ -13247,8 +13259,9 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp, inet_ntop(family, &p->u.prefix_evpn.prefix_addr.ip.ip.addr, local_buf, PREFIX_STRLEN); - sprintf(buf, "%s/%u", local_buf, - p->u.prefix_evpn.prefix_addr.ip_prefix_length); + snprintf(buf, sizeof(buf), "%s/%u", local_buf, + p->u.prefix_evpn.prefix_addr + .ip_prefix_length); } else { prefix2str(p, buf, sizeof(buf)); } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index ad08bbf440..7532dc123a 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -677,4 +677,7 @@ extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, enum bgp_show_type type, void *output_arg, bool use_json); extern int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi); +extern bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, + uint8_t type, uint8_t stype, + struct attr *attr, struct bgp_node *rn); #endif /* _QUAGGA_BGP_ROUTE_H */ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index f30fcc195f..6b57afc5c1 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -39,6 +39,7 @@ #include "hash.h" #include "queue.h" #include "frrstr.h" +#include "network.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -1535,7 +1536,7 @@ static enum route_map_cmd_result_t route_match_probability(void *rule, const struct prefix *prefix, route_map_object_t type, void *object) { - long r = random(); + long r = frr_weak_random(); switch (*(long *)rule) { case 0: diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index e40c7231a7..1ba07e95e6 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -104,7 +104,7 @@ static struct rtr_mgr_group *get_connected_group(void); static void print_prefix_table(struct vty *vty); static void install_cli_commands(void); static int config_write(struct vty *vty); -static void overwrite_exit_commands(void); +static int config_on_exit(struct vty *vty); static void free_cache(struct cache *cache); static struct rtr_mgr_group *get_groups(void); #if defined(FOUND_SSH) @@ -143,7 +143,14 @@ static unsigned int retry_interval; static int rpki_sync_socket_rtr; static int rpki_sync_socket_bgpd; -static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1}; +static struct cmd_node rpki_node = { + .name = "rpki", + .node = RPKI_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-rpki)# ", + .config_write = config_write, + .node_exit = config_on_exit, +}; static const struct route_map_rule_cmd route_match_rpki_cmd = { "rpki", route_match, route_match_compile, route_match_free}; @@ -1394,35 +1401,10 @@ DEFUN (show_rpki_cache_connection, return CMD_SUCCESS; } -DEFUN_NOSH (rpki_exit, - rpki_exit_cmd, - "exit", - "Exit rpki configuration and restart rpki session\n") +static int config_on_exit(struct vty *vty) { reset(false); - - vty->node = CONFIG_NODE; - return CMD_SUCCESS; -} - -DEFUN_NOSH (rpki_quit, - rpki_quit_cmd, - "quit", - "Exit rpki configuration mode\n") -{ - return rpki_exit(self, vty, argc, argv); -} - -DEFUN_NOSH (rpki_end, - rpki_end_cmd, - "end", - "End rpki configuration, restart rpki session and change to enable mode.\n") -{ - int ret = reset(false); - - vty_config_exit(vty); - vty->node = ENABLE_NODE; - return ret == SUCCESS ? CMD_SUCCESS : CMD_WARNING; + return 1; } DEFUN (rpki_reset, @@ -1516,32 +1498,11 @@ DEFUN (no_match_rpki, return CMD_SUCCESS; } -static void overwrite_exit_commands(void) -{ - unsigned int i; - vector cmd_vector = rpki_node.cmd_vector; - - for (i = 0; i < cmd_vector->active; ++i) { - struct cmd_element *cmd = vector_lookup(cmd_vector, i); - - if (strcmp(cmd->string, "exit") == 0 - || strcmp(cmd->string, "quit") == 0 - || strcmp(cmd->string, "end") == 0) { - uninstall_element(RPKI_NODE, cmd); - } - } - - install_element(RPKI_NODE, &rpki_exit_cmd); - install_element(RPKI_NODE, &rpki_quit_cmd); - install_element(RPKI_NODE, &rpki_end_cmd); -} - static void install_cli_commands(void) { // TODO: make config write work - install_node(&rpki_node, &config_write); + install_node(&rpki_node); install_default(RPKI_NODE); - overwrite_exit_commands(); install_element(CONFIG_NODE, &rpki_cmd); install_element(ENABLE_NODE, &rpki_cmd); diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index e40b3320ea..6399bc93aa 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -533,6 +533,14 @@ void bgp_adj_out_unset_subgroup(struct bgp_node *rn, if (adj->adv) bgp_advertise_clean_subgroup(subgrp, adj); + /* If default originate is enabled and the route is default + * route, do not send withdraw. This will prevent deletion of + * the default route at the peer. + */ + if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE) + && is_default_prefix(&rn->p)) + return; + if (adj->attr && withdraw) { /* We need advertisement structure. */ adj->adv = bgp_advertise_new(); @@ -636,12 +644,25 @@ void subgroup_announce_table(struct update_subgroup *subgrp, rn_p, &attr)) bgp_adj_out_set_subgroup(rn, subgrp, &attr, ri); - else + else { + /* If default originate is enabled for + * the peer, do not send explicit + * withdraw. This will prevent deletion + * of default route advertised through + * default originate + */ + if (CHECK_FLAG( + peer->af_flags[afi][safi], + PEER_FLAG_DEFAULT_ORIGINATE) + && is_default_prefix(&rn->p)) + break; + bgp_adj_out_unset_subgroup( rn, subgrp, 1, bgp_addpath_id_for_peer( peer, afi, safi, &ri->tx_addpath)); + } } } @@ -709,7 +730,9 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) struct prefix p; struct peer *from; struct bgp_node *rn; + struct bgp_path_info *pi; struct peer *peer; + struct bgp_adj_out *adj; route_map_result_t ret = RMAP_DENYMATCH; afi_t afi; safi_t safi; @@ -732,10 +755,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) attr.local_pref = bgp->default_local_pref; - memset(&p, 0, sizeof(p)); - p.family = afi2family(afi); - p.prefixlen = 0; - if ((afi == AFI_IP6) || peer_cap_enhe(peer, afi, safi)) { /* IPv6 global nexthop must be included. */ attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL; @@ -778,21 +797,40 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) } } + /* Check if the default route is in local BGP RIB which is + * installed through redistribute or network command + */ + memset(&p, 0, sizeof(p)); + p.family = afi2family(afi); + p.prefixlen = 0; + rn = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi, &p, NULL); + if (withdraw) { + /* Withdraw the default route advertised using default + * originate + */ if (CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) subgroup_default_withdraw_packet(subgrp); UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE); + + /* If default route is present in the local RIB, advertise the + * route + */ + if (rn != NULL) { + for (pi = bgp_node_get_bgp_path_info(rn); pi; + pi = pi->next) { + if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) + if (subgroup_announce_check( + rn, pi, subgrp, &rn->p, + &attr)) + bgp_adj_out_set_subgroup( + rn, subgrp, &attr, pi); + } + } } else { if (!CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) { - if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) - bgp_attr_add_gshut_community(new_attr); - - SET_FLAG(subgrp->sflags, - SUBGRP_STATUS_DEFAULT_ORIGINATE); - subgroup_default_update_packet(subgrp, new_attr, from); - /* The 'neighbor x.x.x.x default-originate' default will * act as an * implicit withdraw for any previous UPDATEs sent for @@ -800,15 +838,37 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) * clear adj_out for the 0.0.0.0/0 prefix in the BGP * table. */ - memset(&p, 0, sizeof(p)); - p.family = afi2family(afi); - p.prefixlen = 0; - - rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, - &p, NULL); - bgp_adj_out_unset_subgroup( - rn, subgrp, 0, - BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE); + if (rn != NULL) { + /* Remove the adjacency for the previously + * advertised default route + */ + adj = adj_lookup( + rn, subgrp, + BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE); + if (adj != NULL) { + /* Clean up previous advertisement. */ + if (adj->adv) + bgp_advertise_clean_subgroup( + subgrp, adj); + + /* Remove from adjacency. */ + RB_REMOVE(bgp_adj_out_rb, &rn->adj_out, + adj); + + /* Free allocated information. */ + adj_free(adj); + + bgp_unlock_node(rn); + } + } + + /* Advertise the default route */ + if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) + bgp_attr_add_gshut_community(new_attr); + + SET_FLAG(subgrp->sflags, + SUBGRP_STATUS_DEFAULT_ORIGINATE); + subgroup_default_update_packet(subgrp, new_attr, from); } } diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index af632a1340..1b95d0656b 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -180,12 +180,14 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, if (type == RD_TYPE_AS || type == RD_TYPE_AS4) - sprintf(rd_str, "%u:%d", - rd_as.as, rd_as.val); + snprintf(rd_str, sizeof(rd_str), + "%u:%d", rd_as.as, + rd_as.val); else if (type == RD_TYPE_IP) - sprintf(rd_str, "%s:%d", - inet_ntoa(rd_ip.ip), - rd_ip.val); + snprintf(rd_str, sizeof(rd_str), + "%s:%d", + inet_ntoa(rd_ip.ip), + rd_ip.val); json_object_string_add( json_routes, "rd", rd_str); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 8f06fdf86c..b7a7d2c382 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -100,6 +100,11 @@ FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE, { .val_ulong = 3, .match_profile = "datacenter", }, { .val_ulong = 60 }, ) +FRR_CFG_DEFAULT_BOOL(BGP_EBGP_REQUIRES_POLICY, + { .val_bool = false, .match_profile = "datacenter", }, + { .val_bool = false, .match_version = "< 7.4", }, + { .val_bool = true }, +) DEFINE_HOOK(bgp_inst_config_write, (struct bgp *bgp, struct vty *vty), @@ -417,6 +422,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name, SET_FLAG((*bgp)->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES); if (DFLT_BGP_DETERMINISTIC_MED) SET_FLAG((*bgp)->flags, BGP_FLAG_DETERMINISTIC_MED); + if (DFLT_BGP_EBGP_REQUIRES_POLICY) + SET_FLAG((*bgp)->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); ret = BGP_SUCCESS; } @@ -2036,7 +2043,7 @@ DEFUN(bgp_ebgp_requires_policy, bgp_ebgp_requires_policy_cmd, "Require in and out policy for eBGP peers (RFC8212)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_ENABLED; + SET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); return CMD_SUCCESS; } @@ -2047,7 +2054,7 @@ DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd, "Require in and out policy for eBGP peers (RFC8212)\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED; + UNSET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY); return CMD_SUCCESS; } @@ -2060,7 +2067,7 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, struct listnode *node, *nnode; struct peer *peer; - bgp->reject_as_sets = BGP_REJECT_AS_SETS_ENABLED; + bgp->reject_as_sets = true; /* Reset existing BGP sessions to reject routes * with aspath containing AS_SET or AS_CONFED_SET. @@ -2086,7 +2093,7 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, struct listnode *node, *nnode; struct peer *peer; - bgp->reject_as_sets = BGP_REJECT_AS_SETS_DISABLED; + bgp->reject_as_sets = false; /* Reset existing BGP sessions to reject routes * with aspath containing AS_SET or AS_CONFED_SET. @@ -8612,8 +8619,9 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer, peer->notify.code, peer->notify.subcode); - sprintf(errorcodesubcode_hexstr, "%02X%02X", - peer->notify.code, peer->notify.subcode); + snprintf(errorcodesubcode_hexstr, + sizeof(errorcodesubcode_hexstr), "%02X%02X", + peer->notify.code, peer->notify.subcode); json_object_string_add(json_peer, "lastErrorCodeSubcode", errorcodesubcode_hexstr); @@ -8792,12 +8800,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, if (peer->hostname && CHECK_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) - sprintf(neighbor_buf, "%s%s(%s) ", - dn_flag, peer->hostname, - peer->host); + snprintf(neighbor_buf, + sizeof(neighbor_buf), + "%s%s(%s) ", dn_flag, + peer->hostname, peer->host); else - sprintf(neighbor_buf, "%s%s ", dn_flag, - peer->host); + snprintf(neighbor_buf, + sizeof(neighbor_buf), "%s%s ", + dn_flag, peer->host); len = strlen(neighbor_buf); @@ -9850,7 +9860,8 @@ static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p, { char buf[SU_ADDRSTRLEN] = {0}; char dn_flag[2] = {0}; - char neighborAddr[INET6_ADDRSTRLEN] = {0}; + /* '*' + v6 address of neighbor */ + char neighborAddr[INET6_ADDRSTRLEN + 1] = {0}; if (!p->conf_if && peer_dynamic_neighbor(p)) dn_flag[0] = '*'; @@ -9870,7 +9881,8 @@ static void bgp_show_peer_gr_status(struct vty *vty, struct peer *p, : sockunion2str(&p->su, buf, SU_ADDRSTRLEN)); } else { - sprintf(neighborAddr, "%s%s", dn_flag, p->host); + snprintf(neighborAddr, sizeof(neighborAddr), "%s%s", dn_flag, + p->host); if (use_json) json_object_string_add(json, "neighborAddr", @@ -9971,7 +9983,8 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, else json_object_free(json_af); - sprintf(orf_pfx_name, "%s.%d.%d", p->host, afi, safi); + snprintf(orf_pfx_name, sizeof(orf_pfx_name), "%s.%d.%d", + p->host, afi, safi); orf_pfx_count = prefix_bgp_show_prefix_list( NULL, afi, orf_pfx_name, use_json); @@ -10149,14 +10162,14 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, filter->map[RMAP_OUT].name); /* ebgp-requires-policy (inbound) */ - if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED + if (CHECK_FLAG(p->bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY) && !bgp_inbound_policy_exists(p, filter)) json_object_string_add( json_addr, "inboundEbgpRequiresPolicy", "Inbound updates discarded due to missing policy"); /* ebgp-requires-policy (outbound) */ - if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED + if (CHECK_FLAG(p->bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY) && (!bgp_outbound_policy_exists(p, filter))) json_object_string_add( json_addr, "outboundEbgpRequiresPolicy", @@ -10267,7 +10280,8 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, PEER_CAP_ORF_PREFIX_RM_OLD_RCV, use_json, NULL); } - sprintf(orf_pfx_name, "%s.%d.%d", p->host, afi, safi); + snprintf(orf_pfx_name, sizeof(orf_pfx_name), "%s.%d.%d", + p->host, afi, safi); orf_pfx_count = prefix_bgp_show_prefix_list( NULL, afi, orf_pfx_name, use_json); @@ -10445,13 +10459,13 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, filter->map[RMAP_OUT].name); /* ebgp-requires-policy (inbound) */ - if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED + if (CHECK_FLAG(p->bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY) && !bgp_inbound_policy_exists(p, filter)) vty_out(vty, " Inbound updates discarded due to missing policy\n"); /* ebgp-requires-policy (outbound) */ - if (p->bgp->ebgp_requires_policy == DEFAULT_EBGP_POLICY_ENABLED + if (CHECK_FLAG(p->bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY) && !bgp_outbound_policy_exists(p, filter)) vty_out(vty, " Outbound updates discarded due to missing policy\n"); @@ -15066,12 +15080,16 @@ int bgp_config_write(struct vty *vty) vty_out(vty, " bgp always-compare-med\n"); /* RFC8212 default eBGP policy. */ - if (bgp->ebgp_requires_policy - == DEFAULT_EBGP_POLICY_ENABLED) - vty_out(vty, " bgp ebgp-requires-policy\n"); + if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY) + != SAVE_BGP_EBGP_REQUIRES_POLICY) + vty_out(vty, " %sbgp ebgp-requires-policy\n", + CHECK_FLAG(bgp->flags, + BGP_FLAG_EBGP_REQUIRES_POLICY) + ? "" + : "no "); /* draft-ietf-idr-deprecate-as-set-confed-set */ - if (bgp->reject_as_sets == BGP_REJECT_AS_SETS_ENABLED) + if (bgp->reject_as_sets) vty_out(vty, " bgp reject-as-sets\n"); /* BGP default ipv4-unicast. */ @@ -15335,50 +15353,96 @@ int bgp_config_write(struct vty *vty) /* BGP node structure. */ static struct cmd_node bgp_node = { - BGP_NODE, "%s(config-router)# ", 1, + .name = "bgp", + .node = BGP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", + .config_write = bgp_config_write, }; static struct cmd_node bgp_ipv4_unicast_node = { - BGP_IPV4_NODE, "%s(config-router-af)# ", 1, + .name = "bgp ipv4 unicast", + .node = BGP_IPV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", }; static struct cmd_node bgp_ipv4_multicast_node = { - BGP_IPV4M_NODE, "%s(config-router-af)# ", 1, + .name = "bgp ipv4 multicast", + .node = BGP_IPV4M_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", }; static struct cmd_node bgp_ipv4_labeled_unicast_node = { - BGP_IPV4L_NODE, "%s(config-router-af)# ", 1, + .name = "bgp ipv4 labeled unicast", + .node = BGP_IPV4L_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", }; static struct cmd_node bgp_ipv6_unicast_node = { - BGP_IPV6_NODE, "%s(config-router-af)# ", 1, + .name = "bgp ipv6", + .node = BGP_IPV6_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", }; static struct cmd_node bgp_ipv6_multicast_node = { - BGP_IPV6M_NODE, "%s(config-router-af)# ", 1, + .name = "bgp ipv6 multicast", + .node = BGP_IPV6M_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", }; static struct cmd_node bgp_ipv6_labeled_unicast_node = { - BGP_IPV6L_NODE, "%s(config-router-af)# ", 1, + .name = "bgp ipv6 labeled unicast", + .node = BGP_IPV6L_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", }; -static struct cmd_node bgp_vpnv4_node = {BGP_VPNV4_NODE, - "%s(config-router-af)# ", 1}; +static struct cmd_node bgp_vpnv4_node = { + .name = "bgp vpnv4", + .node = BGP_VPNV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_vpnv6_node = {BGP_VPNV6_NODE, - "%s(config-router-af-vpnv6)# ", 1}; +static struct cmd_node bgp_vpnv6_node = { + .name = "bgp vpnv6", + .node = BGP_VPNV6_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af-vpnv6)# ", +}; -static struct cmd_node bgp_evpn_node = {BGP_EVPN_NODE, - "%s(config-router-evpn)# ", 1}; +static struct cmd_node bgp_evpn_node = { + .name = "bgp evpn", + .node = BGP_EVPN_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-evpn)# ", +}; -static struct cmd_node bgp_evpn_vni_node = {BGP_EVPN_VNI_NODE, - "%s(config-router-af-vni)# ", 1}; +static struct cmd_node bgp_evpn_vni_node = { + .name = "bgp evpn vni", + .node = BGP_EVPN_VNI_NODE, + .parent_node = BGP_EVPN_NODE, + .prompt = "%s(config-router-af-vni)# ", +}; -static struct cmd_node bgp_flowspecv4_node = {BGP_FLOWSPECV4_NODE, - "%s(config-router-af)# ", 1}; +static struct cmd_node bgp_flowspecv4_node = { + .name = "bgp ipv4 flowspec", + .node = BGP_FLOWSPECV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_flowspecv6_node = {BGP_FLOWSPECV6_NODE, - "%s(config-router-af-vpnv6)# ", 1}; +static struct cmd_node bgp_flowspecv6_node = { + .name = "bgp ipv6 flowspec", + .node = BGP_FLOWSPECV6_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af-vpnv6)# ", +}; static void community_list_vty(void); @@ -15441,19 +15505,19 @@ void bgp_vty_init(void) cmd_variable_handler_register(bgp_var_peergroup); /* Install bgp top node. */ - install_node(&bgp_node, bgp_config_write); - install_node(&bgp_ipv4_unicast_node, NULL); - install_node(&bgp_ipv4_multicast_node, NULL); - install_node(&bgp_ipv4_labeled_unicast_node, NULL); - install_node(&bgp_ipv6_unicast_node, NULL); - install_node(&bgp_ipv6_multicast_node, NULL); - install_node(&bgp_ipv6_labeled_unicast_node, NULL); - install_node(&bgp_vpnv4_node, NULL); - install_node(&bgp_vpnv6_node, NULL); - install_node(&bgp_evpn_node, NULL); - install_node(&bgp_evpn_vni_node, NULL); - install_node(&bgp_flowspecv4_node, NULL); - install_node(&bgp_flowspecv6_node, NULL); + install_node(&bgp_node); + install_node(&bgp_ipv4_unicast_node); + install_node(&bgp_ipv4_multicast_node); + install_node(&bgp_ipv4_labeled_unicast_node); + install_node(&bgp_ipv6_unicast_node); + install_node(&bgp_ipv6_multicast_node); + install_node(&bgp_ipv6_labeled_unicast_node); + install_node(&bgp_vpnv4_node); + install_node(&bgp_vpnv6_node); + install_node(&bgp_evpn_node); + install_node(&bgp_evpn_vni_node); + install_node(&bgp_flowspecv4_node); + install_node(&bgp_flowspecv6_node); /* Install default VTY commands to new nodes. */ install_default(BGP_NODE); @@ -17858,13 +17922,17 @@ static int community_list_config_write(struct vty *vty) return write; } +static int community_list_config_write(struct vty *vty); static struct cmd_node community_list_node = { - COMMUNITY_LIST_NODE, "", 1 /* Export to vtysh. */ + .name = "community list", + .node = COMMUNITY_LIST_NODE, + .prompt = "", + .config_write = community_list_config_write, }; static void community_list_vty(void) { - install_node(&community_list_node, community_list_config_write); + install_node(&community_list_node); /* Community-list. */ install_element(CONFIG_NODE, &bgp_community_list_standard_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index dedd0ed3b1..5d28b138d6 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2972,8 +2972,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, bgp->dynamic_neighbors_count = 0; bgp->lb_ref_bw = BGP_LINK_BW_REF_BW; bgp->lb_handling = BGP_LINK_BW_ECMP; - bgp->ebgp_requires_policy = DEFAULT_EBGP_POLICY_DISABLED; - bgp->reject_as_sets = BGP_REJECT_AS_SETS_DISABLED; + bgp->reject_as_sets = false; bgp_addpath_init_bgp_data(&bgp->tx_addpath); bgp->as = *as; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index f6f9687783..4a5772a53b 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -446,6 +446,7 @@ struct bgp { #define BGP_FLAG_DELETE_IN_PROGRESS (1 << 22) #define BGP_FLAG_SELECT_DEFER_DISABLE (1 << 23) #define BGP_FLAG_GR_DISABLE_EOR (1 << 24) +#define BGP_FLAG_EBGP_REQUIRES_POLICY (1 << 25) enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE] [BGP_GLOBAL_GR_EVENT_CMD]; @@ -593,17 +594,10 @@ struct bgp { /* EVPN enable - advertise local VNIs and their MACs etc. */ int advertise_all_vni; - /* RFC 8212 - prevent route leaks. */ - int ebgp_requires_policy; -#define DEFAULT_EBGP_POLICY_DISABLED 0 -#define DEFAULT_EBGP_POLICY_ENABLED 1 - /* draft-ietf-idr-deprecate-as-set-confed-set * Reject aspaths with AS_SET and/or AS_CONFED_SET. */ bool reject_as_sets; -#define BGP_REJECT_AS_SETS_DISABLED 0 -#define BGP_REJECT_AS_SETS_ENABLED 1 struct bgp_evpn_info *evpn_info; diff --git a/bgpd/rfapi/bgp_rfapi_cfg.c b/bgpd/rfapi/bgp_rfapi_cfg.c index acfab53d2b..2bcef97fc3 100644 --- a/bgpd/rfapi/bgp_rfapi_cfg.c +++ b/bgpd/rfapi/bgp_rfapi_cfg.c @@ -2965,10 +2965,18 @@ DEFUN_NOSH (exit_vnc, } static struct cmd_node bgp_vnc_defaults_node = { - BGP_VNC_DEFAULTS_NODE, "%s(config-router-vnc-defaults)# ", 1}; + .name = "bgp vnc defaults", + .node = BGP_VNC_DEFAULTS_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vnc-defaults)# ", +}; static struct cmd_node bgp_vnc_nve_group_node = { - BGP_VNC_NVE_GROUP_NODE, "%s(config-router-vnc-nve-group)# ", 1}; + .name = "bgp vnc nve", + .node = BGP_VNC_NVE_GROUP_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vnc-nve-group)# ", +}; /*------------------------------------------------------------------------- * VNC nve-group @@ -3388,7 +3396,11 @@ DEFUN_NOSH (exit_vrf_policy, } static struct cmd_node bgp_vrf_policy_node = { - BGP_VRF_POLICY_NODE, "%s(config-router-vrf-policy)# ", 1}; + .name = "bgp vrf policy", + .node = BGP_VRF_POLICY_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vrf-policy)# ", +}; /*------------------------------------------------------------------------- * vnc-l2-group @@ -3624,7 +3636,11 @@ DEFUN (vnc_l2_group_rt, static struct cmd_node bgp_vnc_l2_group_node = { - BGP_VNC_L2_GROUP_NODE, "%s(config-router-vnc-l2-group)# ", 1}; + .name = "bgp vnc l2", + .node = BGP_VNC_L2_GROUP_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vnc-l2-group)# ", +}; struct rfapi_l2_group_cfg * bgp_rfapi_get_group_by_lni_label(struct bgp *bgp, uint32_t logical_net_id, @@ -3681,10 +3697,10 @@ bgp_rfapi_get_ecommunity_by_lni_label(struct bgp *bgp, uint32_t is_import, void bgp_rfapi_cfg_init(void) { - install_node(&bgp_vnc_defaults_node, NULL); - install_node(&bgp_vnc_nve_group_node, NULL); - install_node(&bgp_vrf_policy_node, NULL); - install_node(&bgp_vnc_l2_group_node, NULL); + install_node(&bgp_vnc_defaults_node); + install_node(&bgp_vnc_nve_group_node); + install_node(&bgp_vrf_policy_node); + install_node(&bgp_vnc_l2_group_node); install_default(BGP_VRF_POLICY_NODE); install_default(BGP_VNC_DEFAULTS_NODE); install_default(BGP_VNC_NVE_GROUP_NODE); @@ -4611,7 +4627,8 @@ void bgp_rfapi_show_summary(struct bgp *bgp, struct vty *vty) (hc->rfp_cfg.download_type == RFAPI_RFP_DOWNLOAD_PARTIAL ? "(default)" : "")); - sprintf(tmp, "%u seconds", hc->rfp_cfg.ftd_advertisement_interval); + snprintf(tmp, sizeof(tmp), "%u seconds", + hc->rfp_cfg.ftd_advertisement_interval); vty_out(vty, "%-39s %-19s %s\n", " Advertisement Interval:", tmp, (hc->rfp_cfg.ftd_advertisement_interval == RFAPI_RFP_CFG_DEFAULT_FTD_ADVERTISEMENT_INTERVAL diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index a0d8995a0f..d6b6a78f62 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -3506,7 +3506,7 @@ DEFUN (debug_rfapi_show_import, "\nLNI-based Ethernet Tables:\n"); first_l2 = 0; } - snprintf(buf, BUFSIZ, "L2VPN LNI=%u", lni); + snprintf(buf, sizeof(buf), "L2VPN LNI=%u", lni); rfapiShowImportTable( vty, buf, it->imported_vpn[AFI_L2VPN], 1); diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 89f6852e2b..67f6a6a0fc 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -25,7 +25,6 @@ #include "lib/memory.h" #include "lib/routemap.h" #include "lib/log.h" -#include "lib/log_int.h" #include "lib/linklist.h" #include "lib/command.h" @@ -371,7 +370,7 @@ int rfapiStream2Vty(void *stream, /* input */ *fp = (int (*)(void *, const char *, ...))rfapiDebugPrintf; *outstream = NULL; *vty_newline = str_vty_newline(*vty); - return (vzlog_test(LOG_DEBUG)); + return 1; } if (((uintptr_t)stream == (uintptr_t)1) @@ -1039,7 +1038,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, * Prefix */ buf_pfx[0] = 0; - snprintf(buf_pfx, BUFSIZ, "%s/%d", + snprintf(buf_pfx, sizeof(buf_pfx), "%s/%d", rfapi_ntop(p->family, &p->u.prefix, buf_ntop, BUFSIZ), p->prefixlen); buf_pfx[BUFSIZ - 1] = 0; @@ -1050,7 +1049,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, */ buf_un[0] = 0; if (!rfapiGetUnAddrOfVpnBi(bpi, &pfx_un)) { - snprintf(buf_un, BUFSIZ, "%s", + snprintf(buf_un, sizeof(buf_un), "%s", inet_ntop(pfx_un.family, &pfx_un.u.prefix, buf_ntop, BUFSIZ)); } @@ -1064,18 +1063,18 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, if (tun_type == BGP_ENCAP_TYPE_MPLS) { /* MPLS carries un in nrli next hop (same as vn for IP tunnels) */ - snprintf(buf_un, BUFSIZ, "%s", + snprintf(buf_un, sizeof(buf_un), "%s", inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); if (bpi->extra) { uint32_t l = decode_label(&bpi->extra->label[0]); - snprintf(buf_vn, BUFSIZ, "Label: %d", l); + snprintf(buf_vn, sizeof(buf_vn), "Label: %d", l); } else /* should never happen */ { - snprintf(buf_vn, BUFSIZ, "Label: N/A"); + snprintf(buf_vn, sizeof(buf_vn), "Label: N/A"); } } else { - snprintf(buf_vn, BUFSIZ, "%s", + snprintf(buf_vn, sizeof(buf_vn), "%s", inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, BUFSIZ)); } diff --git a/bgpd/rfapi/vnc_debug.c b/bgpd/rfapi/vnc_debug.c index 2c5e188328..5c627efbee 100644 --- a/bgpd/rfapi/vnc_debug.c +++ b/bgpd/rfapi/vnc_debug.c @@ -173,11 +173,17 @@ static int bgp_vnc_config_write_debug(struct vty *vty) return write; } -static struct cmd_node debug_node = {DEBUG_VNC_NODE, "", 1}; +static int bgp_vnc_config_write_debug(struct vty *vty); +static struct cmd_node debug_node = { + .name = "vnc debug", + .node = DEBUG_VNC_NODE, + .prompt = "", + .config_write = bgp_vnc_config_write_debug, +}; void vnc_debug_init(void) { - install_node(&debug_node, bgp_vnc_config_write_debug); + install_node(&debug_node); install_element(ENABLE_NODE, &show_debugging_bgp_vnc_cmd); install_element(ENABLE_NODE, &debug_bgp_vnc_cmd); diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index ac5beed0e3..0a8e1618fc 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -275,7 +275,12 @@ static void vnc_rhnck(char *tag) vnc_zlog_debug_verbose("%s: vnc_rhnck OK", tag); } -#define VNC_RHNCK(n) do {char buf[BUFSIZ];sprintf(buf,"%s: %s", __func__, #n);vnc_rhnck(buf);} while (0) +#define VNC_RHNCK(n) \ + do { \ + char buf[BUFSIZ]; \ + snprintf(buf, sizeof(buf), "%s: %s", __func__, #n); \ + vnc_rhnck(buf); \ + } while (0) #else diff --git a/bgpd/subdir.am b/bgpd/subdir.am index ff15248a98..6b5c0fe719 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -12,29 +12,29 @@ dist_examples_DATA += \ bgpd/bgpd.conf.vnc.sample \ # end vtysh_scan += \ - $(top_srcdir)/bgpd/bgp_bfd.c \ - $(top_srcdir)/bgpd/bgp_debug.c \ - $(top_srcdir)/bgpd/bgp_dump.c \ - $(top_srcdir)/bgpd/bgp_evpn_vty.c \ - $(top_srcdir)/bgpd/bgp_filter.c \ - $(top_srcdir)/bgpd/bgp_mplsvpn.c \ - $(top_srcdir)/bgpd/bgp_nexthop.c \ - $(top_srcdir)/bgpd/bgp_route.c \ - $(top_srcdir)/bgpd/bgp_routemap.c \ - $(top_srcdir)/bgpd/bgp_vty.c \ - $(top_srcdir)/bgpd/bgp_flowspec_vty.c \ + bgpd/bgp_bfd.c \ + bgpd/bgp_debug.c \ + bgpd/bgp_dump.c \ + bgpd/bgp_evpn_vty.c \ + bgpd/bgp_filter.c \ + bgpd/bgp_mplsvpn.c \ + bgpd/bgp_nexthop.c \ + bgpd/bgp_route.c \ + bgpd/bgp_routemap.c \ + bgpd/bgp_vty.c \ + bgpd/bgp_flowspec_vty.c \ # end # can be loaded as DSO - always include for vtysh -vtysh_scan += $(top_srcdir)/bgpd/bgp_rpki.c -vtysh_scan += $(top_srcdir)/bgpd/bgp_bmp.c +vtysh_scan += bgpd/bgp_rpki.c +vtysh_scan += bgpd/bgp_bmp.c if ENABLE_BGP_VNC vtysh_scan += \ - $(top_srcdir)/bgpd/rfapi/bgp_rfapi_cfg.c \ - $(top_srcdir)/bgpd/rfapi/rfapi.c \ - $(top_srcdir)/bgpd/rfapi/rfapi_vty.c \ - $(top_srcdir)/bgpd/rfapi/vnc_debug.c \ + bgpd/rfapi/bgp_rfapi_cfg.c \ + bgpd/rfapi/rfapi.c \ + bgpd/rfapi/rfapi_vty.c \ + bgpd/rfapi/vnc_debug.c \ # end endif if SNMP @@ -217,18 +217,12 @@ bgpd_bgpd_bmp_la_SOURCES = bgpd/bgp_bmp.c bgpd_bgpd_bmp_la_LIBADD = lib/libfrrcares.la bgpd_bgpd_bmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic -bgpd/bgp_evpn_vty_clippy.c: $(CLIPPY_DEPS) -bgpd/bgp_evpn_vty.$(OBJEXT): bgpd/bgp_evpn_vty_clippy.c -bgpd/bgp_vty_clippy.c: $(CLIPPY_DEPS) -bgpd/bgp_vty.$(OBJEXT): bgpd/bgp_vty_clippy.c -bgpd/bgp_route_clippy.c: $(CLIPPY_DEPS) -bgpd/bgp_route.$(OBJEXT): bgpd/bgp_route_clippy.c -bgpd/bgp_debug_clippy.c: $(CLIPPY_DEPS) -bgpd/bgp_debug.$(OBJEXT): bgpd/bgp_debug_clippy.c -bgpd/bgp_routemap_clippy.c: $(CLIPPY_DEPS) -bgpd/bgp_routemap.$(OBJEXT): bgpd/bgp_routemap_clippy.c -bgpd/bgp_rpki_clippy.c: $(CLIPPY_DEPS) -$(AUTOMAKE_DUMMY)bgpd/bgpd_bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c -$(AUTOMAKE_DUMMY)bgpd/bgpd_rpki_la-bgp_rpki.lo: bgpd/bgp_rpki_clippy.c -bgpd/bgp_bmp_clippy.c: $(CLIPPY_DEPS) -bgpd/bgp_bmp.lo: bgpd/bgp_bmp_clippy.c +clippy_scan += \ + bgpd/bgp_bmp.c \ + bgpd/bgp_debug.c \ + bgpd/bgp_evpn_vty.c \ + bgpd/bgp_route.c \ + bgpd/bgp_routemap.c \ + bgpd/bgp_rpki.c \ + bgpd/bgp_vty.c \ + # end diff --git a/bgpd/valgrind.supp b/bgpd/valgrind.supp index 7a25c88363..ed236a6dc5 100644 --- a/bgpd/valgrind.supp +++ b/bgpd/valgrind.supp @@ -7,3 +7,11 @@ fun:ly_load_plugins_dir fun:ly_load_plugins } +{ + <zlog_keep_working_at_exit> + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + fun:qcalloc + fun:zlog_target_clone +} diff --git a/configure.ac b/configure.ac index 35261aced4..e1e23e224d 100755 --- a/configure.ac +++ b/configure.ac @@ -428,6 +428,9 @@ LT_INIT _LT_CONFIG_LIBTOOL([ patch -N -i "${srcdir}/m4/libtool-whole-archive.patch" libtool >&AS_MESSAGE_LOG_FD || \ AC_MSG_WARN([Could not patch libtool for static linking support. Loading modules into a statically linked daemon will fail.]) + sed -e 's%func_warning "relinking%true #\0%' -i libtool || true + sed -e 's%func_warning "remember to run%true #\0%' -i libtool || true + sed -e 's%func_warning ".*has not been installed in%true #\0%' -i libtool || true ]) if test "$enable_static_bin" = "yes"; then AC_LDFLAGS="-static" @@ -959,7 +962,7 @@ int main(int argc, char **argv) { AC_CHECK_HEADERS([pthread_np.h],,, [ #include <pthread.h> ]) -AC_CHECK_FUNCS([pthread_setname_np pthread_set_name_np]) +AC_CHECK_FUNCS([pthread_setname_np pthread_set_name_np pthread_getthreadid_np]) needsync=true @@ -1202,7 +1205,11 @@ dnl other functions dnl --------------- AC_CHECK_FUNCS([ \ strlcat strlcpy \ - getgrouplist]) + getgrouplist \ + openat \ + unlinkat \ + posix_fallocate \ + ]) dnl ########################################################################## dnl LARGE if block spans a lot of "configure"! @@ -2197,22 +2204,12 @@ if test "$enable_backtrace" != "no" ; then fi if test "$backtrace_ok" = "no"; then - case "$host_os" in - sunos* | solaris2*) - AC_CHECK_FUNCS([printstack], [ - AC_DEFINE([HAVE_PRINTSTACK], [1], [Solaris printstack]) + AC_CHECK_HEADER([execinfo.h], [ + AC_SEARCH_LIBS([backtrace], [execinfo], [ + AC_DEFINE([HAVE_GLIBC_BACKTRACE], [1], [Glibc backtrace]) backtrace_ok=yes - ]) - ;; - esac - if test "$backtrace_ok" = "no"; then - AC_CHECK_HEADER([execinfo.h], [ - AC_SEARCH_LIBS([backtrace], [execinfo], [ - AC_DEFINE([HAVE_GLIBC_BACKTRACE], [1], [Glibc backtrace]) - backtrace_ok=yes - ],, [-lm]) - ]) - fi + ],, [-lm]) + ]) fi if test "$enable_backtrace" = "yes" -a "$backtrace_ok" = "no"; then @@ -2408,7 +2405,13 @@ AM_CONDITIONAL([STATICD], [test "$enable_staticd" != "no"]) AM_CONDITIONAL([FABRICD], [test "$enable_fabricd" != "no"]) AM_CONDITIONAL([VRRPD], [test "$enable_vrrpd" != "no"]) -AC_CONFIG_FILES([Makefile],[sed -e 's/^#AUTODERP# //' -i Makefile]) +AC_CONFIG_FILES([Makefile],[ + test "$enable_dev_build" = "yes" && makefile_devbuild="--dev-build" + ${PYTHON} "${ac_abs_top_srcdir}/python/makefile.py" ${makefile_devbuild} || exit 1 +], [ + PYTHON="$PYTHON" + enable_dev_build="$enable_dev_build" +]) AC_CONFIG_FILES([ config.version diff --git a/doc/developer/fpm.rst b/doc/developer/fpm.rst new file mode 100644 index 0000000000..9849869133 --- /dev/null +++ b/doc/developer/fpm.rst @@ -0,0 +1,103 @@ +FPM +=== + +FPM stands for Forwarding Plane Manager and it's a module for use with Zebra. + +The encapsulation header for the messages exchanged with the FPM is +defined by the file :file:`fpm/fpm.h` in the frr tree. The routes +themselves are encoded in Netlink or protobuf format, with Netlink +being the default. + +Netlink is standard format for encoding messages to talk with kernel space +in Linux and it is also the name of the socket type used by it. +The FPM netlink usage differs from Linux's in: + +- Linux netlink sockets use datagrams in a multicast fashion, FPM uses + as a stream and it is unicast. +- FPM netlink messages might have more or less information than a normal + Linux netlink socket message (example: RTM_NEWROUTE might add an extra + route attribute to signalize VxLAN encapsulation). + +Protobuf is one of a number of new serialization formats wherein the +message schema is expressed in a purpose-built language. Code for +encoding/decoding to/from the wire format is generated from the +schema. Protobuf messages can be extended easily while maintaining +backward-compatibility with older code. Protobuf has the following +advantages over Netlink: + +- Code for serialization/deserialization is generated automatically. This + reduces the likelihood of bugs, allows third-party programs to be integrated + quickly, and makes it easy to add fields. +- The message format is not tied to an OS (Linux), and can be evolved + independently. + +.. note:: + + Currently there are two FPM modules in ``zebra``: + + * ``fpm`` + * ``dplane_fpm_nl`` + +fpm +^^^ + +The first FPM implementation that was built using hooks in ``zebra`` route +handling functions. It uses its own netlink/protobuf encoding functions to +translate ``zebra`` route data structures into formatted binary data. + + +dplane_fpm_nl +^^^^^^^^^^^^^ + +The newer FPM implementation that was built using ``zebra``'s data plane +framework as a plugin. It only supports netlink and it shares ``zebra``'s +netlink functions to translate route event snapshots into formatted binary +data. + + +Protocol Specification +---------------------- + +FPM (in any mode) uses a TCP connection to talk with external applications. +It operates as TCP client and uses the CLI configured address/port to connect +to the FPM server (defaults to port ``2620``). + +FPM frames all data with a header to help the external reader figure how +many bytes it has to read in order to read the full message (this helps +simulates datagrams like in the original netlink Linux kernel usage). + +Frame header: + +:: + + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +---------------+---------------+-------------------------------+ + | Version | Message type | Message length | + +---------------+---------------+-------------------------------+ + | Data... | + +---------------------------------------------------------------+ + + +Version +^^^^^^^ + +Currently there is only one version, so it should be always ``1``. + + +Message Type +^^^^^^^^^^^^ + +Defines what underlining protocol we are using: netlink (``1``) or protobuf (``2``). + + +Message Length +^^^^^^^^^^^^^^ + +Amount of data in this frame in network byte order. + + +Data +^^^^ + +The netlink or protobuf message payload. diff --git a/doc/developer/index.rst b/doc/developer/index.rst index 3a33d9a5ec..26b590c876 100644 --- a/doc/developer/index.rst +++ b/doc/developer/index.rst @@ -11,6 +11,7 @@ FRRouting Developer's Guide library testing bgpd + fpm ospf zebra vtysh diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst index db577c9216..0430ad72a3 100644 --- a/doc/developer/logging.rst +++ b/doc/developer/logging.rst @@ -1,7 +1,7 @@ .. _logging: -Developer's Guide to Logging -============================ +Logging +======= One of the most frequent decisions to make while writing code for FRR is what to log, what level to log it at, and when to log it. Here is a list of @@ -116,8 +116,11 @@ AS-Safety while AS-Safe) * extensions are only AS-Safe if their printer is AS-Safe +Log levels +---------- + Errors and warnings -------------------- +^^^^^^^^^^^^^^^^^^^ If it is something that the user will want to look at and maybe do something, it is either an **error** or a **warning**. @@ -163,7 +166,7 @@ Examples for errors: Informational messages ----------------------- +^^^^^^^^^^^^^^^^^^^^^^ Anything that provides introspection to the user during normal operation is an **info** message. @@ -202,7 +205,7 @@ Examples: Debug messages and asserts --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ Everything that is only interesting on-demand, or only while developing, is a **debug** message. It might be interesting to the user for a @@ -239,3 +242,180 @@ Examples: * some field that is absolutely needed is :code:`NULL` * any other kind of data structure corruption that will cause the daemon to crash sooner or later, one way or another + +Thread-local buffering +---------------------- + +The core logging code in :file:`lib/zlog.c` allows setting up per-thread log +message buffers in order to improve logging performance. The following rules +apply for this buffering: + +* Only messages of priority *DEBUG* or *INFO* are buffered. +* Any higher-priority message causes the thread's entire buffer to be flushed, + thus message ordering is preserved on a per-thread level. +* There is no guarantee on ordering between different threads; in most cases + this is arbitrary to begin with since the threads essentially race each + other in printing log messages. If an order is established with some + synchronization primitive, add calls to :c:func:`zlog_tls_buffer_flush()`. +* The buffers are only ever accessed by the thread they are created by. This + means no locking is necessary. + +Both the main/default thread and additional threads created by +:c:func:`frr_pthread_new()` with the default :c:func:`frr_run()` handler will +initialize thread-local buffering and call :c:func:`zlog_tls_buffer_flush()` +when idle. + +If some piece of code runs for an extended period, it may be useful to insert +calls to :c:func:`zlog_tls_buffer_flush()` in appropriate places: + +.. c:function:: void zlog_tls_buffer_flush(void) + + Write out any pending log messages that the calling thread may have in its + buffer. This function is safe to call regardless of the per-thread log + buffer being set up / in use or not. + +When working with threads that do not use the :c:type:`struct thread_master` +event loop, per-thread buffers can be managed with: + +.. c:function:: void zlog_tls_buffer_init(void) + + Set up thread-local buffering for log messages. This function may be + called repeatedly without adverse effects, but remember to call + :c:func:`zlog_tls_buffer_fini()` at thread exit. + + .. warning:: + + If this function is called, but :c:func:`zlog_tls_buffer_flush()` is + not used, log message output will lag behind since messages will only be + written out when the buffer is full. + + Exiting the thread without calling :c:func:`zlog_tls_buffer_fini()` + will cause buffered log messages to be lost. + +.. c:function:: void zlog_tls_buffer_fini(void) + + Flush pending messages and tear down thread-local log message buffering. + This function may be called repeatedly regardless of whether + :c:func:`zlog_tls_buffer_init()` was ever called. + +Log targets +----------- + +The actual logging subsystem (in :file:`lib/zlog.c`) is heavily separated +from the actual log writers. It uses an atomic linked-list (`zlog_targets`) +with RCU to maintain the log targets to be called. This list is intended to +function as "backend" only, it **is not used for configuration**. + +Logging targets provide their configuration layer on top of this and maintain +their own capability to enumerate and store their configuration. Some targets +(e.g. syslog) are inherently single instance and just stuff their config in +global variables. Others (e.g. file/fd output) are multi-instance capable. +There is another layer boundary here between these and the VTY configuration +that they use. + +Basic internals +^^^^^^^^^^^^^^^ + +.. c:type:: struct zlog_target + + This struct needs to be filled in by any log target and then passed to + :c:func:`zlog_target_replace()`. After it has been registered, + **RCU semantics apply**. Most changes to associated data should make a + copy, change that, and then replace the entire struct. + + Additional per-target data should be "appended" by embedding this struct + into a larger one, for use with `containerof()`, and + :c:func:`zlog_target_clone()` and :c:func:`zlog_target_free()` should be + used to allocate/free the entire container struct. + + Do not use this structure to maintain configuration. It should only + contain (a copy of) the data needed to perform the actual logging. For + example, the syslog target uses this: + + .. code-block:: c + + struct zlt_syslog { + struct zlog_target zt; + int syslog_facility; + }; + + static void zlog_syslog(struct zlog_target *zt, struct zlog_msg *msgs[], size_t nmsgs) + { + struct zlt_syslog *zte = container_of(zt, struct zlt_syslog, zt); + size_t i; + + for (i = 0; i < nmsgs; i++) + if (zlog_msg_prio(msgs[i]) <= zt->prio_min) + syslog(zlog_msg_prio(msgs[i]) | zte->syslog_facility, "%s", + zlog_msg_text(msgs[i], NULL)); + } + + +.. c:function:: struct zlog_target *zlog_target_clone(struct memtype *mt, struct zlog_target *oldzt, size_t size) + + Allocates a logging target struct. Note that the ``oldzt`` argument may be + ``NULL`` to allocate a "from scratch". If ``oldzt`` is not ``NULL``, the + generic bits in :c:type:`struct zlog_target` are copied. **Target specific + bits are not copied.** + +.. c:function:: struct zlog_target *zlog_target_replace(struct zlog_target *oldzt, struct zlog_target *newzt) + + Adds, replaces or deletes a logging target (either ``oldzt`` or ``newzt`` may be ``NULL``.) + + Returns ``oldzt`` for freeing. The target remains possibly in use by + other threads until the RCU cycle ends. This implies you cannot release + resources (e.g. memory, file descriptors) immediately. + + The replace operation is not atomic; for a brief period it is possible that + messages are delivered on both ``oldzt`` and ``newzt``. + + .. warning:: + + ``oldzt`` must remain **functional** until the RCU cycle ends. + +.. c:function:: void zlog_target_free(struct memtype *mt, struct zlog_target *zt) + + Counterpart to :c:func:`zlog_target_clone()`, frees a target (using RCU.) + +.. c:member:: void (*zlog_target.logfn)(struct zlog_target *zt, struct zlog_msg *msgs[], size_t nmsg) + + Called on a target to deliver "normal" logging messages. ``msgs`` is an + array of opaque structs containing the actual message. Use ``zlog_msg_*`` + functions to access message data (this is done to allow some optimizations, + e.g. lazy formatting the message text and timestamp as needed.) + + .. note:: + + ``logfn()`` must check each individual message's priority value against + the configured ``prio_min``. While the ``prio_min`` field is common to + all targets and used by the core logging code to early-drop unneeded log + messages, the array is **not** filtered for each ``logfn()`` call. + +.. c:member:: void (*zlog_target.logfn_sigsafe)(struct zlog_target *zt, const char *text, size_t len) + + Called to deliver "exception" logging messages (i.e. SEGV messages.) + Must be Async-Signal-Safe (may not allocate memory or call "complicated" + libc functions.) May be ``NULL`` if the log target cannot handle this. + +Standard targets +^^^^^^^^^^^^^^^^ + +:file:`lib/zlog_targets.c` provides the standard file / fd / syslog targets. +The syslog target is single-instance while file / fd targets can be +instantiated as needed. There are 3 built-in targets that are fully +autonomous without any config: + +- startup logging to `stderr`, until either :c:func:`zlog_startup_end()` or + :c:func:`zlog_aux_init()` is called. +- stdout logging for non-daemon programs using :c:func:`zlog_aux_init()` +- crashlogs written to :file:`/var/tmp/frr.daemon.crashlog` + +The regular CLI/command-line logging setup is handled by :file:`lib/log_vty.c` +which makes the appropriate instantiations of syslog / file / fd targets. + +.. todo:: + + :c:func:`zlog_startup_end()` should do an explicit switchover from + startup stderr logging to configured logging. Currently, configured logging + starts in parallel as soon as the respective setup is executed. This results + in some duplicate logging. diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index e36b57a5aa..6885a41e0f 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -203,7 +203,6 @@ Submitting Patches and Enhancements FRR accepts patches from two sources: -- Email (git format-patch) - GitHub pull request Contributors are highly encouraged to use GitHub's fork-and-PR workflow. It is @@ -228,29 +227,6 @@ summary of the included patches. The description should provide additional details that will help the reviewer to understand the context of the included patches. -Patch Submission via Mailing List ---------------------------------- - -As an alternative submission method, a patch can be mailed to the -development mailing list. Patches received on the mailing list will be -picked up by Patchwork and tested against the latest development branch. - -The recommended way to send the patch (or series of NN patches) to the -list is by using ``git send-email`` as follows (assuming they are the N -most recent commit(s) in your git history):: - - git send-email -NN --annotate --to=dev@lists.frrouting.org - -If your commits do not already contain a ``Signed-off-by`` line, then -use the following command to add it (after making sure you agree to the -Developer Certificate of Origin as outlined above):: - - git send-email -NN --annotate --signoff --to=dev@lists.frrouting.org - -Submitting multi-commit patches as a GitHub pull request is **strongly -encouraged** and increases the probability of your patch getting reviewed and -merged in a timely manner. - .. _license-for-contributions: License for Contributions @@ -377,6 +353,14 @@ After Submitting Your Changes - An author must never delete or manually dismiss someone else's comments or review. (A review may be overridden by agreement in the weekly technical meeting.) + - When you have addressed someone's review comments, please click the + "re-request review" button (in the top-right corner of the PR page, next + to the reviewer's name, an icon that looks like "reload") + - The responsibility for keeping a PR moving rests with the author at + least as long as there are either negative CI results or negative review + comments. If you forget to mark a review comment as addressed (by + clicking re-request review), the reviewer may very well not notice and + won't come back to your PR. - Automatically generated comments, e.g., those generated by CI systems, may be deleted by authors and others when such comments are not the most recent results from that automated comment source. @@ -459,6 +443,24 @@ Guidelines for code review code change is large enough/significant enough to warrant such a requirement. +For project members with merge permissions, the following patterns have +emerged: + +- a PR with any reviews requesting changes may not be merged. + +- a PR with any negative CI result may not be merged. + +- an open "yellow" review mark ("review requested, but not done") should be + given some time (a few days up to weeks, depending on the size of the PR), + but is not a merge blocker. + +- a "textbubble" review mark ("review comments, but not positive/negative") + should be read through but is not a merge blocker. + +- non-trivial PRs are generally given some time (again depending on the size) + for people to mark an interest in reviewing. Trivial PRs may be merged + immediately when CI is green. + Coding Practices & Style ======================== @@ -539,6 +541,28 @@ your new claim at the end of the list. * ... */ +Defensive coding requirements +----------------------------- + +In general, code submitted into FRR will be rejected if it uses unsafe +programming practices. While there is no enforced overall ruleset, the +following requirements have achieved consensus: + +- ``strcpy``, ``strcat`` and ``sprintf`` are inacceptable without exception. + Use ``strlcpy``, ``strlcat`` and ``snprintf`` instead. (Rationale: even if + you know the operation cannot overflow the buffer, a future code change may + inadvertedly introduce an overflow.) + +- buffer size arguments, particularly to ``strlcpy`` and ``snprintf``, must + use ``sizeof()`` whereever possible. Particularly, do not use a size + constant in these cases. (Rationale: changing a buffer to another size + constant may leave the write operations on a now-incorrect size limit.) + +Other than these specific rules, coding practices from the Linux kernel as +well as CERT or MISRA C guidelines may provide useful input on safe C code. +However, these rules are not applied as-is; some of them expressly collide +with established practice. + Code Formatting --------------- diff --git a/doc/developer/zebra.rst b/doc/developer/zebra.rst index e3526d1843..e2f887ef28 100644 --- a/doc/developer/zebra.rst +++ b/doc/developer/zebra.rst @@ -9,13 +9,20 @@ Zebra Overview of the Zebra Protocol ============================== -The Zebra protocol is used by protocol daemons to communicate with the -**zebra** daemon. - -Each protocol daemon may request and send information to and from the **zebra** -daemon such as interface states, routing state, nexthop-validation, and so on. -Protocol daemons may also install routes with **zebra**. The **zebra** daemon -manages which routes are installed into the forwarding table with the kernel. +The Zebra protocol (or ``ZAPI``) is used by protocol daemons to +communicate with the **zebra** daemon. + +Each protocol daemon may request and send information to and from the +**zebra** daemon such as interface states, routing state, +nexthop-validation, and so on. Protocol daemons may also install +routes with **zebra**. The **zebra** daemon manages which routes are +installed into the forwarding table with the kernel. Some daemons use +more than one ZAPI connection. This is supported: each ZAPI session is +identified by a tuple of: ``{protocol, instance, session_id}``. LDPD +is an example: it uses a second, synchronous ZAPI session to manage +label blocks. The default value for ``session_id`` is zero; daemons +who use multiple ZAPI sessions must assign unique values to the +sessions' ids. The Zebra protocol is a streaming protocol, with a common header. Version 0 lacks a version field and is implicitly versioned. Version 1 and all subsequent diff --git a/doc/user/basic.rst b/doc/user/basic.rst index edcfce45ad..5b7786de18 100644 --- a/doc/user/basic.rst +++ b/doc/user/basic.rst @@ -86,6 +86,15 @@ Basic Config Commands debugging. Note that the existing code logs its most important messages with severity ``errors``. + .. warning:: + + FRRouting uses the ``writev()`` system call to write log messages. This + call is supposed to be atomic, but in reality this does not hold for + pipes or terminals, only regular files. This means that in rare cases, + concurrent log messages from distinct threads may get jumbled in + terminal output. Use a log file and ``tail -f`` if this rare chance is + inacceptable to your setup. + .. index:: single: no log file [FILENAME [LEVEL]] single: log file FILENAME [LEVEL] @@ -104,14 +113,6 @@ Basic Config Commands deprecated ``log trap`` command) will be used. The ``no`` form of the command disables logging to a file. - .. note:: - - If you do not configure any file logging, and a daemon crashes due to a - signal or an assertion failure, it will attempt to save the crash - information in a file named :file:`/var/tmp/frr.<daemon name>.crashlog`. - For security reasons, this will not happen if the file exists already, so - it is important to delete the file after reporting the crash information. - .. index:: single: no log syslog [LEVEL] single: log syslog [LEVEL] diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index d84bffc3c6..eb718007e8 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -414,7 +414,11 @@ Require policy on EBGP .. index:: [no] bgp ebgp-requires-policy .. clicmd:: [no] bgp ebgp-requires-policy - This command requires incoming and outgoing filters to be applied for eBGP sessions. Without the incoming filter, no routes will be accepted. Without the outgoing filter, no routes will be announced. + This command requires incoming and outgoing filters to be applied + for eBGP sessions. Without the incoming filter, no routes will be + accepted. Without the outgoing filter, no routes will be announced. + + This is enabled by default. Reject routes with AS_SET or AS_CONFED_SET types ------------------------------------------------ @@ -2646,7 +2650,14 @@ structure is extended with :clicmd:`show bgp [afi] [safi]`. These commands display BGP routes for the specific routing table indicated by the selected afi and the selected safi. If no afi and no safi value is given, - the command falls back to the default IPv6 routing table + the command falls back to the default IPv6 routing table. + For EVPN prefixes, you can display the full BGP table for this AFI/SAFI + using the standard `show bgp [afi] [safi]` syntax. + +.. index:: show bgp l2vpn evpn route [type <macip|2|multicast|3|es|4|prefix|5>] +.. clicmd:: show bgp l2vpn evpn route [type <macip|2|multicast|3|es|4|prefix|5>] + + Additionally, you can also filter this output by route type. .. index:: show bgp [afi] [safi] summary .. clicmd:: show bgp [afi] [safi] summary diff --git a/doc/user/ipv6.rst b/doc/user/ipv6.rst index f3f064b850..8af54ee23d 100644 --- a/doc/user/ipv6.rst +++ b/doc/user/ipv6.rst @@ -91,6 +91,17 @@ Router Advertisement Default: enabled .. index:: + single: ipv6 nd ra-hop-limit (0-255) + single: no ipv6 nd ra-hop-limit [(0-255)] +.. clicmd:: [no] ipv6 nd ra-hop-limit [(0-255)] + + The value to be placed in the hop count field of router advertisements sent + from the interface, in hops. Indicates the maximum diameter of the network. + Setting the value to zero indicates that the value is unspecified by this + router. Must be between zero or 255 hops. + Default: ``64`` + +.. index:: single: ipv6 nd ra-lifetime (0-9000) single: no ipv6 nd ra-lifetime [(0-9000)] .. clicmd:: [no] ipv6 nd ra-lifetime [(0-9000)] diff --git a/doc/user/pim.rst b/doc/user/pim.rst index f0ec2d26ff..2944e0b705 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -178,6 +178,14 @@ Certain signals have special meanings to *pimd*. the existing IGMP general query timer.If no version is provided in the cli, it will be considered as default v2 query.This is a hidden command. +.. index:: [no] ip igmp watermark-warn (10-60000) +.. clicmd:: [no] ip igmp watermark-warn (10-60000) + + Configure watermark warning generation for an igmp group limit. Generates + warning once the configured group limit is reached while adding new groups. + 'no' form of the command disables the warning generation. This command is + vrf aware. To configure per vrf, enter vrf submode. + .. _pim-interface-configuration: PIM Interface Configuration diff --git a/doc/user/setup.rst b/doc/user/setup.rst index 6d61a970d2..f60a66b9fd 100644 --- a/doc/user/setup.rst +++ b/doc/user/setup.rst @@ -6,6 +6,22 @@ Basic Setup After installing FRR, some basic configuration must be completed before it is ready to use. +Crash logs +---------- + +If any daemon should crash for some reason (segmentation fault, assertion +failure, etc.), it will attempt to write a backtrace to a file located in +:file:`/var/tmp/frr/<daemon>[-<instance>].<pid>/crashlog`. This feature is +not affected by any configuration options. + +The crashlog file's directory also contains files corresponding to per-thread +message buffers in files named +:file:`/var/tmp/frr/<daemon>[-<instance>].<pid>/logbuf.<tid>`. In case of a +crash, these may contain unwritten buffered log messages. To show the contents +of these buffers, pipe their contents through ``tr '\0' '\n'``. A blank line +marks the end of valid unwritten data (it will generally be followed by +garbled, older log messages since the buffer is not cleared.) + Daemons Configuration File -------------------------- After a fresh install, starting FRR will do nothing. This is because daemons diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 520080e83a..9dfd08f733 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -736,43 +736,30 @@ these cases, the FIB needs to be maintained reliably in the fast path as well. We refer to the component that programs the forwarding plane (directly or indirectly) as the Forwarding Plane Manager or FPM. -The FIB push interface comprises of a TCP connection between zebra and -the FPM. The connection is initiated by zebra -- that is, the FPM acts -as the TCP server. - .. program:: configure The relevant zebra code kicks in when zebra is configured with the -:option:`--enable-fpm` flag. Zebra periodically attempts to connect to -the well-known FPM port. Once the connection is up, zebra starts -sending messages containing routes over the socket to the FPM. Zebra -sends a complete copy of the forwarding table to the FPM, including -routes that it may have picked up from the kernel. The existing -interaction of zebra with the kernel remains unchanged -- that is, the -kernel continues to receive FIB updates as before. - -The encapsulation header for the messages exchanged with the FPM is -defined by the file :file:`fpm/fpm.h` in the frr tree. The routes -themselves are encoded in Netlink or protobuf format, with Netlink -being the default. - -Protobuf is one of a number of new serialization formats wherein the -message schema is expressed in a purpose-built language. Code for -encoding/decoding to/from the wire format is generated from the -schema. Protobuf messages can be extended easily while maintaining -backward-compatibility with older code. Protobuf has the following -advantages over Netlink: - -- Code for serialization/deserialization is generated automatically. This - reduces the likelihood of bugs, allows third-party programs to be integrated - quickly, and makes it easy to add fields. -- The message format is not tied to an OS (Linux), and can be evolved - independently. - -As mentioned before, zebra encodes routes sent to the FPM in Netlink -format by default. The format can be controlled via the FPM module's -load-time option to zebra, which currently takes the values `Netlink` -and `protobuf`. +:option:`--enable-fpm` flag and started with the module (``-M fpm`` +or ``-M dplane_fpm_nl``). + +.. note:: + + The ``fpm`` implementation attempts to connect to ``127.0.0.1`` port ``2620`` + by default without configurations. The ``dplane_fpm_nl`` only attempts to + connect to a server if configured. + +Zebra periodically attempts to connect to the well-known FPM port (``2620``). +Once the connection is up, zebra starts sending messages containing routes +over the socket to the FPM. Zebra sends a complete copy of the forwarding +table to the FPM, including routes that it may have picked up from the kernel. +The existing interaction of zebra with the kernel remains unchanged -- that +is, the kernel continues to receive FIB updates as before. + +The default FPM message format is netlink, however it can be controlled +with the module load-time option. The modules accept the following options: + +- ``fpm``: ``netlink`` and ``protobuf``. +- ``dplane_fpm_nl``: none, it only implements netlink. The zebra FPM interface uses replace semantics. That is, if a 'route add' message for a prefix is followed by another 'route add' message, @@ -782,6 +769,121 @@ replaces the information sent in the first message. If the connection to the FPM goes down for some reason, zebra sends the FPM a complete copy of the forwarding table(s) when it reconnects. +For more details on the implementation, please read the developer's manual FPM +section. + +FPM Commands +============ + +``fpm`` implementation +---------------------- + +.. index:: fpm connection ip A.B.C.D port (1-65535) +.. clicmd:: fpm connection ip A.B.C.D port (1-65535) + + Configure ``zebra`` to connect to a different FPM server than + ``127.0.0.1`` port ``2620``. + + +.. index:: no fpm connection ip A.B.C.D port (1-65535) +.. clicmd:: no fpm connection ip A.B.C.D port (1-65535) + + Configure ``zebra`` to connect to the default FPM server at ``127.0.0.1`` + port ``2620``. + + +.. index:: show zebra fpm stats +.. clicmd:: show zebra fpm stats + + Shows the FPM statistics. + + Sample output: + + :: + + Counter Total Last 10 secs + + connect_calls 3 2 + connect_no_sock 0 0 + read_cb_calls 2 2 + write_cb_calls 2 0 + write_calls 1 0 + partial_writes 0 0 + max_writes_hit 0 0 + t_write_yields 0 0 + nop_deletes_skipped 6 0 + route_adds 5 0 + route_dels 0 0 + updates_triggered 11 0 + redundant_triggers 0 0 + dests_del_after_update 0 0 + t_conn_down_starts 0 0 + t_conn_down_dests_processed 0 0 + t_conn_down_yields 0 0 + t_conn_down_finishes 0 0 + t_conn_up_starts 1 0 + t_conn_up_dests_processed 11 0 + t_conn_up_yields 0 0 + t_conn_up_aborts 0 0 + t_conn_up_finishes 1 0 + + +.. index:: clear zebra fpm stats +.. clicmd:: clear zebra fpm stats + + Reset statistics related to the zebra code that interacts with the + optional Forwarding Plane Manager (FPM) component. + + +``dplane_fpm_nl`` implementation +-------------------------------- + +.. index:: fpm address <A.B.C.D|X:X::X:X> [port (1-65535)] +.. clicmd:: fpm address <A.B.C.D|X:X::X:X> [port (1-65535)] + + Configures the FPM server address. Once configured ``zebra`` will attempt + to connect to it immediately. + + +.. index:: no fpm address [<A.B.C.D|X:X::X:X> [port (1-65535)]] +.. clicmd:: no fpm address [<A.B.C.D|X:X::X:X> [port (1-65535)]] + + Disables FPM entirely. ``zebra`` will close any current connections and + will not attempt to connect to it anymore. + + +.. index:: show fpm counters [json] +.. clicmd:: show fpm counters [json] + + Show the FPM statistics (plain text or JSON formatted). + + Sample output: + + :: + + FPM counters + ============ + Input bytes: 0 + Output bytes: 308 + Output buffer current size: 0 + Output buffer peak size: 308 + Connection closes: 0 + Connection errors: 0 + Data plane items processed: 0 + Data plane items enqueued: 0 + Data plane items queue peak: 0 + Buffer full hits: 0 + User FPM configurations: 1 + User FPM disable requests: 0 + + +.. index:: clear fpm counters +.. clicmd:: clear fpm counters + + Reset statistics related to the zebra code that interacts with the + optional Forwarding Plane Manager (FPM) component. + + .. _zebra-dplane: Dataplane Commands @@ -899,18 +1001,6 @@ zebra Terminal Mode Commands total number of route nodes in the table. Which will be higher than the actual number of routes that are held. -.. index:: show zebra fpm stats -.. clicmd:: show zebra fpm stats - - Display statistics related to the zebra code that interacts with the - optional Forwarding Plane Manager (FPM) component. - -.. index:: clear zebra fpm stats -.. clicmd:: clear zebra fpm stats - - Reset statistics related to the zebra code that interacts with the - optional Forwarding Plane Manager (FPM) component. - .. index:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] .. clicmd:: show nexthop-group rib [ID] [vrf NAME] diff --git a/eigrpd/eigrp_cli.c b/eigrpd/eigrp_cli.c index a93d4c8280..c76e067685 100644 --- a/eigrpd/eigrp_cli.c +++ b/eigrpd/eigrp_cli.c @@ -838,7 +838,14 @@ void eigrp_cli_show_keychain(struct vty *vty, struct lyd_node *dnode, /* * CLI installation procedures. */ -static struct cmd_node eigrp_node = {EIGRP_NODE, "%s(config-router)# ", 1}; +static int eigrp_config_write(struct vty *vty); +static struct cmd_node eigrp_node = { + .name = "eigrp", + .node = EIGRP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", + .config_write = eigrp_config_write, +}; static int eigrp_config_write(struct vty *vty) { @@ -854,8 +861,14 @@ static int eigrp_config_write(struct vty *vty) return written; } -static struct cmd_node eigrp_interface_node = {INTERFACE_NODE, - "%s(config-if)# ", 1}; +static int eigrp_write_interface(struct vty *vty); +static struct cmd_node eigrp_interface_node = { + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = eigrp_write_interface, +}; static int eigrp_write_interface(struct vty *vty) @@ -888,7 +901,7 @@ eigrp_cli_init(void) install_element(CONFIG_NODE, &router_eigrp_cmd); install_element(CONFIG_NODE, &no_router_eigrp_cmd); - install_node(&eigrp_node, eigrp_config_write); + install_node(&eigrp_node); install_default(EIGRP_NODE); install_element(EIGRP_NODE, &eigrp_router_id_cmd); @@ -906,7 +919,7 @@ eigrp_cli_init(void) install_element(EIGRP_NODE, &eigrp_neighbor_cmd); install_element(EIGRP_NODE, &eigrp_redistribute_source_metric_cmd); - install_node(&eigrp_interface_node, eigrp_write_interface); + install_node(&eigrp_interface_node); if_cmd_init(); install_element(INTERFACE_NODE, &eigrp_if_delay_cmd); diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 7278b002d8..a3d6eb2e9e 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -555,14 +555,18 @@ DEFUN (no_debug_eigrp_packets, } /* Debug node. */ +static int config_write_debug(struct vty *vty); static struct cmd_node eigrp_debug_node = { - DEBUG_NODE, "", 1 /* VTYSH */ + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = config_write_debug, }; /* Initialize debug commands. */ void eigrp_debug_init(void) { - install_node(&eigrp_debug_node, config_write_debug); + install_node(&eigrp_debug_node); install_element(ENABLE_NODE, &show_debugging_eigrp_cmd); install_element(ENABLE_NODE, &debug_eigrp_packets_all_cmd); diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index add758fa21..cdf1c6acdb 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -141,6 +141,7 @@ static const struct frr_yang_module_info *const eigrpd_yang_modules[] = { &frr_eigrpd_info, &frr_interface_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(eigrpd, EIGRP, .vty_port = EIGRP_VTY_PORT, diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c index e03ebb4fcb..13887368f7 100644 --- a/eigrpd/eigrp_northbound.c +++ b/eigrpd/eigrp_northbound.c @@ -74,49 +74,47 @@ static struct eigrp_interface *eigrp_interface_lookup(const struct eigrp *eigrp, /* * XPath: /frr-eigrpd:eigrpd/instance */ -static int eigrpd_instance_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_create(struct nb_cb_create_args *args) { struct eigrp *eigrp; const char *vrf; vrf_id_t vrfid; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* NOTHING */ break; case NB_EV_PREPARE: - vrf = yang_dnode_get_string(dnode, "./vrf"); + vrf = yang_dnode_get_string(args->dnode, "./vrf"); vrfid = vrf_name_to_id(vrf); - eigrp = eigrp_get(yang_dnode_get_uint16(dnode, "./asn"), vrfid); - resource->ptr = eigrp; + eigrp = eigrp_get(yang_dnode_get_uint16(args->dnode, "./asn"), + vrfid); + args->resource->ptr = eigrp; break; case NB_EV_ABORT: - eigrp_finish_final(resource->ptr); + eigrp_finish_final(args->resource->ptr); break; case NB_EV_APPLY: - nb_running_set_entry(dnode, resource->ptr); + nb_running_set_entry(args->dnode, args->resource->ptr); break; } return NB_OK; } -static int eigrpd_instance_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_unset_entry(dnode); + eigrp = nb_running_unset_entry(args->dnode); eigrp_finish_final(eigrp); break; } @@ -127,40 +125,38 @@ static int eigrpd_instance_destroy(enum nb_event event, /* * XPath: /frr-eigrpd:eigrpd/instance/router-id */ -static int eigrpd_instance_router_id_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_router_id_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv4(&eigrp->router_id_static, dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv4(&eigrp->router_id_static, args->dnode, + NULL); break; } return NB_OK; } -static int eigrpd_instance_router_id_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_router_id_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->router_id_static.s_addr = INADDR_ANY; break; } @@ -172,17 +168,15 @@ static int eigrpd_instance_router_id_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/passive-interface */ static int -eigrpd_instance_passive_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_passive_interface_create(struct nb_cb_create_args *args) { struct eigrp_interface *eif; struct eigrp *eigrp; const char *ifname; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - eigrp = nb_running_get_entry(dnode, NULL, false); + eigrp = nb_running_get_entry(args->dnode, NULL, false); if (eigrp == NULL) { /* * XXX: we can't verify if the interface exists @@ -191,7 +185,7 @@ eigrpd_instance_passive_interface_create(enum nb_event event, break; } - ifname = yang_dnode_get_string(dnode, NULL); + ifname = yang_dnode_get_string(args->dnode, NULL); eif = eigrp_interface_lookup(eigrp, ifname); if (eif == NULL) return NB_ERR_INCONSISTENCY; @@ -201,8 +195,8 @@ eigrpd_instance_passive_interface_create(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); eif = eigrp_interface_lookup(eigrp, ifname); if (eif == NULL) return NB_ERR_INCONSISTENCY; @@ -215,22 +209,21 @@ eigrpd_instance_passive_interface_create(enum nb_event event, } static int -eigrpd_instance_passive_interface_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args) { struct eigrp_interface *eif; struct eigrp *eigrp; const char *ifname; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); eif = eigrp_interface_lookup(eigrp, ifname); if (eif == NULL) break; @@ -245,11 +238,9 @@ eigrpd_instance_passive_interface_destroy(enum nb_event event, /* * XPath: /frr-eigrpd:eigrpd/instance/active-time */ -static int eigrpd_instance_active_time_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_active_time_modify(struct nb_cb_modify_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -266,40 +257,37 @@ static int eigrpd_instance_active_time_modify(enum nb_event event, /* * XPath: /frr-eigrpd:eigrpd/instance/variance */ -static int eigrpd_instance_variance_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_variance_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->variance = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->variance = yang_dnode_get_uint8(args->dnode, NULL); break; } return NB_OK; } -static int eigrpd_instance_variance_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_variance_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->variance = EIGRP_VARIANCE_DEFAULT; break; } @@ -310,40 +298,38 @@ static int eigrpd_instance_variance_destroy(enum nb_event event, /* * XPath: /frr-eigrpd:eigrpd/instance/maximum-paths */ -static int eigrpd_instance_maximum_paths_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_maximum_paths_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->max_paths = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->max_paths = yang_dnode_get_uint8(args->dnode, NULL); break; } return NB_OK; } -static int eigrpd_instance_maximum_paths_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int +eigrpd_instance_maximum_paths_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->max_paths = EIGRP_MAX_PATHS_DEFAULT; break; } @@ -355,21 +341,19 @@ static int eigrpd_instance_maximum_paths_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K1 */ static int -eigrpd_instance_metric_weights_K1_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_metric_weights_K1_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->k_values[0] = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->k_values[0] = yang_dnode_get_uint8(args->dnode, NULL); break; } @@ -377,19 +361,18 @@ eigrpd_instance_metric_weights_K1_modify(enum nb_event event, } static int -eigrpd_instance_metric_weights_K1_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_metric_weights_K1_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->k_values[0] = EIGRP_K1_DEFAULT; break; } @@ -401,21 +384,19 @@ eigrpd_instance_metric_weights_K1_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K2 */ static int -eigrpd_instance_metric_weights_K2_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_metric_weights_K2_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->k_values[1] = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->k_values[1] = yang_dnode_get_uint8(args->dnode, NULL); break; } @@ -423,19 +404,18 @@ eigrpd_instance_metric_weights_K2_modify(enum nb_event event, } static int -eigrpd_instance_metric_weights_K2_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_metric_weights_K2_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->k_values[1] = EIGRP_K2_DEFAULT; break; } @@ -447,21 +427,19 @@ eigrpd_instance_metric_weights_K2_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K3 */ static int -eigrpd_instance_metric_weights_K3_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_metric_weights_K3_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->k_values[2] = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->k_values[2] = yang_dnode_get_uint8(args->dnode, NULL); break; } @@ -469,19 +447,18 @@ eigrpd_instance_metric_weights_K3_modify(enum nb_event event, } static int -eigrpd_instance_metric_weights_K3_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_metric_weights_K3_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->k_values[2] = EIGRP_K3_DEFAULT; break; } @@ -493,21 +470,19 @@ eigrpd_instance_metric_weights_K3_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K4 */ static int -eigrpd_instance_metric_weights_K4_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_metric_weights_K4_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->k_values[3] = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->k_values[3] = yang_dnode_get_uint8(args->dnode, NULL); break; } @@ -515,19 +490,18 @@ eigrpd_instance_metric_weights_K4_modify(enum nb_event event, } static int -eigrpd_instance_metric_weights_K4_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_metric_weights_K4_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->k_values[3] = EIGRP_K4_DEFAULT; break; } @@ -539,21 +513,19 @@ eigrpd_instance_metric_weights_K4_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K5 */ static int -eigrpd_instance_metric_weights_K5_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_metric_weights_K5_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->k_values[4] = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->k_values[4] = yang_dnode_get_uint8(args->dnode, NULL); break; } @@ -561,19 +533,18 @@ eigrpd_instance_metric_weights_K5_modify(enum nb_event event, } static int -eigrpd_instance_metric_weights_K5_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_metric_weights_K5_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->k_values[4] = EIGRP_K5_DEFAULT; break; } @@ -585,21 +556,19 @@ eigrpd_instance_metric_weights_K5_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/metric-weights/K6 */ static int -eigrpd_instance_metric_weights_K6_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_metric_weights_K6_modify(struct nb_cb_modify_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - eigrp->k_values[5] = yang_dnode_get_uint8(dnode, NULL); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + eigrp->k_values[5] = yang_dnode_get_uint8(args->dnode, NULL); break; } @@ -607,19 +576,18 @@ eigrpd_instance_metric_weights_K6_modify(enum nb_event event, } static int -eigrpd_instance_metric_weights_K6_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_metric_weights_K6_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp->k_values[5] = EIGRP_K6_DEFAULT; break; } @@ -630,20 +598,18 @@ eigrpd_instance_metric_weights_K6_destroy(enum nb_event event, /* * XPath: /frr-eigrpd:eigrpd/instance/network */ -static int eigrpd_instance_network_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_network_create(struct nb_cb_create_args *args) { struct route_node *rnode; struct prefix prefix; struct eigrp *eigrp; int exists; - yang_dnode_get_ipv4p(&prefix, dnode, NULL); + yang_dnode_get_ipv4p(&prefix, args->dnode, NULL); - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - eigrp = nb_running_get_entry(dnode, NULL, false); + eigrp = nb_running_get_entry(args->dnode, NULL, false); /* If entry doesn't exist it means the list is empty. */ if (eigrp == NULL) break; @@ -659,7 +625,7 @@ static int eigrpd_instance_network_create(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); if (eigrp_network_set(eigrp, &prefix) == 0) return NB_ERR_INCONSISTENCY; break; @@ -668,19 +634,18 @@ static int eigrpd_instance_network_create(enum nb_event event, return NB_OK; } -static int eigrpd_instance_network_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_network_destroy(struct nb_cb_destroy_args *args) { struct route_node *rnode; struct prefix prefix; struct eigrp *eigrp; int exists = 0; - yang_dnode_get_ipv4p(&prefix, dnode, NULL); + yang_dnode_get_ipv4p(&prefix, args->dnode, NULL); - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - eigrp = nb_running_get_entry(dnode, NULL, false); + eigrp = nb_running_get_entry(args->dnode, NULL, false); /* If entry doesn't exist it means the list is empty. */ if (eigrp == NULL) break; @@ -696,7 +661,7 @@ static int eigrpd_instance_network_destroy(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); + eigrp = nb_running_get_entry(args->dnode, NULL, true); eigrp_network_unset(eigrp, &prefix); break; } @@ -707,11 +672,9 @@ static int eigrpd_instance_network_destroy(enum nb_event event, /* * XPath: /frr-eigrpd:eigrpd/instance/neighbor */ -static int eigrpd_instance_neighbor_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_neighbor_create(struct nb_cb_create_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -725,10 +688,9 @@ static int eigrpd_instance_neighbor_create(enum nb_event event, return NB_OK; } -static int eigrpd_instance_neighbor_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_neighbor_destroy(struct nb_cb_destroy_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -745,9 +707,7 @@ static int eigrpd_instance_neighbor_destroy(enum nb_event event, /* * XPath: /frr-eigrpd:eigrpd/instance/redistribute */ -static int eigrpd_instance_redistribute_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_redistribute_create(struct nb_cb_create_args *args) { struct eigrp_metrics metrics; const char *vrfname; @@ -755,10 +715,10 @@ static int eigrpd_instance_redistribute_create(enum nb_event event, uint32_t proto; vrf_id_t vrfid; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - proto = yang_dnode_get_enum(dnode, "./protocol"); - vrfname = yang_dnode_get_string(dnode, "../vrf"); + proto = yang_dnode_get_enum(args->dnode, "./protocol"); + vrfname = yang_dnode_get_string(args->dnode, "../vrf"); vrfid = vrf_name_to_id(vrfname); if (vrf_bitmap_check(zclient->redist[AFI_IP][proto], vrfid)) return NB_ERR_INCONSISTENCY; @@ -768,9 +728,9 @@ static int eigrpd_instance_redistribute_create(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - proto = yang_dnode_get_enum(dnode, "./protocol"); - redistribute_get_metrics(dnode, &metrics); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + proto = yang_dnode_get_enum(args->dnode, "./protocol"); + redistribute_get_metrics(args->dnode, &metrics); eigrp_redistribute_set(eigrp, proto, metrics); break; } @@ -778,21 +738,20 @@ static int eigrpd_instance_redistribute_create(enum nb_event event, return NB_OK; } -static int eigrpd_instance_redistribute_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_redistribute_destroy(struct nb_cb_destroy_args *args) { struct eigrp *eigrp; uint32_t proto; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - proto = yang_dnode_get_enum(dnode, "./protocol"); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + proto = yang_dnode_get_enum(args->dnode, "./protocol"); eigrp_redistribute_unset(eigrp, proto); break; } @@ -804,11 +763,9 @@ static int eigrpd_instance_redistribute_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map */ static int -eigrpd_instance_redistribute_route_map_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -823,10 +780,9 @@ eigrpd_instance_redistribute_route_map_modify(enum nb_event event, } static int -eigrpd_instance_redistribute_route_map_destroy(enum nb_event event, - const struct lyd_node *dnode) +eigrpd_instance_redistribute_route_map_destroy(struct nb_cb_destroy_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -844,23 +800,22 @@ eigrpd_instance_redistribute_route_map_destroy(enum nb_event event, * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/bandwidth */ static int eigrpd_instance_redistribute_metrics_bandwidth_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct eigrp_metrics metrics; struct eigrp *eigrp; uint32_t proto; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - proto = yang_dnode_get_enum(dnode, "../../protocol"); - redistribute_get_metrics(dnode, &metrics); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + proto = yang_dnode_get_enum(args->dnode, "../../protocol"); + redistribute_get_metrics(args->dnode, &metrics); eigrp_redistribute_set(eigrp, proto, metrics); break; } @@ -869,22 +824,22 @@ static int eigrpd_instance_redistribute_metrics_bandwidth_modify( } static int eigrpd_instance_redistribute_metrics_bandwidth_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { struct eigrp_metrics metrics; struct eigrp *eigrp; uint32_t proto; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eigrp = nb_running_get_entry(dnode, NULL, true); - proto = yang_dnode_get_enum(dnode, "../../protocol"); - redistribute_get_metrics(dnode, &metrics); + eigrp = nb_running_get_entry(args->dnode, NULL, true); + proto = yang_dnode_get_enum(args->dnode, "../../protocol"); + redistribute_get_metrics(args->dnode, &metrics); eigrp_redistribute_set(eigrp, proto, metrics); break; } @@ -895,98 +850,74 @@ static int eigrpd_instance_redistribute_metrics_bandwidth_destroy( /* * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/delay */ -static int -eigrpd_instance_redistribute_metrics_delay_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int eigrpd_instance_redistribute_metrics_delay_modify( + struct nb_cb_modify_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_modify(event, - dnode, - resource); + return eigrpd_instance_redistribute_metrics_bandwidth_modify(args); } -static int -eigrpd_instance_redistribute_metrics_delay_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_redistribute_metrics_delay_destroy( + struct nb_cb_destroy_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event, - dnode); + return eigrpd_instance_redistribute_metrics_bandwidth_destroy(args); } /* * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/reliability */ static int eigrpd_instance_redistribute_metrics_reliability_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_modify(event, - dnode, - resource); + return eigrpd_instance_redistribute_metrics_bandwidth_modify(args); } static int eigrpd_instance_redistribute_metrics_reliability_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event, - dnode); + return eigrpd_instance_redistribute_metrics_bandwidth_destroy(args); } /* * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/load */ static int -eigrpd_instance_redistribute_metrics_load_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_redistribute_metrics_load_modify(struct nb_cb_modify_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_modify(event, - dnode, - resource); + return eigrpd_instance_redistribute_metrics_bandwidth_modify(args); } -static int -eigrpd_instance_redistribute_metrics_load_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_redistribute_metrics_load_destroy( + struct nb_cb_destroy_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event, - dnode); + return eigrpd_instance_redistribute_metrics_bandwidth_destroy(args); } /* * XPath: /frr-eigrpd:eigrpd/instance/redistribute/metrics/mtu */ static int -eigrpd_instance_redistribute_metrics_mtu_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +eigrpd_instance_redistribute_metrics_mtu_modify(struct nb_cb_modify_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_modify(event, - dnode, - resource); + return eigrpd_instance_redistribute_metrics_bandwidth_modify(args); } -static int -eigrpd_instance_redistribute_metrics_mtu_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int eigrpd_instance_redistribute_metrics_mtu_destroy( + struct nb_cb_destroy_args *args) { - return eigrpd_instance_redistribute_metrics_bandwidth_destroy(event, - dnode); + return eigrpd_instance_redistribute_metrics_bandwidth_destroy(args); } /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/delay */ -static int lib_interface_eigrp_delay_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_eigrp_delay_modify(struct nb_cb_modify_args *args) { struct eigrp_interface *ei; struct interface *ifp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - ifp = nb_running_get_entry(dnode, NULL, false); + ifp = nb_running_get_entry(args->dnode, NULL, false); if (ifp == NULL) { /* * XXX: we can't verify if the interface exists @@ -1004,12 +935,12 @@ static int lib_interface_eigrp_delay_modify(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ei = ifp->info; if (ei == NULL) return NB_ERR_INCONSISTENCY; - ei->params.delay = yang_dnode_get_uint32(dnode, NULL); + ei->params.delay = yang_dnode_get_uint32(args->dnode, NULL); eigrp_if_reset(ifp); break; } @@ -1020,16 +951,14 @@ static int lib_interface_eigrp_delay_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/bandwidth */ -static int lib_interface_eigrp_bandwidth_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_eigrp_bandwidth_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct eigrp_interface *ei; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - ifp = nb_running_get_entry(dnode, NULL, false); + ifp = nb_running_get_entry(args->dnode, NULL, false); if (ifp == NULL) { /* * XXX: we can't verify if the interface exists @@ -1047,12 +976,12 @@ static int lib_interface_eigrp_bandwidth_modify(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ei = ifp->info; if (ei == NULL) return NB_ERR_INCONSISTENCY; - ei->params.bandwidth = yang_dnode_get_uint32(dnode, NULL); + ei->params.bandwidth = yang_dnode_get_uint32(args->dnode, NULL); eigrp_if_reset(ifp); break; } @@ -1064,16 +993,14 @@ static int lib_interface_eigrp_bandwidth_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hello-interval */ static int -lib_interface_eigrp_hello_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_eigrp_hello_interval_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct eigrp_interface *ei; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - ifp = nb_running_get_entry(dnode, NULL, false); + ifp = nb_running_get_entry(args->dnode, NULL, false); if (ifp == NULL) { /* * XXX: we can't verify if the interface exists @@ -1091,12 +1018,12 @@ lib_interface_eigrp_hello_interval_modify(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ei = ifp->info; if (ei == NULL) return NB_ERR_INCONSISTENCY; - ei->params.v_hello = yang_dnode_get_uint16(dnode, NULL); + ei->params.v_hello = yang_dnode_get_uint16(args->dnode, NULL); break; } @@ -1106,16 +1033,14 @@ lib_interface_eigrp_hello_interval_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/hold-time */ -static int lib_interface_eigrp_hold_time_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_eigrp_hold_time_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct eigrp_interface *ei; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - ifp = nb_running_get_entry(dnode, NULL, false); + ifp = nb_running_get_entry(args->dnode, NULL, false); if (ifp == NULL) { /* * XXX: we can't verify if the interface exists @@ -1133,12 +1058,12 @@ static int lib_interface_eigrp_hold_time_modify(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ei = ifp->info; if (ei == NULL) return NB_ERR_INCONSISTENCY; - ei->params.v_wait = yang_dnode_get_uint16(dnode, NULL); + ei->params.v_wait = yang_dnode_get_uint16(args->dnode, NULL); break; } @@ -1149,11 +1074,9 @@ static int lib_interface_eigrp_hold_time_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/split-horizon */ static int -lib_interface_eigrp_split_horizon_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_eigrp_split_horizon_modify(struct nb_cb_modify_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -1170,17 +1093,15 @@ lib_interface_eigrp_split_horizon_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance */ -static int lib_interface_eigrp_instance_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_eigrp_instance_create(struct nb_cb_create_args *args) { struct eigrp_interface *eif; struct interface *ifp; struct eigrp *eigrp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - ifp = nb_running_get_entry(dnode, NULL, false); + ifp = nb_running_get_entry(args->dnode, NULL, false); if (ifp == NULL) { /* * XXX: we can't verify if the interface exists @@ -1189,7 +1110,7 @@ static int lib_interface_eigrp_instance_create(enum nb_event event, break; } - eigrp = eigrp_get(yang_dnode_get_uint16(dnode, "./asn"), + eigrp = eigrp_get(yang_dnode_get_uint16(args->dnode, "./asn"), ifp->vrf_id); eif = eigrp_interface_lookup(eigrp, ifp->name); if (eif == NULL) @@ -1200,31 +1121,30 @@ static int lib_interface_eigrp_instance_create(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - ifp = nb_running_get_entry(dnode, NULL, true); - eigrp = eigrp_get(yang_dnode_get_uint16(dnode, "./asn"), + ifp = nb_running_get_entry(args->dnode, NULL, true); + eigrp = eigrp_get(yang_dnode_get_uint16(args->dnode, "./asn"), ifp->vrf_id); eif = eigrp_interface_lookup(eigrp, ifp->name); if (eif == NULL) return NB_ERR_INCONSISTENCY; - nb_running_set_entry(dnode, eif); + nb_running_set_entry(args->dnode, eif); break; } return NB_OK; } -static int lib_interface_eigrp_instance_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_interface_eigrp_instance_destroy(struct nb_cb_destroy_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - nb_running_unset_entry(dnode); + nb_running_unset_entry(args->dnode); break; } @@ -1236,10 +1156,9 @@ static int lib_interface_eigrp_instance_destroy(enum nb_event event, * /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/summarize-addresses */ static int lib_interface_eigrp_instance_summarize_addresses_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -1254,9 +1173,9 @@ static int lib_interface_eigrp_instance_summarize_addresses_create( } static int lib_interface_eigrp_instance_summarize_addresses_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* TODO: Not implemented. */ return NB_ERR_INCONSISTENCY; @@ -1273,22 +1192,20 @@ static int lib_interface_eigrp_instance_summarize_addresses_destroy( /* * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/authentication */ -static int -lib_interface_eigrp_instance_authentication_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_eigrp_instance_authentication_modify( + struct nb_cb_modify_args *args) { struct eigrp_interface *eif; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eif = nb_running_get_entry(dnode, NULL, true); - eif->params.auth_type = yang_dnode_get_enum(dnode, NULL); + eif = nb_running_get_entry(args->dnode, NULL, true); + eif->params.auth_type = yang_dnode_get_enum(args->dnode, NULL); break; } @@ -1299,34 +1216,34 @@ lib_interface_eigrp_instance_authentication_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-eigrpd:eigrp/instance/keychain */ static int -lib_interface_eigrp_instance_keychain_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_eigrp_instance_keychain_modify(struct nb_cb_modify_args *args) { struct eigrp_interface *eif; struct keychain *keychain; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - keychain = keychain_lookup(yang_dnode_get_string(dnode, NULL)); + keychain = keychain_lookup( + yang_dnode_get_string(args->dnode, NULL)); if (keychain == NULL) return NB_ERR_INCONSISTENCY; break; case NB_EV_PREPARE: - resource->ptr = strdup(yang_dnode_get_string(dnode, NULL)); - if (resource->ptr == NULL) + args->resource->ptr = + strdup(yang_dnode_get_string(args->dnode, NULL)); + if (args->resource->ptr == NULL) return NB_ERR_RESOURCE; break; case NB_EV_ABORT: - free(resource->ptr); - resource->ptr = NULL; + free(args->resource->ptr); + args->resource->ptr = NULL; break; case NB_EV_APPLY: - eif = nb_running_get_entry(dnode, NULL, true); + eif = nb_running_get_entry(args->dnode, NULL, true); if (eif->params.auth_keychain) free(eif->params.auth_keychain); - eif->params.auth_keychain = resource->ptr; + eif->params.auth_keychain = args->resource->ptr; break; } @@ -1334,19 +1251,18 @@ lib_interface_eigrp_instance_keychain_modify(enum nb_event event, } static int -lib_interface_eigrp_instance_keychain_destroy(enum nb_event event, - const struct lyd_node *dnode) +lib_interface_eigrp_instance_keychain_destroy(struct nb_cb_destroy_args *args) { struct eigrp_interface *eif; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - eif = nb_running_get_entry(dnode, NULL, true); + eif = nb_running_get_entry(args->dnode, NULL, true); if (eif->params.auth_keychain) free(eif->params.auth_keychain); diff --git a/eigrpd/subdir.am b/eigrpd/subdir.am index e59c88b471..8b86b9c8a7 100644 --- a/eigrpd/subdir.am +++ b/eigrpd/subdir.am @@ -7,11 +7,11 @@ noinst_LIBRARIES += eigrpd/libeigrp.a sbin_PROGRAMS += eigrpd/eigrpd dist_examples_DATA += eigrpd/eigrpd.conf.sample vtysh_scan += \ - $(top_srcdir)/eigrpd/eigrp_cli.c \ - $(top_srcdir)/eigrpd/eigrp_dump.c \ - $(top_srcdir)/eigrpd/eigrp_vty.c \ + eigrpd/eigrp_cli.c \ + eigrpd/eigrp_dump.c \ + eigrpd/eigrp_vty.c \ # end -# $(top_srcdir)/eigrpd/eigrp_routemap.c +# eigrpd/eigrp_routemap.c man8 += $(MANBUILD)/frr-eigrpd.8 endif @@ -48,11 +48,10 @@ eigrpdheader_HEADERS = \ eigrpd/eigrpd.h \ # end -eigrpd/eigrp_vty_clippy.c: $(CLIPPY_DEPS) -eigrpd/eigrp_vty.$(OBJEXT): eigrpd/eigrp_vty_clippy.c - -eigrpd/eigrp_cli_clippy.c: $(CLIPPY_DEPS) -eigrpd/eigrp_cli.$(OBJEXT): eigrpd/eigrp_cli_clippy.c +clippy_scan += \ + eigrpd/eigrp_cli.c \ + eigrpd/eigrp_vty.c \ + # end noinst_HEADERS += \ eigrpd/eigrp_const.h \ diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 9beed206e8..4e0ee4448b 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -201,13 +201,14 @@ void isis_adj_process_threeway(struct isis_adjacency *adj, fabricd_initial_sync_hello(adj->circuit); if (next_tw_state == ISIS_THREEWAY_DOWN) { - isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Neighbor restarted"); + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, + "Neighbor restarted"); return; } if (next_tw_state == ISIS_THREEWAY_UP) { if (adj->adj_state != ISIS_ADJ_UP) { - isis_adj_state_change(adj, ISIS_ADJ_UP, NULL); + isis_adj_state_change(&adj, ISIS_ADJ_UP, NULL); adj->adj_usage = adj_usage; } } @@ -219,12 +220,13 @@ void isis_adj_process_threeway(struct isis_adjacency *adj, adj->threeway_state = next_tw_state; } -void isis_adj_state_change(struct isis_adjacency *adj, +void isis_adj_state_change(struct isis_adjacency **padj, enum isis_adj_state new_state, const char *reason) { + struct isis_adjacency *adj = *padj; enum isis_adj_state old_state = adj->adj_state; struct isis_circuit *circuit = adj->circuit; - bool del; + bool del = false; adj->adj_state = new_state; if (new_state != old_state) { @@ -262,7 +264,6 @@ void isis_adj_state_change(struct isis_adjacency *adj, #endif /* ifndef FABRICD */ if (circuit->circ_type == CIRCUIT_T_BROADCAST) { - del = false; for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { if ((adj->level & level) == 0) continue; @@ -299,11 +300,7 @@ void isis_adj_state_change(struct isis_adjacency *adj, lsp_regenerate_schedule_pseudo(circuit, level); } - if (del) - isis_delete_adj(adj); - } else if (circuit->circ_type == CIRCUIT_T_P2P) { - del = false; for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) { if ((adj->level & level) == 0) continue; @@ -336,9 +333,11 @@ void isis_adj_state_change(struct isis_adjacency *adj, del = true; } } + } - if (del) - isis_delete_adj(adj); + if (del) { + isis_delete_adj(adj); + *padj = NULL; } } @@ -402,7 +401,7 @@ int isis_adj_expire(struct thread *thread) adj->t_expire = NULL; /* trigger the adj expire event */ - isis_adj_state_change(adj, ISIS_ADJ_DOWN, "holding time expired"); + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "holding time expired"); return 0; } diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h index 93583fc122..8f3d63c297 100644 --- a/isisd/isis_adjacency.h +++ b/isisd/isis_adjacency.h @@ -118,7 +118,7 @@ void isis_adj_process_threeway(struct isis_adjacency *adj, struct isis_threeway_adj *tw_adj, enum isis_adj_usage adj_usage); DECLARE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj)) -void isis_adj_state_change(struct isis_adjacency *adj, +void isis_adj_state_change(struct isis_adjacency **adj, enum isis_adj_state state, const char *reason); void isis_adj_print(struct isis_adjacency *adj); const char *isis_adj_yang_state(enum isis_adj_state state); diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c index 68be9c1a99..0f0d20e393 100644 --- a/isisd/isis_bfd.c +++ b/isisd/isis_bfd.c @@ -138,7 +138,7 @@ static void bfd_adj_event(struct isis_adjacency *adj, struct prefix *dst, return; } - isis_adj_state_change(adj, ISIS_ADJ_DOWN, "bfd session went down"); + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "bfd session went down"); } static int isis_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS) @@ -391,6 +391,7 @@ void isis_bfd_circuit_param_set(struct isis_circuit *circuit, isis_bfd_circuit_cmd(circuit, command); } +#ifdef FABRICD static int bfd_circuit_write_settings(struct isis_circuit *circuit, struct vty *vty) { @@ -402,6 +403,7 @@ static int bfd_circuit_write_settings(struct isis_circuit *circuit, vty_out(vty, " %s bfd\n", PROTO_NAME); return 1; } +#endif void isis_bfd_init(void) { @@ -413,6 +415,8 @@ void isis_bfd_init(void) zclient->bfd_dest_replay = isis_bfd_nbr_replay; hook_register(isis_adj_state_change_hook, bfd_handle_adj_state_change); +#ifdef FABRICD hook_register(isis_circuit_config_write, bfd_circuit_write_settings); +#endif } diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 7d4f7b355d..39118a2c86 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -67,7 +67,6 @@ DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp)) /* * Prototypes. */ -int isis_interface_config_write(struct vty *); int isis_if_new_hook(struct interface *); int isis_if_delete_hook(struct interface *); @@ -964,12 +963,12 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty, return; } +#ifdef FABRICD DEFINE_HOOK(isis_circuit_config_write, (struct isis_circuit *circuit, struct vty *vty), (circuit, vty)) -#ifdef FABRICD -int isis_interface_config_write(struct vty *vty) +static int isis_interface_config_write(struct vty *vty) { struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); int write = 0; @@ -1192,12 +1191,11 @@ int isis_interface_config_write(struct vty *vty) return write; } #else -int isis_interface_config_write(struct vty *vty) +static int isis_interface_config_write(struct vty *vty) { struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); int write = 0; struct interface *ifp; - struct isis_circuit *circuit; struct lyd_node *dnode; FOR_ALL_INTERFACES (vrf, ifp) { @@ -1210,10 +1208,6 @@ int isis_interface_config_write(struct vty *vty) write++; nb_cli_show_dnode_cmds(vty, dnode, false); - circuit = circuit_scan_by_ifp(ifp); - if (circuit) - write += hook_call(isis_circuit_config_write, circuit, - vty); } return write; } @@ -1336,7 +1330,11 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit, } struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", 1, + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = isis_interface_config_write, }; void isis_circuit_circ_type_set(struct isis_circuit *circuit, int circ_type) @@ -1441,7 +1439,7 @@ void isis_circuit_init(void) hook_register_prio(if_del, 0, isis_if_delete_hook); /* Install interface node */ - install_node(&interface_node, isis_interface_config_write); + install_node(&interface_node); if_cmd_init(); if_zapi_callbacks(isis_ifp_create, isis_ifp_up, isis_ifp_down, isis_ifp_destroy); diff --git a/isisd/isis_circuit.h b/isisd/isis_circuit.h index f677d3aded..7c380fb0d9 100644 --- a/isisd/isis_circuit.h +++ b/isisd/isis_circuit.h @@ -208,8 +208,10 @@ ferr_r isis_circuit_passwd_hmac_md5_set(struct isis_circuit *circuit, int isis_circuit_mt_enabled_set(struct isis_circuit *circuit, uint16_t mtid, bool enabled); +#ifdef FABRICD DECLARE_HOOK(isis_circuit_config_write, (struct isis_circuit *circuit, struct vty *vty), (circuit, vty)) +#endif #endif /* _ZEBRA_ISIS_CIRCUIT_H */ diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index c0b90e8439..effd19ed7d 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -603,7 +603,7 @@ static void lsp_set_time(struct isis_lsp *lsp) void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag) { struct isis_dynhn *dyn = NULL; - uint8_t id[SYSID_STRLEN]; + char id[SYSID_STRLEN]; if (dynhost) dyn = dynhn_find_by_id(lsp_id); @@ -611,9 +611,9 @@ void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag) dyn = NULL; if (dyn) - sprintf((char *)id, "%.14s", dyn->hostname); + snprintf(id, sizeof(id), "%.14s", dyn->hostname); else if (!memcmp(isis->sysid, lsp_id, ISIS_SYS_ID_LEN) && dynhost) - sprintf((char *)id, "%.14s", cmd_hostname_get()); + snprintf(id, sizeof(id), "%.14s", cmd_hostname_get()); else memcpy(id, sysid_print(lsp_id), 15); if (frag) @@ -659,7 +659,7 @@ void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost) vty_out(vty, "0x%08" PRIx32 " ", lsp->hdr.seqno); vty_out(vty, "0x%04" PRIx16 " ", lsp->hdr.checksum); if (lsp->hdr.rem_lifetime == 0) { - snprintf(age_out, 8, "(%d)", lsp->age_out); + snprintf(age_out, sizeof(age_out), "(%d)", lsp->age_out); age_out[7] = '\0'; vty_out(vty, "%7s ", age_out); } else diff --git a/isisd/isis_main.c b/isisd/isis_main.c index f7fe089b99..4c841dffe2 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -168,6 +168,7 @@ static const struct frr_yang_module_info *const isisd_yang_modules[] = { &frr_isisd_info, #endif /* ifndef FABRICD */ &frr_route_map_info, + &frr_vrf_info, }; #ifdef FABRICD diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c index 96b76da92d..25f7f8609b 100644 --- a/isisd/isis_misc.c +++ b/isisd/isis_misc.c @@ -29,6 +29,7 @@ #include "hash.h" #include "if.h" #include "command.h" +#include "network.h" #include "isisd/isis_constants.h" #include "isisd/isis_common.h" @@ -413,7 +414,7 @@ unsigned long isis_jitter(unsigned long timer, unsigned long jitter) * most IS-IS timers are no longer than 16 bit */ - j = 1 + (int)((RANDOM_SPREAD * random()) / (RAND_MAX + 1.0)); + j = 1 + (int)((RANDOM_SPREAD * frr_weak_random()) / (RAND_MAX + 1.0)); k = timer - (timer * (100 - jitter)) / 100; diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index e8e35ae63b..5c262049a9 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -302,6 +302,7 @@ circuit_get_mt_setting(struct isis_circuit *circuit, uint16_t mtid) return setting; } +#ifdef FABRICD static int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty) { @@ -318,6 +319,7 @@ static int circuit_write_mt_settings(struct isis_circuit *circuit, } return written; } +#endif struct isis_circuit_mt_setting ** circuit_mt_settings(struct isis_circuit *circuit, unsigned int *mt_count) @@ -552,6 +554,8 @@ void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit, void mt_init(void) { +#ifdef FABRICD hook_register(isis_circuit_config_write, circuit_write_mt_settings); +#endif } diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index e028dfd11b..65aa95cd69 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -28,379 +28,247 @@ struct isis_circuit; struct isis_adjacency; /* Mandatory callbacks. */ -int isis_instance_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_destroy(enum nb_event event, const struct lyd_node *dnode); -int isis_instance_is_type_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_area_address_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_area_address_destroy(enum nb_event event, - const struct lyd_node *dnode); -int isis_instance_dynamic_hostname_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_attached_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_overload_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_metric_style_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_purge_originator_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_lsp_mtu_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); +int isis_instance_create(struct nb_cb_create_args *args); +int isis_instance_destroy(struct nb_cb_destroy_args *args); +int isis_instance_is_type_modify(struct nb_cb_modify_args *args); +int isis_instance_area_address_create(struct nb_cb_create_args *args); +int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args); +int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args); +int isis_instance_attached_modify(struct nb_cb_modify_args *args); +int isis_instance_overload_modify(struct nb_cb_modify_args *args); +int isis_instance_metric_style_modify(struct nb_cb_modify_args *args); +int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args); +int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args); int isis_instance_lsp_refresh_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_lsp_refresh_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_lsp_maximum_lifetime_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_lsp_maximum_lifetime_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_lsp_generation_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_lsp_generation_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_spf_ietf_backoff_delay_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_spf_ietf_backoff_delay_destroy(enum nb_event event, - const struct lyd_node *dnode); + struct nb_cb_modify_args *args); +int isis_instance_spf_ietf_backoff_delay_create(struct nb_cb_create_args *args); +int isis_instance_spf_ietf_backoff_delay_destroy( + struct nb_cb_destroy_args *args); int isis_instance_spf_ietf_backoff_delay_init_delay_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_spf_ietf_backoff_delay_short_delay_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_spf_ietf_backoff_delay_long_delay_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_spf_ietf_backoff_delay_hold_down_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_spf_minimum_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_spf_minimum_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_area_password_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_area_password_destroy(enum nb_event event, - const struct lyd_node *dnode); -int isis_instance_area_password_password_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int isis_instance_area_password_create(struct nb_cb_create_args *args); +int isis_instance_area_password_destroy(struct nb_cb_destroy_args *args); +int isis_instance_area_password_password_modify(struct nb_cb_modify_args *args); int isis_instance_area_password_password_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_area_password_authenticate_snp_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_domain_password_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_domain_password_destroy(enum nb_event event, - const struct lyd_node *dnode); -int isis_instance_domain_password_password_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int isis_instance_domain_password_create(struct nb_cb_create_args *args); +int isis_instance_domain_password_destroy(struct nb_cb_destroy_args *args); +int isis_instance_domain_password_password_modify( + struct nb_cb_modify_args *args); int isis_instance_domain_password_password_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_domain_password_authenticate_snp_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_default_information_originate_ipv4_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_default_information_originate_ipv4_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_default_information_originate_ipv4_always_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_default_information_originate_ipv4_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_default_information_originate_ipv4_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_default_information_originate_ipv4_metric_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_default_information_originate_ipv6_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_default_information_originate_ipv6_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_default_information_originate_ipv6_always_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_default_information_originate_ipv6_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_default_information_originate_ipv6_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_default_information_originate_ipv6_metric_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_redistribute_ipv4_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_redistribute_ipv4_destroy(enum nb_event event, - const struct lyd_node *dnode); + struct nb_cb_modify_args *args); +int isis_instance_redistribute_ipv4_create(struct nb_cb_create_args *args); +int isis_instance_redistribute_ipv4_destroy(struct nb_cb_destroy_args *args); int isis_instance_redistribute_ipv4_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_redistribute_ipv4_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode); -int isis_instance_redistribute_ipv4_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_redistribute_ipv6_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_redistribute_ipv6_destroy(enum nb_event event, - const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); +int isis_instance_redistribute_ipv4_metric_modify( + struct nb_cb_modify_args *args); +int isis_instance_redistribute_ipv6_create(struct nb_cb_create_args *args); +int isis_instance_redistribute_ipv6_destroy(struct nb_cb_destroy_args *args); int isis_instance_redistribute_ipv6_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_redistribute_ipv6_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode); -int isis_instance_redistribute_ipv6_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_destroy_args *args); +int isis_instance_redistribute_ipv6_metric_modify( + struct nb_cb_modify_args *args); int isis_instance_multi_topology_ipv4_multicast_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_multi_topology_ipv4_multicast_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_multi_topology_ipv4_multicast_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_multi_topology_ipv4_management_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_multi_topology_ipv4_management_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_multi_topology_ipv4_management_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_multi_topology_ipv6_unicast_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_multi_topology_ipv6_unicast_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_multi_topology_ipv6_unicast_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_multi_topology_ipv6_multicast_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_multi_topology_ipv6_multicast_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_multi_topology_ipv6_multicast_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_multi_topology_ipv6_management_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_multi_topology_ipv6_management_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_multi_topology_ipv6_management_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int isis_instance_multi_topology_ipv6_dstsrc_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_create_args *args); int isis_instance_multi_topology_ipv6_dstsrc_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int isis_instance_multi_topology_ipv6_dstsrc_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_log_adjacency_changes_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_mpls_te_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_mpls_te_destroy(enum nb_event event, - const struct lyd_node *dnode); -int isis_instance_mpls_te_router_address_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int isis_instance_mpls_te_router_address_destroy(enum nb_event event, - const struct lyd_node *dnode); -int lib_interface_isis_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_destroy(enum nb_event event, - const struct lyd_node *dnode); -int lib_interface_isis_area_tag_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_ipv4_routing_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_ipv6_routing_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_circuit_type_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_bfd_monitoring_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args); +int isis_instance_mpls_te_create(struct nb_cb_create_args *args); +int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args); +int isis_instance_mpls_te_router_address_modify(struct nb_cb_modify_args *args); +int isis_instance_mpls_te_router_address_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_isis_create(struct nb_cb_create_args *args); +int lib_interface_isis_destroy(struct nb_cb_destroy_args *args); +int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_ipv4_routing_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_ipv6_routing_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_bfd_monitoring_modify(struct nb_cb_modify_args *args); int lib_interface_isis_csnp_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_csnp_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_psnp_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_psnp_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_hello_padding_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int lib_interface_isis_hello_padding_modify(struct nb_cb_modify_args *args); int lib_interface_isis_hello_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_hello_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_hello_multiplier_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_hello_multiplier_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_metric_level_1_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_metric_level_2_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_priority_level_1_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_priority_level_2_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_network_type_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_passive_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_password_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_isis_password_destroy(enum nb_event event, - const struct lyd_node *dnode); -int lib_interface_isis_password_password_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int lib_interface_isis_metric_level_1_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_metric_level_2_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_priority_level_1_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_priority_level_2_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_network_type_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args); +int lib_interface_isis_password_create(struct nb_cb_create_args *args); +int lib_interface_isis_password_destroy(struct nb_cb_destroy_args *args); +int lib_interface_isis_password_password_modify(struct nb_cb_modify_args *args); int lib_interface_isis_password_password_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_disable_three_way_handshake_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_multi_topology_ipv4_unicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_multi_topology_ipv4_multicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_multi_topology_ipv4_management_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_multi_topology_ipv6_unicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_multi_topology_ipv6_multicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_multi_topology_ipv6_management_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_isis_multi_topology_ipv6_dstsrc_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -const void * -lib_interface_isis_adjacencies_adjacency_get_next(const void *parent_list_entry, - const void *list_entry); + struct nb_cb_modify_args *args); +const void *lib_interface_isis_adjacencies_adjacency_get_next( + struct nb_cb_get_next_args *args); struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_priority_get_elem( - const char *xpath, const void *list_entry); -struct yang_data * -lib_interface_isis_adjacencies_adjacency_state_get_elem(const char *xpath, - const void *list_entry); + struct nb_cb_get_elem_args *args); +struct yang_data *lib_interface_isis_adjacencies_adjacency_state_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_isis_event_counters_adjacency_changes_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_isis_event_counters_adjacency_number_get_elem( - const char *xpath, const void *list_entry); -struct yang_data * -lib_interface_isis_event_counters_init_fails_get_elem(const char *xpath, - const void *list_entry); + struct nb_cb_get_elem_args *args); +struct yang_data *lib_interface_isis_event_counters_init_fails_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_isis_event_counters_adjacency_rejects_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_isis_event_counters_id_len_mismatch_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_isis_event_counters_authentication_type_fails_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_isis_event_counters_authentication_fails_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); /* Optional 'apply_finish' callbacks. */ -void ietf_backoff_delay_apply_finish(const struct lyd_node *dnode); -void area_password_apply_finish(const struct lyd_node *dnode); -void domain_password_apply_finish(const struct lyd_node *dnode); +void ietf_backoff_delay_apply_finish(struct nb_cb_apply_finish_args *args); +void area_password_apply_finish(struct nb_cb_apply_finish_args *args); +void domain_password_apply_finish(struct nb_cb_apply_finish_args *args); void default_info_origin_apply_finish(const struct lyd_node *dnode, int family); -void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode); -void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode); +void default_info_origin_ipv4_apply_finish( + struct nb_cb_apply_finish_args *args); +void default_info_origin_ipv6_apply_finish( + struct nb_cb_apply_finish_args *args); void redistribute_apply_finish(const struct lyd_node *dnode, int family); -void redistribute_ipv4_apply_finish(const struct lyd_node *dnode); -void redistribute_ipv6_apply_finish(const struct lyd_node *dnode); +void redistribute_ipv4_apply_finish(struct nb_cb_apply_finish_args *args); +void redistribute_ipv6_apply_finish(struct nb_cb_apply_finish_args *args); /* Optional 'cli_show' callbacks. */ void cli_show_router_isis(struct vty *vty, struct lyd_node *dnode, diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 4347c85664..2f56fac186 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -49,35 +49,34 @@ /* * XPath: /frr-isisd:isis/instance */ -int isis_instance_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_create(struct nb_cb_create_args *args) { struct isis_area *area; const char *area_tag; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area_tag = yang_dnode_get_string(dnode, "./area-tag"); + area_tag = yang_dnode_get_string(args->dnode, "./area-tag"); area = isis_area_lookup(area_tag); if (area) return NB_ERR_INCONSISTENCY; area = isis_area_create(area_tag); /* save area in dnode to avoid looking it up all the time */ - nb_running_set_entry(dnode, area); + nb_running_set_entry(args->dnode, area); return NB_OK; } -int isis_instance_destroy(enum nb_event event, const struct lyd_node *dnode) +int isis_instance_destroy(struct nb_cb_destroy_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_unset_entry(dnode); + area = nb_running_unset_entry(args->dnode); isis_area_destroy(area->area_tag); return NB_OK; @@ -86,18 +85,16 @@ int isis_instance_destroy(enum nb_event event, const struct lyd_node *dnode) /* * XPath: /frr-isisd:isis/instance/is-type */ -int isis_instance_is_type_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_is_type_modify(struct nb_cb_modify_args *args) { struct isis_area *area; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, NULL); isis_area_is_type_set(area, type); return NB_OK; @@ -106,17 +103,15 @@ int isis_instance_is_type_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/area-address */ -int isis_instance_area_address_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_area_address_create(struct nb_cb_create_args *args) { struct isis_area *area; struct area_addr addr, *addrr = NULL, *addrp = NULL; struct listnode *node; uint8_t buff[255]; - const char *net_title = yang_dnode_get_string(dnode, NULL); + const char *net_title = yang_dnode_get_string(args->dnode, NULL); - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: addr.addr_len = dotformat2buff(buff, net_title); memcpy(addr.area_addr, buff, addr.addr_len); @@ -141,14 +136,14 @@ int isis_instance_area_address_create(enum nb_event event, addrr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct area_addr)); addrr->addr_len = dotformat2buff(buff, net_title); memcpy(addrr->area_addr, buff, addrr->addr_len); - resource->ptr = addrr; + args->resource->ptr = addrr; break; case NB_EV_ABORT: - XFREE(MTYPE_ISIS_AREA_ADDR, resource->ptr); + XFREE(MTYPE_ISIS_AREA_ADDR, args->resource->ptr); break; case NB_EV_APPLY: - area = nb_running_get_entry(dnode, NULL, true); - addrr = resource->ptr; + area = nb_running_get_entry(args->dnode, NULL, true); + addrr = args->resource->ptr; if (isis->sysid_set == 0) { /* @@ -190,8 +185,7 @@ int isis_instance_area_address_create(enum nb_event event, return NB_OK; } -int isis_instance_area_address_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args) { struct area_addr addr, *addrp = NULL; struct listnode *node; @@ -199,13 +193,13 @@ int isis_instance_area_address_destroy(enum nb_event event, struct isis_area *area; const char *net_title; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - net_title = yang_dnode_get_string(dnode, NULL); + net_title = yang_dnode_get_string(args->dnode, NULL); addr.addr_len = dotformat2buff(buff, net_title); memcpy(addr.area_addr, buff, (int)addr.addr_len); - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node, addrp)) { if ((addrp->addr_len + ISIS_SYS_ID_LEN + 1) == addr.addr_len && !memcmp(addrp->area_addr, addr.area_addr, addr.addr_len)) @@ -232,17 +226,15 @@ int isis_instance_area_address_destroy(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/dynamic-hostname */ -int isis_instance_dynamic_hostname_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - isis_area_dynhostname_set(area, yang_dnode_get_bool(dnode, NULL)); + area = nb_running_get_entry(args->dnode, NULL, true); + isis_area_dynhostname_set(area, yang_dnode_get_bool(args->dnode, NULL)); return NB_OK; } @@ -250,18 +242,16 @@ int isis_instance_dynamic_hostname_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/attached */ -int isis_instance_attached_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_attached_modify(struct nb_cb_modify_args *args) { struct isis_area *area; bool attached; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - attached = yang_dnode_get_bool(dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); + attached = yang_dnode_get_bool(args->dnode, NULL); isis_area_attached_bit_set(area, attached); return NB_OK; @@ -270,18 +260,16 @@ int isis_instance_attached_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/overload */ -int isis_instance_overload_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_overload_modify(struct nb_cb_modify_args *args) { struct isis_area *area; bool overload; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - overload = yang_dnode_get_bool(dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); + overload = yang_dnode_get_bool(args->dnode, NULL); isis_area_overload_bit_set(area, overload); return NB_OK; @@ -290,18 +278,17 @@ int isis_instance_overload_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/metric-style */ -int isis_instance_metric_style_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_metric_style_modify(struct nb_cb_modify_args *args) { struct isis_area *area; bool old_metric, new_metric; - enum isis_metric_style metric_style = yang_dnode_get_enum(dnode, NULL); + enum isis_metric_style metric_style = + yang_dnode_get_enum(args->dnode, NULL); - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); old_metric = (metric_style == ISIS_WIDE_METRIC) ? false : true; new_metric = (metric_style == ISIS_NARROW_METRIC) ? false : true; isis_area_metricstyle_set(area, old_metric, new_metric); @@ -312,17 +299,15 @@ int isis_instance_metric_style_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/purge-originator */ -int isis_instance_purge_originator_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - area->purge_originator = yang_dnode_get_bool(dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); + area->purge_originator = yang_dnode_get_bool(args->dnode, NULL); return NB_OK; } @@ -330,18 +315,16 @@ int isis_instance_purge_originator_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/lsp/mtu */ -int isis_instance_lsp_mtu_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args) { struct listnode *node; struct isis_circuit *circuit; - uint16_t lsp_mtu = yang_dnode_get_uint16(dnode, NULL); + uint16_t lsp_mtu = yang_dnode_get_uint16(args->dnode, NULL); struct isis_area *area; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - area = nb_running_get_entry(dnode, NULL, false); + area = nb_running_get_entry(args->dnode, NULL, false); if (!area) break; for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { @@ -362,7 +345,7 @@ int isis_instance_lsp_mtu_modify(enum nb_event event, case NB_EV_ABORT: break; case NB_EV_APPLY: - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); isis_area_lsp_mtu_set(area, lsp_mtu); break; } @@ -374,17 +357,16 @@ int isis_instance_lsp_mtu_modify(enum nb_event event, * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/refresh-interval */ int isis_instance_lsp_refresh_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; uint16_t refr_int; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - refr_int = yang_dnode_get_uint16(dnode, NULL); - area = nb_running_get_entry(dnode, NULL, true); + refr_int = yang_dnode_get_uint16(args->dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); isis_area_lsp_refresh_set(area, IS_LEVEL_1, refr_int); return NB_OK; @@ -394,17 +376,16 @@ int isis_instance_lsp_refresh_interval_level_1_modify( * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/refresh-interval */ int isis_instance_lsp_refresh_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; uint16_t refr_int; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - refr_int = yang_dnode_get_uint16(dnode, NULL); - area = nb_running_get_entry(dnode, NULL, true); + refr_int = yang_dnode_get_uint16(args->dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); isis_area_lsp_refresh_set(area, IS_LEVEL_2, refr_int); return NB_OK; @@ -414,17 +395,16 @@ int isis_instance_lsp_refresh_interval_level_2_modify( * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/maximum-lifetime */ int isis_instance_lsp_maximum_lifetime_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; uint16_t max_lt; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - max_lt = yang_dnode_get_uint16(dnode, NULL); - area = nb_running_get_entry(dnode, NULL, true); + max_lt = yang_dnode_get_uint16(args->dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); isis_area_max_lsp_lifetime_set(area, IS_LEVEL_1, max_lt); return NB_OK; @@ -434,17 +414,16 @@ int isis_instance_lsp_maximum_lifetime_level_1_modify( * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/maximum-lifetime */ int isis_instance_lsp_maximum_lifetime_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; uint16_t max_lt; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - max_lt = yang_dnode_get_uint16(dnode, NULL); - area = nb_running_get_entry(dnode, NULL, true); + max_lt = yang_dnode_get_uint16(args->dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); isis_area_max_lsp_lifetime_set(area, IS_LEVEL_2, max_lt); return NB_OK; @@ -454,17 +433,16 @@ int isis_instance_lsp_maximum_lifetime_level_2_modify( * XPath: /frr-isisd:isis/instance/lsp/timers/level-1/generation-interval */ int isis_instance_lsp_generation_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; uint16_t gen_int; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - gen_int = yang_dnode_get_uint16(dnode, NULL); - area = nb_running_get_entry(dnode, NULL, true); + gen_int = yang_dnode_get_uint16(args->dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); area->lsp_gen_interval[0] = gen_int; return NB_OK; @@ -474,17 +452,16 @@ int isis_instance_lsp_generation_interval_level_1_modify( * XPath: /frr-isisd:isis/instance/lsp/timers/level-2/generation-interval */ int isis_instance_lsp_generation_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; uint16_t gen_int; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - gen_int = yang_dnode_get_uint16(dnode, NULL); - area = nb_running_get_entry(dnode, NULL, true); + gen_int = yang_dnode_get_uint16(args->dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); area->lsp_gen_interval[1] = gen_int; return NB_OK; @@ -493,14 +470,15 @@ int isis_instance_lsp_generation_interval_level_2_modify( /* * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay */ -void ietf_backoff_delay_apply_finish(const struct lyd_node *dnode) +void ietf_backoff_delay_apply_finish(struct nb_cb_apply_finish_args *args) { - long init_delay = yang_dnode_get_uint16(dnode, "./init-delay"); - long short_delay = yang_dnode_get_uint16(dnode, "./short-delay"); - long long_delay = yang_dnode_get_uint16(dnode, "./long-delay"); - long holddown = yang_dnode_get_uint16(dnode, "./hold-down"); - long timetolearn = yang_dnode_get_uint16(dnode, "./time-to-learn"); - struct isis_area *area = nb_running_get_entry(dnode, NULL, true); + long init_delay = yang_dnode_get_uint16(args->dnode, "./init-delay"); + long short_delay = yang_dnode_get_uint16(args->dnode, "./short-delay"); + long long_delay = yang_dnode_get_uint16(args->dnode, "./long-delay"); + long holddown = yang_dnode_get_uint16(args->dnode, "./hold-down"); + long timetolearn = + yang_dnode_get_uint16(args->dnode, "./time-to-learn"); + struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true); size_t bufsiz = strlen(area->area_tag) + sizeof("IS-IS Lx"); char *buf = XCALLOC(MTYPE_TMP, bufsiz); @@ -519,23 +497,21 @@ void ietf_backoff_delay_apply_finish(const struct lyd_node *dnode) XFREE(MTYPE_TMP, buf); } -int isis_instance_spf_ietf_backoff_delay_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_spf_ietf_backoff_delay_create(struct nb_cb_create_args *args) { /* All the work is done in the apply_finish */ return NB_OK; } -int isis_instance_spf_ietf_backoff_delay_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_spf_ietf_backoff_delay_destroy( + struct nb_cb_destroy_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); spf_backoff_free(area->spf_delay_ietf[0]); spf_backoff_free(area->spf_delay_ietf[1]); area->spf_delay_ietf[0] = NULL; @@ -548,8 +524,7 @@ int isis_instance_spf_ietf_backoff_delay_destroy(enum nb_event event, * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/init-delay */ int isis_instance_spf_ietf_backoff_delay_init_delay_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* All the work is done in the apply_finish */ return NB_OK; @@ -559,8 +534,7 @@ int isis_instance_spf_ietf_backoff_delay_init_delay_modify( * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/short-delay */ int isis_instance_spf_ietf_backoff_delay_short_delay_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* All the work is done in the apply_finish */ return NB_OK; @@ -570,8 +544,7 @@ int isis_instance_spf_ietf_backoff_delay_short_delay_modify( * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/long-delay */ int isis_instance_spf_ietf_backoff_delay_long_delay_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* All the work is done in the apply_finish */ return NB_OK; @@ -581,8 +554,7 @@ int isis_instance_spf_ietf_backoff_delay_long_delay_modify( * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/hold-down */ int isis_instance_spf_ietf_backoff_delay_hold_down_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* All the work is done in the apply_finish */ return NB_OK; @@ -592,8 +564,7 @@ int isis_instance_spf_ietf_backoff_delay_hold_down_modify( * XPath: /frr-isisd:isis/instance/spf/ietf-backoff-delay/time-to-learn */ int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* All the work is done in the apply_finish */ return NB_OK; @@ -603,16 +574,15 @@ int isis_instance_spf_ietf_backoff_delay_time_to_learn_modify( * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-1 */ int isis_instance_spf_minimum_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - area->min_spf_interval[0] = yang_dnode_get_uint16(dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); + area->min_spf_interval[0] = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -621,16 +591,15 @@ int isis_instance_spf_minimum_interval_level_1_modify( * XPath: /frr-isisd:isis/instance/spf/minimum-interval/level-2 */ int isis_instance_spf_minimum_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - area->min_spf_interval[1] = yang_dnode_get_uint16(dnode, NULL); + area = nb_running_get_entry(args->dnode, NULL, true); + area->min_spf_interval[1] = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -638,12 +607,13 @@ int isis_instance_spf_minimum_interval_level_2_modify( /* * XPath: /frr-isisd:isis/instance/area-password */ -void area_password_apply_finish(const struct lyd_node *dnode) +void area_password_apply_finish(struct nb_cb_apply_finish_args *args) { - const char *password = yang_dnode_get_string(dnode, "./password"); - struct isis_area *area = nb_running_get_entry(dnode, NULL, true); - int pass_type = yang_dnode_get_enum(dnode, "./password-type"); - uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp"); + const char *password = yang_dnode_get_string(args->dnode, "./password"); + struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true); + int pass_type = yang_dnode_get_enum(args->dnode, "./password-type"); + uint8_t snp_auth = + yang_dnode_get_enum(args->dnode, "./authenticate-snp"); switch (pass_type) { case ISIS_PASSWD_TYPE_CLEARTXT: @@ -657,23 +627,20 @@ void area_password_apply_finish(const struct lyd_node *dnode) } } -int isis_instance_area_password_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_area_password_create(struct nb_cb_create_args *args) { /* actual setting is done in apply_finish */ return NB_OK; } -int isis_instance_area_password_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_area_password_destroy(struct nb_cb_destroy_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); isis_area_passwd_unset(area, IS_LEVEL_1); return NB_OK; @@ -682,9 +649,7 @@ int isis_instance_area_password_destroy(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/area-password/password */ -int isis_instance_area_password_password_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_area_password_password_modify(struct nb_cb_modify_args *args) { /* actual setting is done in apply_finish */ return NB_OK; @@ -694,8 +659,7 @@ int isis_instance_area_password_password_modify(enum nb_event event, * XPath: /frr-isisd:isis/instance/area-password/password-type */ int isis_instance_area_password_password_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* actual setting is done in apply_finish */ return NB_OK; @@ -705,8 +669,7 @@ int isis_instance_area_password_password_type_modify( * XPath: /frr-isisd:isis/instance/area-password/authenticate-snp */ int isis_instance_area_password_authenticate_snp_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* actual setting is done in apply_finish */ return NB_OK; @@ -715,12 +678,13 @@ int isis_instance_area_password_authenticate_snp_modify( /* * XPath: /frr-isisd:isis/instance/domain-password */ -void domain_password_apply_finish(const struct lyd_node *dnode) +void domain_password_apply_finish(struct nb_cb_apply_finish_args *args) { - const char *password = yang_dnode_get_string(dnode, "./password"); - struct isis_area *area = nb_running_get_entry(dnode, NULL, true); - int pass_type = yang_dnode_get_enum(dnode, "./password-type"); - uint8_t snp_auth = yang_dnode_get_enum(dnode, "./authenticate-snp"); + const char *password = yang_dnode_get_string(args->dnode, "./password"); + struct isis_area *area = nb_running_get_entry(args->dnode, NULL, true); + int pass_type = yang_dnode_get_enum(args->dnode, "./password-type"); + uint8_t snp_auth = + yang_dnode_get_enum(args->dnode, "./authenticate-snp"); switch (pass_type) { case ISIS_PASSWD_TYPE_CLEARTXT: @@ -734,23 +698,20 @@ void domain_password_apply_finish(const struct lyd_node *dnode) } } -int isis_instance_domain_password_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_domain_password_create(struct nb_cb_create_args *args) { /* actual setting is done in apply_finish */ return NB_OK; } -int isis_instance_domain_password_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_domain_password_destroy(struct nb_cb_destroy_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); isis_area_passwd_unset(area, IS_LEVEL_2); return NB_OK; @@ -759,9 +720,8 @@ int isis_instance_domain_password_destroy(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/domain-password/password */ -int isis_instance_domain_password_password_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_domain_password_password_modify( + struct nb_cb_modify_args *args) { /* actual setting is done in apply_finish */ return NB_OK; @@ -771,8 +731,7 @@ int isis_instance_domain_password_password_modify(enum nb_event event, * XPath: /frr-isisd:isis/instance/domain-password/password-type */ int isis_instance_domain_password_password_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* actual setting is done in apply_finish */ return NB_OK; @@ -782,8 +741,7 @@ int isis_instance_domain_password_password_type_modify( * XPath: /frr-isisd:isis/instance/domain-password/authenticate-snp */ int isis_instance_domain_password_authenticate_snp_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* actual setting is done in apply_finish */ return NB_OK; @@ -817,35 +775,34 @@ void default_info_origin_apply_finish(const struct lyd_node *dnode, int family) originate_type); } -void default_info_origin_ipv4_apply_finish(const struct lyd_node *dnode) +void default_info_origin_ipv4_apply_finish(struct nb_cb_apply_finish_args *args) { - default_info_origin_apply_finish(dnode, AF_INET); + default_info_origin_apply_finish(args->dnode, AF_INET); } -void default_info_origin_ipv6_apply_finish(const struct lyd_node *dnode) +void default_info_origin_ipv6_apply_finish(struct nb_cb_apply_finish_args *args) { - default_info_origin_apply_finish(dnode, AF_INET6); + default_info_origin_apply_finish(args->dnode, AF_INET6); } int isis_instance_default_information_originate_ipv4_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; } int isis_instance_default_information_originate_ipv4_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { struct isis_area *area; int level; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - level = yang_dnode_get_enum(dnode, "./level"); + area = nb_running_get_entry(args->dnode, NULL, true); + level = yang_dnode_get_enum(args->dnode, "./level"); isis_redist_unset(area, level, AF_INET, DEFAULT_ROUTE); return NB_OK; @@ -855,8 +812,7 @@ int isis_instance_default_information_originate_ipv4_destroy( * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/always */ int isis_instance_default_information_originate_ipv4_always_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; @@ -866,15 +822,14 @@ int isis_instance_default_information_originate_ipv4_always_modify( * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/route-map */ int isis_instance_default_information_originate_ipv4_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; } int isis_instance_default_information_originate_ipv4_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; @@ -884,8 +839,7 @@ int isis_instance_default_information_originate_ipv4_route_map_destroy( * XPath: /frr-isisd:isis/instance/default-information-originate/ipv4/metric */ int isis_instance_default_information_originate_ipv4_metric_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; @@ -895,24 +849,23 @@ int isis_instance_default_information_originate_ipv4_metric_modify( * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6 */ int isis_instance_default_information_originate_ipv6_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; } int isis_instance_default_information_originate_ipv6_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { struct isis_area *area; int level; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - level = yang_dnode_get_enum(dnode, "./level"); + area = nb_running_get_entry(args->dnode, NULL, true); + level = yang_dnode_get_enum(args->dnode, "./level"); isis_redist_unset(area, level, AF_INET6, DEFAULT_ROUTE); return NB_OK; @@ -922,8 +875,7 @@ int isis_instance_default_information_originate_ipv6_destroy( * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/always */ int isis_instance_default_information_originate_ipv6_always_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; @@ -933,15 +885,14 @@ int isis_instance_default_information_originate_ipv6_always_modify( * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/route-map */ int isis_instance_default_information_originate_ipv6_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; } int isis_instance_default_information_originate_ipv6_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; @@ -951,8 +902,7 @@ int isis_instance_default_information_originate_ipv6_route_map_destroy( * XPath: /frr-isisd:isis/instance/default-information-originate/ipv6/metric */ int isis_instance_default_information_originate_ipv6_metric_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by default_info_origin_apply_finish */ return NB_OK; @@ -981,36 +931,33 @@ void redistribute_apply_finish(const struct lyd_node *dnode, int family) isis_redist_set(area, level, family, type, metric, routemap, 0); } -void redistribute_ipv4_apply_finish(const struct lyd_node *dnode) +void redistribute_ipv4_apply_finish(struct nb_cb_apply_finish_args *args) { - redistribute_apply_finish(dnode, AF_INET); + redistribute_apply_finish(args->dnode, AF_INET); } -void redistribute_ipv6_apply_finish(const struct lyd_node *dnode) +void redistribute_ipv6_apply_finish(struct nb_cb_apply_finish_args *args) { - redistribute_apply_finish(dnode, AF_INET6); + redistribute_apply_finish(args->dnode, AF_INET6); } -int isis_instance_redistribute_ipv4_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_redistribute_ipv4_create(struct nb_cb_create_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; } -int isis_instance_redistribute_ipv4_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_redistribute_ipv4_destroy(struct nb_cb_destroy_args *args) { struct isis_area *area; int level, type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - level = yang_dnode_get_enum(dnode, "./level"); - type = yang_dnode_get_enum(dnode, "./protocol"); + area = nb_running_get_entry(args->dnode, NULL, true); + level = yang_dnode_get_enum(args->dnode, "./level"); + type = yang_dnode_get_enum(args->dnode, "./protocol"); isis_redist_unset(area, level, AF_INET, type); return NB_OK; @@ -1020,15 +967,14 @@ int isis_instance_redistribute_ipv4_destroy(enum nb_event event, * XPath: /frr-isisd:isis/instance/redistribute/ipv4/route-map */ int isis_instance_redistribute_ipv4_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; } int isis_instance_redistribute_ipv4_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; @@ -1037,9 +983,8 @@ int isis_instance_redistribute_ipv4_route_map_destroy( /* * XPath: /frr-isisd:isis/instance/redistribute/ipv4/metric */ -int isis_instance_redistribute_ipv4_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_redistribute_ipv4_metric_modify( + struct nb_cb_modify_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; @@ -1048,26 +993,23 @@ int isis_instance_redistribute_ipv4_metric_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/redistribute/ipv6 */ -int isis_instance_redistribute_ipv6_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_redistribute_ipv6_create(struct nb_cb_create_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; } -int isis_instance_redistribute_ipv6_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_redistribute_ipv6_destroy(struct nb_cb_destroy_args *args) { struct isis_area *area; int level, type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); - level = yang_dnode_get_enum(dnode, "./level"); - type = yang_dnode_get_enum(dnode, "./protocol"); + area = nb_running_get_entry(args->dnode, NULL, true); + level = yang_dnode_get_enum(args->dnode, "./level"); + type = yang_dnode_get_enum(args->dnode, "./protocol"); isis_redist_unset(area, level, AF_INET6, type); return NB_OK; @@ -1077,15 +1019,14 @@ int isis_instance_redistribute_ipv6_destroy(enum nb_event event, * XPath: /frr-isisd:isis/instance/redistribute/ipv6/route-map */ int isis_instance_redistribute_ipv6_route_map_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; } int isis_instance_redistribute_ipv6_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; @@ -1094,9 +1035,8 @@ int isis_instance_redistribute_ipv6_route_map_destroy( /* * XPath: /frr-isisd:isis/instance/redistribute/ipv6/metric */ -int isis_instance_redistribute_ipv6_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_redistribute_ipv6_metric_modify( + struct nb_cb_modify_args *args) { /* It's all done by redistribute_apply_finish */ return NB_OK; @@ -1157,27 +1097,26 @@ static int isis_multi_topology_overload_common(enum nb_event event, } int isis_instance_multi_topology_ipv4_multicast_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - return isis_multi_topology_common(event, dnode, "ipv4-multicast", true); + return isis_multi_topology_common(args->event, args->dnode, + "ipv4-multicast", true); } int isis_instance_multi_topology_ipv4_multicast_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return isis_multi_topology_common(event, dnode, "ipv4-multicast", - false); + return isis_multi_topology_common(args->event, args->dnode, + "ipv4-multicast", false); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-multicast/overload */ int isis_instance_multi_topology_ipv4_multicast_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return isis_multi_topology_overload_common(event, dnode, + return isis_multi_topology_overload_common(args->event, args->dnode, "ipv4-multicast"); } @@ -1185,52 +1124,53 @@ int isis_instance_multi_topology_ipv4_multicast_overload_modify( * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management */ int isis_instance_multi_topology_ipv4_management_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - return isis_multi_topology_common(event, dnode, "ipv4-mgmt", true); + return isis_multi_topology_common(args->event, args->dnode, "ipv4-mgmt", + true); } int isis_instance_multi_topology_ipv4_management_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return isis_multi_topology_common(event, dnode, "ipv4-mgmt", false); + return isis_multi_topology_common(args->event, args->dnode, "ipv4-mgmt", + false); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv4-management/overload */ int isis_instance_multi_topology_ipv4_management_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return isis_multi_topology_overload_common(event, dnode, "ipv4-mgmt"); + return isis_multi_topology_overload_common(args->event, args->dnode, + "ipv4-mgmt"); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast */ int isis_instance_multi_topology_ipv6_unicast_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-unicast", true); + return isis_multi_topology_common(args->event, args->dnode, + "ipv6-unicast", true); } int isis_instance_multi_topology_ipv6_unicast_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-unicast", false); + return isis_multi_topology_common(args->event, args->dnode, + "ipv6-unicast", false); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-unicast/overload */ int isis_instance_multi_topology_ipv6_unicast_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return isis_multi_topology_overload_common(event, dnode, + return isis_multi_topology_overload_common(args->event, args->dnode, "ipv6-unicast"); } @@ -1238,27 +1178,26 @@ int isis_instance_multi_topology_ipv6_unicast_overload_modify( * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast */ int isis_instance_multi_topology_ipv6_multicast_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-multicast", true); + return isis_multi_topology_common(args->event, args->dnode, + "ipv6-multicast", true); } int isis_instance_multi_topology_ipv6_multicast_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-multicast", - false); + return isis_multi_topology_common(args->event, args->dnode, + "ipv6-multicast", false); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-multicast/overload */ int isis_instance_multi_topology_ipv6_multicast_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return isis_multi_topology_overload_common(event, dnode, + return isis_multi_topology_overload_common(args->event, args->dnode, "ipv6-multicast"); } @@ -1266,68 +1205,68 @@ int isis_instance_multi_topology_ipv6_multicast_overload_modify( * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management */ int isis_instance_multi_topology_ipv6_management_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-mgmt", true); + return isis_multi_topology_common(args->event, args->dnode, "ipv6-mgmt", + true); } int isis_instance_multi_topology_ipv6_management_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-mgmt", false); + return isis_multi_topology_common(args->event, args->dnode, "ipv6-mgmt", + false); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-management/overload */ int isis_instance_multi_topology_ipv6_management_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return isis_multi_topology_overload_common(event, dnode, "ipv6-mgmt"); + return isis_multi_topology_overload_common(args->event, args->dnode, + "ipv6-mgmt"); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc */ int isis_instance_multi_topology_ipv6_dstsrc_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", true); + return isis_multi_topology_common(args->event, args->dnode, + "ipv6-dstsrc", true); } int isis_instance_multi_topology_ipv6_dstsrc_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return isis_multi_topology_common(event, dnode, "ipv6-dstsrc", false); + return isis_multi_topology_common(args->event, args->dnode, + "ipv6-dstsrc", false); } /* * XPath: /frr-isisd:isis/instance/multi-topology/ipv6-dstsrc/overload */ int isis_instance_multi_topology_ipv6_dstsrc_overload_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return isis_multi_topology_overload_common(event, dnode, "ipv6-dstsrc"); + return isis_multi_topology_overload_common(args->event, args->dnode, + "ipv6-dstsrc"); } /* * XPath: /frr-isisd:isis/instance/log-adjacency-changes */ -int isis_instance_log_adjacency_changes_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_log_adjacency_changes_modify(struct nb_cb_modify_args *args) { struct isis_area *area; - bool log = yang_dnode_get_bool(dnode, NULL); + bool log = yang_dnode_get_bool(args->dnode, NULL); - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); area->log_adj_changes = log ? 1 : 0; return NB_OK; @@ -1336,18 +1275,16 @@ int isis_instance_log_adjacency_changes_modify(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/mpls-te */ -int isis_instance_mpls_te_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_mpls_te_create(struct nb_cb_create_args *args) { struct listnode *node; struct isis_area *area; struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); if (area->mta == NULL) { struct mpls_te_area *new; @@ -1379,17 +1316,16 @@ int isis_instance_mpls_te_create(enum nb_event event, return NB_OK; } -int isis_instance_mpls_te_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args) { struct listnode *node; struct isis_area *area; struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); if (IS_MPLS_TE(area->mta)) area->mta->status = disable; else @@ -1421,23 +1357,21 @@ int isis_instance_mpls_te_destroy(enum nb_event event, /* * XPath: /frr-isisd:isis/instance/mpls-te/router-address */ -int isis_instance_mpls_te_router_address_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int isis_instance_mpls_te_router_address_modify(struct nb_cb_modify_args *args) { struct in_addr value; struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); /* only proceed if MPLS-TE is enabled */ if (!IS_MPLS_TE(area->mta)) return NB_OK; /* Update Area Router ID */ - yang_dnode_get_ipv4(&value, dnode, NULL); + yang_dnode_get_ipv4(&value, args->dnode, NULL); area->mta->router_id.s_addr = value.s_addr; /* And re-schedule LSP update */ @@ -1446,15 +1380,15 @@ int isis_instance_mpls_te_router_address_modify(enum nb_event event, return NB_OK; } -int isis_instance_mpls_te_router_address_destroy(enum nb_event event, - const struct lyd_node *dnode) +int isis_instance_mpls_te_router_address_destroy( + struct nb_cb_destroy_args *args) { struct isis_area *area; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - area = nb_running_get_entry(dnode, NULL, true); + area = nb_running_get_entry(args->dnode, NULL, true); /* only proceed if MPLS-TE is enabled */ if (!IS_MPLS_TE(area->mta)) return NB_OK; @@ -1471,16 +1405,15 @@ int isis_instance_mpls_te_router_address_destroy(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis */ -int lib_interface_isis_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_create(struct nb_cb_create_args *args) { struct isis_area *area; struct interface *ifp; struct isis_circuit *circuit; - const char *area_tag = yang_dnode_get_string(dnode, "./area-tag"); + const char *area_tag = yang_dnode_get_string(args->dnode, "./area-tag"); uint32_t min_mtu, actual_mtu; - switch (event) { + switch (args->event) { case NB_EV_PREPARE: case NB_EV_ABORT: break; @@ -1488,7 +1421,7 @@ int lib_interface_isis_create(enum nb_event event, const struct lyd_node *dnode, /* check if interface mtu is sufficient. If the area has not * been created yet, assume default MTU for the area */ - ifp = nb_running_get_entry(dnode, NULL, false); + ifp = nb_running_get_entry(args->dnode, NULL, false); /* zebra might not know yet about the MTU - nothing we can do */ if (!ifp || ifp->mtu == 0) break; @@ -1527,27 +1460,26 @@ int lib_interface_isis_create(enum nb_event event, const struct lyd_node *dnode, abort(); } - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); circuit = isis_circuit_create(area, ifp); assert(circuit && (circuit->state == C_STATE_CONF || circuit->state == C_STATE_UP)); - nb_running_set_entry(dnode, circuit); + nb_running_set_entry(args->dnode, circuit); break; } return NB_OK; } -int lib_interface_isis_destroy(enum nb_event event, - const struct lyd_node *dnode) +int lib_interface_isis_destroy(struct nb_cb_destroy_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_unset_entry(dnode); + circuit = nb_running_unset_entry(args->dnode); if (!circuit) return NB_ERR_INCONSISTENCY; @@ -1563,27 +1495,27 @@ int lib_interface_isis_destroy(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/area-tag */ -int lib_interface_isis_area_tag_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; struct interface *ifp; struct vrf *vrf; const char *area_tag, *ifname, *vrfname; - if (event == NB_EV_VALIDATE) { + if (args->event == NB_EV_VALIDATE) { /* libyang doesn't like relative paths across module boundaries */ - ifname = yang_dnode_get_string(dnode->parent->parent, "./name"); - vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf"); + ifname = yang_dnode_get_string(args->dnode->parent->parent, + "./name"); + vrfname = yang_dnode_get_string(args->dnode->parent->parent, + "./vrf"); vrf = vrf_lookup_by_name(vrfname); assert(vrf); ifp = if_lookup_by_name(ifname, vrf->vrf_id); if (!ifp) return NB_OK; circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list); - area_tag = yang_dnode_get_string(dnode, NULL); + area_tag = yang_dnode_get_string(args->dnode, NULL); if (circuit && circuit->area && circuit->area->area_tag && strcmp(circuit->area->area_tag, area_tag)) { flog_warn(EC_LIB_NB_CB_CONFIG_VALIDATE, @@ -1599,22 +1531,22 @@ int lib_interface_isis_area_tag_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/circuit-type */ -int lib_interface_isis_circuit_type_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args) { - int circ_type = yang_dnode_get_enum(dnode, NULL); + int circ_type = yang_dnode_get_enum(args->dnode, NULL); struct isis_circuit *circuit; struct interface *ifp; struct vrf *vrf; const char *ifname, *vrfname; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* libyang doesn't like relative paths across module boundaries */ - ifname = yang_dnode_get_string(dnode->parent->parent, "./name"); - vrfname = yang_dnode_get_string(dnode->parent->parent, "./vrf"); + ifname = yang_dnode_get_string(args->dnode->parent->parent, + "./name"); + vrfname = yang_dnode_get_string(args->dnode->parent->parent, + "./vrf"); vrf = vrf_lookup_by_name(vrfname); assert(vrf); ifp = if_lookup_by_name(ifname, vrf->vrf_id); @@ -1634,7 +1566,7 @@ int lib_interface_isis_circuit_type_modify(enum nb_event event, case NB_EV_ABORT: break; case NB_EV_APPLY: - circuit = nb_running_get_entry(dnode, NULL, true); + circuit = nb_running_get_entry(args->dnode, NULL, true); isis_circuit_is_type_set(circuit, circ_type); break; } @@ -1645,19 +1577,17 @@ int lib_interface_isis_circuit_type_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv4-routing */ -int lib_interface_isis_ipv4_routing_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_ipv4_routing_modify(struct nb_cb_modify_args *args) { bool ipv4, ipv6; struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - ipv4 = yang_dnode_get_bool(dnode, NULL); - ipv6 = yang_dnode_get_bool(dnode, "../ipv6-routing"); + circuit = nb_running_get_entry(args->dnode, NULL, true); + ipv4 = yang_dnode_get_bool(args->dnode, NULL); + ipv6 = yang_dnode_get_bool(args->dnode, "../ipv6-routing"); isis_circuit_af_set(circuit, ipv4, ipv6); return NB_OK; @@ -1666,19 +1596,17 @@ int lib_interface_isis_ipv4_routing_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/ipv6-routing */ -int lib_interface_isis_ipv6_routing_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_ipv6_routing_modify(struct nb_cb_modify_args *args) { bool ipv4, ipv6; struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - ipv4 = yang_dnode_exists(dnode, "../ipv4-routing"); - ipv6 = yang_dnode_get_bool(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + ipv4 = yang_dnode_exists(args->dnode, "../ipv4-routing"); + ipv6 = yang_dnode_get_bool(args->dnode, NULL); isis_circuit_af_set(circuit, ipv4, ipv6); return NB_OK; @@ -1687,18 +1615,16 @@ int lib_interface_isis_ipv6_routing_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring */ -int lib_interface_isis_bfd_monitoring_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_bfd_monitoring_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; bool bfd_monitoring; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - bfd_monitoring = yang_dnode_get_bool(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + bfd_monitoring = yang_dnode_get_bool(args->dnode, NULL); if (bfd_monitoring) { isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX, @@ -1716,16 +1642,15 @@ int lib_interface_isis_bfd_monitoring_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-1 */ int lib_interface_isis_csnp_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->csnp_interval[0] = yang_dnode_get_uint16(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->csnp_interval[0] = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -1734,16 +1659,15 @@ int lib_interface_isis_csnp_interval_level_1_modify( * XPath: /frr-interface:lib/interface/frr-isisd:isis/csnp-interval/level-2 */ int lib_interface_isis_csnp_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->csnp_interval[1] = yang_dnode_get_uint16(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->csnp_interval[1] = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -1752,16 +1676,15 @@ int lib_interface_isis_csnp_interval_level_2_modify( * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-1 */ int lib_interface_isis_psnp_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->psnp_interval[0] = yang_dnode_get_uint16(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->psnp_interval[0] = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -1770,16 +1693,15 @@ int lib_interface_isis_psnp_interval_level_1_modify( * XPath: /frr-interface:lib/interface/frr-isisd:isis/psnp-interval/level-2 */ int lib_interface_isis_psnp_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->psnp_interval[1] = yang_dnode_get_uint16(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->psnp_interval[1] = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -1787,17 +1709,15 @@ int lib_interface_isis_psnp_interval_level_2_modify( /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/padding */ -int lib_interface_isis_hello_padding_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_hello_padding_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->pad_hellos = yang_dnode_get_bool(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->pad_hellos = yang_dnode_get_bool(args->dnode, NULL); return NB_OK; } @@ -1806,17 +1726,16 @@ int lib_interface_isis_hello_padding_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-1 */ int lib_interface_isis_hello_interval_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; uint32_t interval; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - interval = yang_dnode_get_uint32(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + interval = yang_dnode_get_uint32(args->dnode, NULL); circuit->hello_interval[0] = interval; return NB_OK; @@ -1826,17 +1745,16 @@ int lib_interface_isis_hello_interval_level_1_modify( * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/interval/level-2 */ int lib_interface_isis_hello_interval_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; uint32_t interval; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - interval = yang_dnode_get_uint32(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + interval = yang_dnode_get_uint32(args->dnode, NULL); circuit->hello_interval[1] = interval; return NB_OK; @@ -1846,17 +1764,16 @@ int lib_interface_isis_hello_interval_level_2_modify( * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-1 */ int lib_interface_isis_hello_multiplier_level_1_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; uint16_t multi; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - multi = yang_dnode_get_uint16(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + multi = yang_dnode_get_uint16(args->dnode, NULL); circuit->hello_multiplier[0] = multi; return NB_OK; @@ -1866,17 +1783,16 @@ int lib_interface_isis_hello_multiplier_level_1_modify( * XPath: /frr-interface:lib/interface/frr-isisd:isis/hello/multiplier/level-2 */ int lib_interface_isis_hello_multiplier_level_2_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; uint16_t multi; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - multi = yang_dnode_get_uint16(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + multi = yang_dnode_get_uint16(args->dnode, NULL); circuit->hello_multiplier[1] = multi; return NB_OK; @@ -1885,18 +1801,16 @@ int lib_interface_isis_hello_multiplier_level_2_modify( /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-1 */ -int lib_interface_isis_metric_level_1_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_metric_level_1_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; unsigned int met; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - met = yang_dnode_get_uint32(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + met = yang_dnode_get_uint32(args->dnode, NULL); isis_circuit_metric_set(circuit, IS_LEVEL_1, met); return NB_OK; @@ -1905,18 +1819,16 @@ int lib_interface_isis_metric_level_1_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/metric/level-2 */ -int lib_interface_isis_metric_level_2_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_metric_level_2_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; unsigned int met; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - met = yang_dnode_get_uint32(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + met = yang_dnode_get_uint32(args->dnode, NULL); isis_circuit_metric_set(circuit, IS_LEVEL_2, met); return NB_OK; @@ -1925,17 +1837,15 @@ int lib_interface_isis_metric_level_2_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-1 */ -int lib_interface_isis_priority_level_1_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_priority_level_1_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->priority[0] = yang_dnode_get_uint8(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->priority[0] = yang_dnode_get_uint8(args->dnode, NULL); return NB_OK; } @@ -1943,17 +1853,15 @@ int lib_interface_isis_priority_level_1_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/priority/level-2 */ -int lib_interface_isis_priority_level_2_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_priority_level_2_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->priority[1] = yang_dnode_get_uint8(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->priority[1] = yang_dnode_get_uint8(args->dnode, NULL); return NB_OK; } @@ -1961,16 +1869,14 @@ int lib_interface_isis_priority_level_2_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/network-type */ -int lib_interface_isis_network_type_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_network_type_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - int net_type = yang_dnode_get_enum(dnode, NULL); + int net_type = yang_dnode_get_enum(args->dnode, NULL); - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - circuit = nb_running_get_entry(dnode, NULL, false); + circuit = nb_running_get_entry(args->dnode, NULL, false); if (!circuit) break; if (circuit->circ_type == CIRCUIT_T_LOOPBACK) { @@ -1992,7 +1898,7 @@ int lib_interface_isis_network_type_modify(enum nb_event event, case NB_EV_ABORT: break; case NB_EV_APPLY: - circuit = nb_running_get_entry(dnode, NULL, true); + circuit = nb_running_get_entry(args->dnode, NULL, true); isis_circuit_circ_type_set(circuit, net_type); break; } @@ -2003,18 +1909,16 @@ int lib_interface_isis_network_type_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/passive */ -int lib_interface_isis_passive_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_passive_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; struct isis_area *area; struct interface *ifp; - bool passive = yang_dnode_get_bool(dnode, NULL); + bool passive = yang_dnode_get_bool(args->dnode, NULL); /* validation only applies if we are setting passive to false */ - if (!passive && event == NB_EV_VALIDATE) { - circuit = nb_running_get_entry(dnode, NULL, false); + if (!passive && args->event == NB_EV_VALIDATE) { + circuit = nb_running_get_entry(args->dnode, NULL, false); if (!circuit) return NB_OK; ifp = circuit->interface; @@ -2027,10 +1931,10 @@ int lib_interface_isis_passive_modify(enum nb_event event, } } - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); + circuit = nb_running_get_entry(args->dnode, NULL, true); if (circuit->state != C_STATE_UP) { circuit->is_passive = passive; } else { @@ -2046,22 +1950,19 @@ int lib_interface_isis_passive_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/password */ -int lib_interface_isis_password_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_password_create(struct nb_cb_create_args *args) { return NB_OK; } -int lib_interface_isis_password_destroy(enum nb_event event, - const struct lyd_node *dnode) +int lib_interface_isis_password_destroy(struct nb_cb_destroy_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); + circuit = nb_running_get_entry(args->dnode, NULL, true); isis_circuit_passwd_unset(circuit); return NB_OK; @@ -2070,18 +1971,16 @@ int lib_interface_isis_password_destroy(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password */ -int lib_interface_isis_password_password_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_isis_password_password_modify(struct nb_cb_modify_args *args) { struct isis_circuit *circuit; const char *password; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - password = yang_dnode_get_string(dnode, NULL); - circuit = nb_running_get_entry(dnode, NULL, true); + password = yang_dnode_get_string(args->dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); isis_circuit_passwd_set(circuit, circuit->passwd.type, password); @@ -2092,17 +1991,16 @@ int lib_interface_isis_password_password_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-isisd:isis/password/password-type */ int lib_interface_isis_password_password_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; uint8_t pass_type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - pass_type = yang_dnode_get_enum(dnode, NULL); - circuit = nb_running_get_entry(dnode, NULL, true); + pass_type = yang_dnode_get_enum(args->dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); circuit->passwd.type = pass_type; return NB_OK; @@ -2113,16 +2011,15 @@ int lib_interface_isis_password_password_type_modify( * /frr-interface:lib/interface/frr-isisd:isis/disable-three-way-handshake */ int lib_interface_isis_disable_three_way_handshake_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct isis_circuit *circuit; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - circuit = nb_running_get_entry(dnode, NULL, true); - circuit->disable_threeway_adj = yang_dnode_get_bool(dnode, NULL); + circuit = nb_running_get_entry(args->dnode, NULL, true); + circuit->disable_threeway_adj = yang_dnode_get_bool(args->dnode, NULL); return NB_OK; } @@ -2161,11 +2058,10 @@ static int lib_interface_isis_multi_topology_common( } int lib_interface_isis_multi_topology_ipv4_unicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_interface_isis_multi_topology_common(event, dnode, - ISIS_MT_IPV4_UNICAST); + return lib_interface_isis_multi_topology_common( + args->event, args->dnode, ISIS_MT_IPV4_UNICAST); } /* @@ -2173,11 +2069,10 @@ int lib_interface_isis_multi_topology_ipv4_unicast_modify( * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-multicast */ int lib_interface_isis_multi_topology_ipv4_multicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_interface_isis_multi_topology_common(event, dnode, - ISIS_MT_IPV4_MULTICAST); + return lib_interface_isis_multi_topology_common( + args->event, args->dnode, ISIS_MT_IPV4_MULTICAST); } /* @@ -2185,11 +2080,10 @@ int lib_interface_isis_multi_topology_ipv4_multicast_modify( * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv4-management */ int lib_interface_isis_multi_topology_ipv4_management_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_interface_isis_multi_topology_common(event, dnode, - ISIS_MT_IPV4_MGMT); + return lib_interface_isis_multi_topology_common( + args->event, args->dnode, ISIS_MT_IPV4_MGMT); } /* @@ -2197,11 +2091,10 @@ int lib_interface_isis_multi_topology_ipv4_management_modify( * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-unicast */ int lib_interface_isis_multi_topology_ipv6_unicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_interface_isis_multi_topology_common(event, dnode, - ISIS_MT_IPV6_UNICAST); + return lib_interface_isis_multi_topology_common( + args->event, args->dnode, ISIS_MT_IPV6_UNICAST); } /* @@ -2209,11 +2102,10 @@ int lib_interface_isis_multi_topology_ipv6_unicast_modify( * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-multicast */ int lib_interface_isis_multi_topology_ipv6_multicast_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_interface_isis_multi_topology_common(event, dnode, - ISIS_MT_IPV6_MULTICAST); + return lib_interface_isis_multi_topology_common( + args->event, args->dnode, ISIS_MT_IPV6_MULTICAST); } /* @@ -2221,20 +2113,18 @@ int lib_interface_isis_multi_topology_ipv6_multicast_modify( * /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-management */ int lib_interface_isis_multi_topology_ipv6_management_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_interface_isis_multi_topology_common(event, dnode, - ISIS_MT_IPV6_MGMT); + return lib_interface_isis_multi_topology_common( + args->event, args->dnode, ISIS_MT_IPV6_MGMT); } /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/multi-topology/ipv6-dstsrc */ int lib_interface_isis_multi_topology_ipv6_dstsrc_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_interface_isis_multi_topology_common(event, dnode, - ISIS_MT_IPV6_DSTSRC); + return lib_interface_isis_multi_topology_common( + args->event, args->dnode, ISIS_MT_IPV6_DSTSRC); } diff --git a/isisd/isis_nb_state.c b/isisd/isis_nb_state.c index e52d0201d5..1e44e60ee0 100644 --- a/isisd/isis_nb_state.c +++ b/isisd/isis_nb_state.c @@ -31,9 +31,8 @@ /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency */ -const void * -lib_interface_isis_adjacencies_adjacency_get_next(const void *parent_list_entry, - const void *list_entry) +const void *lib_interface_isis_adjacencies_adjacency_get_next( + struct nb_cb_get_next_args *args) { struct interface *ifp; struct isis_circuit *circuit; @@ -42,8 +41,8 @@ lib_interface_isis_adjacencies_adjacency_get_next(const void *parent_list_entry, struct listnode *node, *node_next; /* Get first adjacency. */ - if (list_entry == NULL) { - ifp = (struct interface *)parent_list_entry; + if (args->list_entry == NULL) { + ifp = (struct interface *)args->parent_list_entry; if (!ifp) return NULL; @@ -73,7 +72,7 @@ lib_interface_isis_adjacencies_adjacency_get_next(const void *parent_list_entry, } /* Get next adjacency. */ - adj = (struct isis_adjacency *)list_entry; + adj = (struct isis_adjacency *)args->list_entry; circuit = adj->circuit; switch (circuit->circ_type) { case CIRCUIT_T_BROADCAST: @@ -106,11 +105,11 @@ lib_interface_isis_adjacencies_adjacency_get_next(const void *parent_list_entry, */ struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct isis_adjacency *adj = list_entry; + const struct isis_adjacency *adj = args->list_entry; - return yang_data_new_enum(xpath, adj->level); + return yang_data_new_enum(args->xpath, adj->level); } /* @@ -119,11 +118,11 @@ lib_interface_isis_adjacencies_adjacency_neighbor_sys_type_get_elem( */ struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct isis_adjacency *adj = list_entry; + const struct isis_adjacency *adj = args->list_entry; - return yang_data_new_string(xpath, sysid_print(adj->sysid)); + return yang_data_new_string(args->xpath, sysid_print(adj->sysid)); } /* @@ -132,11 +131,11 @@ lib_interface_isis_adjacencies_adjacency_neighbor_sysid_get_elem( */ struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct isis_adjacency *adj = list_entry; + const struct isis_adjacency *adj = args->list_entry; - return yang_data_new_uint32(xpath, adj->circuit->circuit_id); + return yang_data_new_uint32(args->xpath, adj->circuit->circuit_id); } /* @@ -145,11 +144,11 @@ lib_interface_isis_adjacencies_adjacency_neighbor_extended_circuit_id_get_elem( */ struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct isis_adjacency *adj = list_entry; + const struct isis_adjacency *adj = args->list_entry; - return yang_data_new_string(xpath, snpa_print(adj->snpa)); + return yang_data_new_string(args->xpath, snpa_print(adj->snpa)); } /* @@ -157,11 +156,11 @@ lib_interface_isis_adjacencies_adjacency_neighbor_snpa_get_elem( * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/hold-timer */ struct yang_data *lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct isis_adjacency *adj = list_entry; + const struct isis_adjacency *adj = args->list_entry; - return yang_data_new_uint16(xpath, adj->hold_time); + return yang_data_new_uint16(args->xpath, adj->hold_time); } /* @@ -170,24 +169,24 @@ struct yang_data *lib_interface_isis_adjacencies_adjacency_hold_timer_get_elem( */ struct yang_data * lib_interface_isis_adjacencies_adjacency_neighbor_priority_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct isis_adjacency *adj = list_entry; + const struct isis_adjacency *adj = args->list_entry; - return yang_data_new_uint8(xpath, adj->prio[adj->level - 1]); + return yang_data_new_uint8(args->xpath, adj->prio[adj->level - 1]); } /* * XPath: * /frr-interface:lib/interface/frr-isisd:isis/adjacencies/adjacency/state */ -struct yang_data * -lib_interface_isis_adjacencies_adjacency_state_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *lib_interface_isis_adjacencies_adjacency_state_get_elem( + struct nb_cb_get_elem_args *args) { - const struct isis_adjacency *adj = list_entry; + const struct isis_adjacency *adj = args->list_entry; - return yang_data_new_string(xpath, isis_adj_yang_state(adj->adj_state)); + return yang_data_new_string(args->xpath, + isis_adj_yang_state(adj->adj_state)); } /* @@ -195,12 +194,12 @@ lib_interface_isis_adjacencies_adjacency_state_get_elem(const char *xpath, * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-changes */ struct yang_data *lib_interface_isis_event_counters_adjacency_changes_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -208,7 +207,7 @@ struct yang_data *lib_interface_isis_event_counters_adjacency_changes_get_elem( if (!circuit) return NULL; - return yang_data_new_uint32(xpath, circuit->adj_state_changes); + return yang_data_new_uint32(args->xpath, circuit->adj_state_changes); } /* @@ -216,7 +215,7 @@ struct yang_data *lib_interface_isis_event_counters_adjacency_changes_get_elem( * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-number */ struct yang_data *lib_interface_isis_event_counters_adjacency_number_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; @@ -224,7 +223,7 @@ struct yang_data *lib_interface_isis_event_counters_adjacency_number_get_elem( struct listnode *node; uint32_t total = 0; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -253,20 +252,19 @@ struct yang_data *lib_interface_isis_event_counters_adjacency_number_get_elem( break; } - return yang_data_new_uint32(xpath, total); + return yang_data_new_uint32(args->xpath, total); } /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/event-counters/init-fails */ -struct yang_data * -lib_interface_isis_event_counters_init_fails_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *lib_interface_isis_event_counters_init_fails_get_elem( + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -274,7 +272,7 @@ lib_interface_isis_event_counters_init_fails_get_elem(const char *xpath, if (!circuit) return NULL; - return yang_data_new_uint32(xpath, circuit->init_failures); + return yang_data_new_uint32(args->xpath, circuit->init_failures); } /* @@ -282,12 +280,12 @@ lib_interface_isis_event_counters_init_fails_get_elem(const char *xpath, * /frr-interface:lib/interface/frr-isisd:isis/event-counters/adjacency-rejects */ struct yang_data *lib_interface_isis_event_counters_adjacency_rejects_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -295,7 +293,7 @@ struct yang_data *lib_interface_isis_event_counters_adjacency_rejects_get_elem( if (!circuit) return NULL; - return yang_data_new_uint32(xpath, circuit->rej_adjacencies); + return yang_data_new_uint32(args->xpath, circuit->rej_adjacencies); } /* @@ -303,12 +301,12 @@ struct yang_data *lib_interface_isis_event_counters_adjacency_rejects_get_elem( * /frr-interface:lib/interface/frr-isisd:isis/event-counters/id-len-mismatch */ struct yang_data *lib_interface_isis_event_counters_id_len_mismatch_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -316,7 +314,7 @@ struct yang_data *lib_interface_isis_event_counters_id_len_mismatch_get_elem( if (!circuit) return NULL; - return yang_data_new_uint32(xpath, circuit->id_len_mismatches); + return yang_data_new_uint32(args->xpath, circuit->id_len_mismatches); } /* @@ -325,12 +323,12 @@ struct yang_data *lib_interface_isis_event_counters_id_len_mismatch_get_elem( */ struct yang_data * lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -338,7 +336,8 @@ lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem( if (!circuit) return NULL; - return yang_data_new_uint32(xpath, circuit->max_area_addr_mismatches); + return yang_data_new_uint32(args->xpath, + circuit->max_area_addr_mismatches); } /* @@ -347,12 +346,12 @@ lib_interface_isis_event_counters_max_area_addresses_mismatch_get_elem( */ struct yang_data * lib_interface_isis_event_counters_authentication_type_fails_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -360,7 +359,7 @@ lib_interface_isis_event_counters_authentication_type_fails_get_elem( if (!circuit) return NULL; - return yang_data_new_uint32(xpath, circuit->auth_type_failures); + return yang_data_new_uint32(args->xpath, circuit->auth_type_failures); } /* @@ -369,12 +368,12 @@ lib_interface_isis_event_counters_authentication_type_fails_get_elem( */ struct yang_data * lib_interface_isis_event_counters_authentication_fails_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { struct interface *ifp; struct isis_circuit *circuit; - ifp = (struct interface *)list_entry; + ifp = (struct interface *)args->list_entry; if (!ifp) return NULL; @@ -382,5 +381,5 @@ lib_interface_isis_event_counters_authentication_fails_get_elem( if (!circuit) return NULL; - return yang_data_new_uint32(xpath, circuit->auth_failures); + return yang_data_new_uint32(args->xpath, circuit->auth_failures); } diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 9153512623..e8a0ba02e9 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -164,7 +164,7 @@ static int process_p2p_hello(struct iih_info *iih) if (memcmp(iih->sys_id, adj->sysid, ISIS_SYS_ID_LEN)) { zlog_debug( "hello source and adjacency do not match, set adj down\n"); - isis_adj_state_change(adj, ISIS_ADJ_DOWN, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "adj do not exist"); return ISIS_OK; } @@ -184,7 +184,7 @@ static int process_p2p_hello(struct iih_info *iih) * adjacency entry getting added to the lsp tlv neighbor list. */ adj->circuit_t = iih->circ_type; - isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL); + isis_adj_state_change(&adj, ISIS_ADJ_INITIALIZING, NULL); adj->sys_type = ISIS_SYSTYPE_UNKNOWN; } @@ -233,7 +233,7 @@ static int process_p2p_hello(struct iih_info *iih) return ISIS_WARNING; } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { /* (6) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } @@ -254,7 +254,7 @@ static int process_p2p_hello(struct iih_info *iih) || (adj->adj_usage == ISIS_ADJ_LEVEL2)) { /* (8) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } @@ -268,7 +268,7 @@ static int process_p2p_hello(struct iih_info *iih) || (adj->adj_usage == ISIS_ADJ_LEVEL1AND2)) { /* (8) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } @@ -282,7 +282,7 @@ static int process_p2p_hello(struct iih_info *iih) || (adj->adj_usage == ISIS_ADJ_LEVEL2)) { /* (8) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } @@ -304,7 +304,7 @@ static int process_p2p_hello(struct iih_info *iih) || (adj->adj_usage == ISIS_ADJ_LEVEL2)) { /* (6) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } @@ -318,7 +318,7 @@ static int process_p2p_hello(struct iih_info *iih) } else if (adj->adj_usage == ISIS_ADJ_LEVEL1AND2) { /* (6) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } @@ -331,11 +331,11 @@ static int process_p2p_hello(struct iih_info *iih) if (iih->circuit->area->is_type == IS_LEVEL_1) { /* 8.2.5.2 b) 1) is_type L1 and adj is not up */ if (adj->adj_state != ISIS_ADJ_UP) { - isis_adj_state_change(adj, ISIS_ADJ_DOWN, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Area Mismatch"); /* 8.2.5.2 b) 2)is_type L1 and adj is up */ } else { - isis_adj_state_change(adj, ISIS_ADJ_DOWN, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Down - Area Mismatch"); } } @@ -349,7 +349,7 @@ static int process_p2p_hello(struct iih_info *iih) return ISIS_WARNING; } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { /* (7) down - area mismatch */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Area Mismatch"); @@ -358,7 +358,7 @@ static int process_p2p_hello(struct iih_info *iih) || (adj->adj_usage == ISIS_ADJ_LEVEL2)) { /* (7) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } @@ -371,7 +371,7 @@ static int process_p2p_hello(struct iih_info *iih) ISIS_ADJ_LEVEL2); } else if (adj->adj_usage == ISIS_ADJ_LEVEL1) { /* (7) down - wrong system */ - isis_adj_state_change(adj, + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Wrong System"); } else if (adj->adj_usage @@ -379,12 +379,12 @@ static int process_p2p_hello(struct iih_info *iih) if (iih->circ_type == IS_LEVEL_2) { /* (7) down - wrong system */ isis_adj_state_change( - adj, ISIS_ADJ_DOWN, + &adj, ISIS_ADJ_DOWN, "Wrong System"); } else { /* (7) down - area mismatch */ isis_adj_state_change( - adj, ISIS_ADJ_DOWN, + &adj, ISIS_ADJ_DOWN, "Area Mismatch"); } } @@ -393,34 +393,36 @@ static int process_p2p_hello(struct iih_info *iih) } } else { /* down - area mismatch */ - isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Area Mismatch"); + isis_adj_state_change(&adj, ISIS_ADJ_DOWN, "Area Mismatch"); } - if (adj->adj_state == ISIS_ADJ_UP && changed) { - lsp_regenerate_schedule(adj->circuit->area, - isis_adj_usage2levels(adj->adj_usage), - 0); - } + if (adj) { + if (adj->adj_state == ISIS_ADJ_UP && changed) { + lsp_regenerate_schedule( + adj->circuit->area, + isis_adj_usage2levels(adj->adj_usage), 0); + } - /* 8.2.5.2 c) if the action was up - comparing circuit IDs */ - /* FIXME - Missing parts */ + /* 8.2.5.2 c) if the action was up - comparing circuit IDs */ + /* FIXME - Missing parts */ - /* some of my own understanding of the ISO, why the heck does - * it not say what should I change the system_type to... - */ - switch (adj->adj_usage) { - case ISIS_ADJ_LEVEL1: - adj->sys_type = ISIS_SYSTYPE_L1_IS; - break; - case ISIS_ADJ_LEVEL2: - adj->sys_type = ISIS_SYSTYPE_L2_IS; - break; - case ISIS_ADJ_LEVEL1AND2: - adj->sys_type = ISIS_SYSTYPE_L2_IS; - break; - case ISIS_ADJ_NONE: - adj->sys_type = ISIS_SYSTYPE_UNKNOWN; - break; + /* some of my own understanding of the ISO, why the heck does + * it not say what should I change the system_type to... + */ + switch (adj->adj_usage) { + case ISIS_ADJ_LEVEL1: + adj->sys_type = ISIS_SYSTYPE_L1_IS; + break; + case ISIS_ADJ_LEVEL2: + adj->sys_type = ISIS_SYSTYPE_L2_IS; + break; + case ISIS_ADJ_LEVEL1AND2: + adj->sys_type = ISIS_SYSTYPE_L2_IS; + break; + case ISIS_ADJ_NONE: + adj->sys_type = ISIS_SYSTYPE_UNKNOWN; + break; + } } if (isis->debugs & DEBUG_ADJ_PACKETS) { @@ -455,7 +457,7 @@ static int process_lan_hello(struct iih_info *iih) } adj->level = iih->level; } - isis_adj_state_change(adj, ISIS_ADJ_INITIALIZING, NULL); + isis_adj_state_change(&adj, ISIS_ADJ_INITIALIZING, NULL); if (iih->level == IS_LEVEL_1) adj->sys_type = ISIS_SYSTYPE_L1_IS; @@ -506,13 +508,13 @@ static int process_lan_hello(struct iih_info *iih) if (adj->adj_state != ISIS_ADJ_UP) { if (own_snpa_found) { isis_adj_state_change( - adj, ISIS_ADJ_UP, + &adj, ISIS_ADJ_UP, "own SNPA found in LAN Neighbours TLV"); } } else { if (!own_snpa_found) { isis_adj_state_change( - adj, ISIS_ADJ_INITIALIZING, + &adj, ISIS_ADJ_INITIALIZING, "own SNPA not found in LAN Neighbours TLV"); } } diff --git a/isisd/isisd.c b/isisd/isisd.c index c61c7f0e0c..298629e246 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -73,7 +73,6 @@ int area_clear_net_title(struct vty *, const char *); int show_isis_interface_common(struct vty *, const char *ifname, char); int show_isis_neighbor_common(struct vty *, const char *id, char); int clear_isis_neighbor_common(struct vty *, const char *id); -int isis_config_write(struct vty *); void isis_new(unsigned long process_id, vrf_id_t vrf_id) @@ -654,7 +653,7 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id) sysid, ISIS_SYS_ID_LEN)) isis_adj_state_change( - adj, + &adj, ISIS_ADJ_DOWN, "clear user request"); } @@ -666,7 +665,7 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id) || !memcmp(adj->sysid, sysid, ISIS_SYS_ID_LEN)) isis_adj_state_change( - adj, ISIS_ADJ_DOWN, + &adj, ISIS_ADJ_DOWN, "clear user request"); } } @@ -784,8 +783,14 @@ DEFUN_NOSH (show_debugging, return CMD_SUCCESS; } +static int config_write_debug(struct vty *vty); /* Debug node. */ -static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = config_write_debug, +}; static int config_write_debug(struct vty *vty) { @@ -1852,7 +1857,7 @@ DEFUN (no_log_adj_changes, #endif /* ifdef FABRICD */ #ifdef FABRICD /* IS-IS configuration write function */ -int isis_config_write(struct vty *vty) +static int isis_config_write(struct vty *vty) { int write = 0; @@ -2124,9 +2129,16 @@ int isis_config_write(struct vty *vty) return write; } +struct cmd_node router_node = { + .name = "openfabric", + .node = OPENFABRIC_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", + .config_write = isis_config_write, +}; #else /* IS-IS configuration write function */ -int isis_config_write(struct vty *vty) +static int isis_config_write(struct vty *vty) { int write = 0; struct lyd_node *dnode; @@ -2139,14 +2151,20 @@ int isis_config_write(struct vty *vty) return write; } -#endif /* ifdef FABRICD */ -struct cmd_node router_node = {ROUTER_NODE, "%s(config-router)# ", 1}; +struct cmd_node router_node = { + .name = "isis", + .node = ISIS_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", + .config_write = isis_config_write, +}; +#endif /* ifdef FABRICD */ void isis_init(void) { /* Install IS-IS top node */ - install_node(&router_node, isis_config_write); + install_node(&router_node); install_element(VIEW_NODE, &show_isis_summary_cmd); @@ -2167,7 +2185,7 @@ void isis_init(void) install_element(ENABLE_NODE, &show_debugging_isis_cmd); - install_node(&debug_node, config_write_debug); + install_node(&debug_node); install_element(ENABLE_NODE, &debug_isis_adj_cmd); install_element(ENABLE_NODE, &no_debug_isis_adj_cmd); diff --git a/isisd/subdir.am b/isisd/subdir.am index 5dddb7d345..94f9116d34 100644 --- a/isisd/subdir.am +++ b/isisd/subdir.am @@ -7,12 +7,12 @@ noinst_LIBRARIES += isisd/libisis.a sbin_PROGRAMS += isisd/isisd dist_examples_DATA += isisd/isisd.conf.sample vtysh_scan += \ - $(top_srcdir)/isisd/isis_cli.c \ - $(top_srcdir)/isisd/isis_redist.c \ - $(top_srcdir)/isisd/isis_spf.c \ - $(top_srcdir)/isisd/isis_te.c \ - $(top_srcdir)/isisd/isis_vty_fabricd.c \ - $(top_srcdir)/isisd/isisd.c \ + isisd/isis_cli.c \ + isisd/isis_redist.c \ + isisd/isis_spf.c \ + isisd/isis_te.c \ + isisd/isis_vty_fabricd.c \ + isisd/isisd.c \ # end man8 += $(MANBUILD)/frr-isisd.8 endif @@ -106,8 +106,9 @@ isisd_libisis_a_SOURCES = \ isisd/isis_cli.c \ #end -isisd/isis_cli_clippy.c: $(CLIPPY_DEPS) -isisd/isis_cli.$(OBJEXT): isisd/isis_cli_clippy.c +clippy_scan += \ + isisd/isis_cli.c \ + # end isisd_isisd_LDADD = isisd/libisis.a $(ISIS_LDADD_COMMON) isisd_isisd_SOURCES = $(ISIS_SOURCES) diff --git a/ldpd/lde.c b/ldpd/lde.c index ae883078dd..968fc490fb 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -56,7 +56,7 @@ static void lde_map_free(void *); static int lde_address_add(struct lde_nbr *, struct lde_addr *); static int lde_address_del(struct lde_nbr *, struct lde_addr *); static void lde_address_list_free(struct lde_nbr *); -static void zclient_sync_init(unsigned short instance); +static void zclient_sync_init(void); static void lde_label_list_init(void); static int lde_get_label_chunk(void); static void on_get_label_chunk_response(uint32_t start, uint32_t end); @@ -173,8 +173,7 @@ lde_init(struct ldpd_init *init) /* Init synchronous zclient and label list */ frr_zclient_addr(&zclient_addr, &zclient_addr_len, init->zclient_serv_path); - zclient_sync_init(init->instance); - lde_label_list_init(); + zclient_sync_init(); } static void @@ -1746,36 +1745,67 @@ lde_address_list_free(struct lde_nbr *ln) free(lde_addr); } -static void zclient_sync_init(unsigned short instance) +/* + * Event callback used to retry the label-manager sync zapi session. + */ +static int zclient_sync_retry(struct thread *thread) +{ + zclient_sync_init(); + + return 0; +} + +/* + * Initialize and open a synchronous zapi session. This is used by label chunk + * management code, which acquires and releases blocks of labels from the + * zebra label-manager module. + */ +static void zclient_sync_init(void) { struct zclient_options options = zclient_options_default; + options.synchronous = true; /* Initialize special zclient for synchronous message exchanges. */ zclient_sync = zclient_new(master, &options); zclient_sync->sock = -1; zclient_sync->redist_default = ZEBRA_ROUTE_LDP; - zclient_sync->instance = instance; + zclient_sync->session_id = 1; /* Distinguish from main session */ zclient_sync->privs = &lde_privs; - while (zclient_socket_connect(zclient_sync) < 0) { + if (zclient_socket_connect(zclient_sync) < 0) { log_warnx("Error connecting synchronous zclient!"); - sleep(1); + goto retry; } /* make socket non-blocking */ sock_set_nonblock(zclient_sync->sock); /* Send hello to notify zebra this is a synchronous client */ - while (zclient_send_hello(zclient_sync) < 0) { + if (zclient_send_hello(zclient_sync) < 0) { log_warnx("Error sending hello for synchronous zclient!"); - sleep(1); + goto retry; } /* Connect to label manager */ - while (lm_label_manager_connect(zclient_sync, 0) != 0) { + if (lm_label_manager_connect(zclient_sync, 0) != 0) { log_warnx("Error connecting to label manager!"); - sleep(1); + goto retry; } + + /* Finish label-manager init once the LM session is running */ + lde_label_list_init(); + + return; + +retry: + + /* Discard failed zclient object */ + zclient_stop(zclient_sync); + zclient_free(zclient_sync); + zclient_sync = NULL; + + /* Retry using a timer */ + thread_add_timer(master, zclient_sync_retry, NULL, 1, NULL); } static void diff --git a/ldpd/ldp_debug.c b/ldpd/ldp_debug.c index ec70ef510a..b9ef60ff94 100644 --- a/ldpd/ldp_debug.c +++ b/ldpd/ldp_debug.c @@ -29,12 +29,14 @@ struct ldp_debug conf_ldp_debug; struct ldp_debug ldp_debug; +static int ldp_debug_config_write(struct vty *); + /* Debug node. */ -struct cmd_node ldp_debug_node = -{ - DEBUG_NODE, - "", - 1 +struct cmd_node ldp_debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = ldp_debug_config_write, }; int @@ -142,7 +144,7 @@ ldp_vty_show_debugging(struct vty *vty) return (CMD_SUCCESS); } -int +static int ldp_debug_config_write(struct vty *vty) { int write = 0; diff --git a/ldpd/ldp_vty.h b/ldpd/ldp_vty.h index af5f1d5616..f6ba8f8c97 100644 --- a/ldpd/ldp_vty.h +++ b/ldpd/ldp_vty.h @@ -33,9 +33,6 @@ extern struct cmd_node ldp_debug_node; union ldpd_addr; int ldp_get_address(const char *, int *, union ldpd_addr *); -int ldp_config_write(struct vty *); -int ldp_l2vpn_config_write(struct vty *); -int ldp_debug_config_write(struct vty *); int ldp_vty_mpls_ldp (struct vty *, const char *); int ldp_vty_address_family (struct vty *, const char *, const char *); int ldp_vty_disc_holdtime(struct vty *, const char *, enum hello_type, long); diff --git a/ldpd/ldp_vty_cmds.c b/ldpd/ldp_vty_cmds.c index c10c6ae35c..fc84c7f76b 100644 --- a/ldpd/ldp_vty_cmds.c +++ b/ldpd/ldp_vty_cmds.c @@ -779,14 +779,14 @@ ldp_vty_init (void) { cmd_variable_handler_register(l2vpn_var_handlers); - install_node(&ldp_node, ldp_config_write); - install_node(&ldp_ipv4_node, NULL); - install_node(&ldp_ipv6_node, NULL); - install_node(&ldp_ipv4_iface_node, NULL); - install_node(&ldp_ipv6_iface_node, NULL); - install_node(&ldp_l2vpn_node, ldp_l2vpn_config_write); - install_node(&ldp_pseudowire_node, NULL); - install_node(&ldp_debug_node, ldp_debug_config_write); + install_node(&ldp_node); + install_node(&ldp_ipv4_node); + install_node(&ldp_ipv6_node); + install_node(&ldp_ipv4_iface_node); + install_node(&ldp_ipv6_iface_node); + install_node(&ldp_l2vpn_node); + install_node(&ldp_pseudowire_node); + install_node(&ldp_debug_node); install_default(LDP_NODE); install_default(LDP_IPV4_NODE); install_default(LDP_IPV6_NODE); diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index 84a5c0b1b2..3abd0817a8 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -30,60 +30,64 @@ #include "vty.h" #include "ldp_vty.h" +static int ldp_config_write(struct vty *); static void ldp_af_iface_config_write(struct vty *, int); static void ldp_af_config_write(struct vty *, int, struct ldpd_conf *, struct ldpd_af_conf *); +static int ldp_l2vpn_config_write(struct vty *); static void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *); static int ldp_vty_get_af(struct vty *); static int ldp_iface_is_configured(struct ldpd_conf *, const char *); -struct cmd_node ldp_node = -{ - LDP_NODE, - "%s(config-ldp)# ", - 1, +struct cmd_node ldp_node = { + .name = "ldp", + .node = LDP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-ldp)# ", + .config_write = ldp_config_write, }; -struct cmd_node ldp_ipv4_node = -{ - LDP_IPV4_NODE, - "%s(config-ldp-af)# ", - 1, +struct cmd_node ldp_ipv4_node = { + .name = "ldp ipv4", + .node = LDP_IPV4_NODE, + .parent_node = LDP_NODE, + .prompt = "%s(config-ldp-af)# ", }; -struct cmd_node ldp_ipv6_node = -{ - LDP_IPV6_NODE, - "%s(config-ldp-af)# ", - 1, +struct cmd_node ldp_ipv6_node = { + .name = "ldp ipv6", + .node = LDP_IPV6_NODE, + .parent_node = LDP_NODE, + .prompt = "%s(config-ldp-af)# ", }; -struct cmd_node ldp_ipv4_iface_node = -{ - LDP_IPV4_IFACE_NODE, - "%s(config-ldp-af-if)# ", - 1, +struct cmd_node ldp_ipv4_iface_node = { + .name = "ldp ipv4 interface", + .node = LDP_IPV4_IFACE_NODE, + .parent_node = LDP_IPV4_NODE, + .prompt = "%s(config-ldp-af-if)# ", }; -struct cmd_node ldp_ipv6_iface_node = -{ - LDP_IPV6_IFACE_NODE, - "%s(config-ldp-af-if)# ", - 1, +struct cmd_node ldp_ipv6_iface_node = { + .name = "ldp ipv6 interface", + .node = LDP_IPV6_IFACE_NODE, + .parent_node = LDP_IPV6_NODE, + .prompt = "%s(config-ldp-af-if)# ", }; -struct cmd_node ldp_l2vpn_node = -{ - LDP_L2VPN_NODE, - "%s(config-l2vpn)# ", - 1, +struct cmd_node ldp_l2vpn_node = { + .name = "ldp l2vpn", + .node = LDP_L2VPN_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-l2vpn)# ", + .config_write = ldp_l2vpn_config_write, }; -struct cmd_node ldp_pseudowire_node = -{ - LDP_PSEUDOWIRE_NODE, - "%s(config-l2vpn-pw)# ", - 1, +struct cmd_node ldp_pseudowire_node = { + .name = "ldp", + .node = LDP_PSEUDOWIRE_NODE, + .parent_node = LDP_L2VPN_NODE, + .prompt = "%s(config-l2vpn-pw)# ", }; int @@ -240,7 +244,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf, vty_out(vty, " exit-address-family\n"); } -int +static int ldp_config_write(struct vty *vty) { struct nbr_params *nbrp; @@ -345,7 +349,7 @@ ldp_l2vpn_pw_config_write(struct vty *vty, struct l2vpn_pw *pw) vty_out (vty," ! Incomplete config, specify a pw-id\n"); } -int +static int ldp_l2vpn_config_write(struct vty *vty) { struct l2vpn *l2vpn; diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c index 66c127abdc..d317da7b20 100644 --- a/ldpd/ldp_vty_exec.c +++ b/ldpd/ldp_vty_exec.c @@ -193,7 +193,8 @@ show_interface_msg_json(struct imsg *imsg, struct show_params *params, json_object_int_add(json_iface, "adjacencyCount", iface->adj_cnt); - sprintf(key_name, "%s: %s", iface->name, af_name(iface->af)); + snprintf(key_name, sizeof(key_name), "%s: %s", iface->name, + af_name(iface->af)); json_object_object_add(json, key_name, json_iface); break; case IMSG_CTL_END: @@ -1328,7 +1329,8 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params, json_object_string_add(json_pw, "remoteLabel", "unassigned"); - sprintf(key_name, "%s: %u", inet_ntoa(pw->lsr_id), pw->pwid); + snprintf(key_name, sizeof(key_name), "%s: %u", + inet_ntoa(pw->lsr_id), pw->pwid); json_object_object_add(json, key_name, json_pw); break; case IMSG_CTL_END: diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index b3ccb77602..28e56ecd64 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -108,8 +108,7 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr) struct zapi_labels zl = {}; struct zapi_nexthop *znh; - if (kr->local_label < MPLS_LABEL_RESERVED_MAX || - kr->remote_label == NO_LABEL) + if (kr->local_label < MPLS_LABEL_RESERVED_MAX) return (0); debug_zebra_out("prefix %s/%u nexthop %s ifindex %u labels %s/%s (%s)", @@ -122,21 +121,32 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr) zl.local_label = kr->local_label; /* Set prefix. */ - SET_FLAG(zl.message, ZAPI_LABELS_FTN); - zl.route.prefix.family = kr->af; - switch (kr->af) { - case AF_INET: - zl.route.prefix.u.prefix4 = kr->prefix.v4; - break; - case AF_INET6: - zl.route.prefix.u.prefix6 = kr->prefix.v6; - break; - default: - fatalx("ldp_zebra_send_mpls_labels: unknown af"); + if (kr->remote_label != NO_LABEL) { + SET_FLAG(zl.message, ZAPI_LABELS_FTN); + zl.route.prefix.family = kr->af; + switch (kr->af) { + case AF_INET: + zl.route.prefix.u.prefix4 = kr->prefix.v4; + break; + case AF_INET6: + zl.route.prefix.u.prefix6 = kr->prefix.v6; + break; + default: + fatalx("ldp_zebra_send_mpls_labels: unknown af"); + } + zl.route.prefix.prefixlen = kr->prefixlen; + zl.route.type = kr->route_type; + zl.route.instance = kr->route_instance; } - zl.route.prefix.prefixlen = kr->prefixlen; - zl.route.type = kr->route_type; - zl.route.instance = kr->route_instance; + + /* + * For broken LSPs, instruct the forwarding plane to pop the top-level + * label and forward packets normally. This is a best-effort attempt + * to deliver labeled IP packets to their final destination (instead of + * dropping them). + */ + if (kr->remote_label == NO_LABEL) + kr->remote_label = MPLS_LABEL_IMPLICIT_NULL; /* Set nexthop. */ zl.nexthop_num = 1; diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 741c8c4655..0e05f3c6a6 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -180,6 +180,7 @@ static struct quagga_signal_t ldp_signals[] = }; static const struct frr_yang_module_info *const ldpd_yang_modules[] = { + &frr_vrf_info, }; FRR_DAEMON_INFO(ldpd, LDP, @@ -238,9 +239,6 @@ main(int argc, char *argv[]) " --ctl_socket Override ctl socket path\n" " -n, --instance Instance id\n"); - /* set default instance (to differentiate ldpd socket from lde one */ - init.instance = 1; - while (1) { int opt; @@ -308,9 +306,15 @@ main(int argc, char *argv[]) exit(1); } - if (lflag || eflag) - openzlog(ldpd_di.progname, "LDP", 0, - LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); + if (lflag || eflag) { + struct zprivs_ids_t ids; + + zprivs_preinit(&ldpd_privs); + zprivs_get_ids(&ids); + + zlog_init(ldpd_di.progname, "LDP", 0, + ids.uid_normal, ids.gid_normal); + } if (lflag) lde(); else if (eflag) @@ -486,7 +490,7 @@ ldpd_shutdown(void) static pid_t start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync) { - char *argv[3]; + char *argv[7]; int argc = 0, nullfd; pid_t pid; @@ -529,6 +533,11 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync) argv[argc++] = (char *)"-E"; break; } + + argv[argc++] = (char *)"-u"; + argv[argc++] = (char *)ldpd_privs.user; + argv[argc++] = (char *)"-g"; + argv[argc++] = (char *)ldpd_privs.group; argv[argc++] = NULL; execvp(argv0, argv); diff --git a/ldpd/log.c b/ldpd/log.c index b138e5754a..1903017588 100644 --- a/ldpd/log.c +++ b/ldpd/log.c @@ -24,7 +24,6 @@ #include "log.h" #include <lib/log.h> -#include <lib/log_int.h> const char *log_procname; diff --git a/ldpd/subdir.am b/ldpd/subdir.am index f464bad9e7..09936e5c28 100644 --- a/ldpd/subdir.am +++ b/ldpd/subdir.am @@ -6,7 +6,7 @@ if LDPD noinst_LIBRARIES += ldpd/libldp.a sbin_PROGRAMS += ldpd/ldpd dist_examples_DATA += ldpd/ldpd.conf.sample -vtysh_scan += $(top_srcdir)/ldpd/ldp_vty_cmds.c +vtysh_scan += ldpd/ldp_vty_cmds.c man8 += $(MANBUILD)/frr-ldpd.8 endif @@ -40,8 +40,9 @@ ldpd_libldp_a_SOURCES = \ ldpd/util.c \ # end -ldpd/ldp_vty_cmds_clippy.c: $(CLIPPY_DEPS) -ldpd/ldp_vty_cmds.$(OBJEXT): ldpd/ldp_vty_cmds_clippy.c +clippy_scan += \ + ldpd/ldp_vty_cmds.c \ + # end noinst_HEADERS += \ ldpd/control.h \ diff --git a/lib/agentx.c b/lib/agentx.c index d1b801fe8c..7c4bdcbe27 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -158,9 +158,13 @@ static void agentx_events_update(void) } /* AgentX node. */ -static struct cmd_node agentx_node = {SMUX_NODE, - "", /* AgentX has no interface. */ - 1}; +static int config_write_agentx(struct vty *vty); +static struct cmd_node agentx_node = { + .name = "smux", + .node = SMUX_NODE, + .prompt = "", + .config_write = config_write_agentx, +}; /* Logging NetSNMP messages */ static int agentx_log_callback(int major, int minor, void *serverarg, @@ -246,7 +250,7 @@ void smux_init(struct thread_master *tm) agentx_log_callback, NULL); init_agent(FRR_SMUX_NAME); - install_node(&agentx_node, config_write_agentx); + install_node(&agentx_node); install_element(CONFIG_NODE, &agentx_enable_cmd); install_element(CONFIG_NODE, &no_agentx_cmd); } diff --git a/lib/atomlist.h b/lib/atomlist.h index 621db6824f..5ca19cbcd4 100644 --- a/lib/atomlist.h +++ b/lib/atomlist.h @@ -20,6 +20,10 @@ #include "typesafe.h" #include "frratomic.h" +#ifdef __cplusplus +extern "C" { +#endif + /* pointer with lock/deleted/invalid bit in lowest bit * * for atomlist/atomsort, "locked" means "this pointer can't be updated, the @@ -34,7 +38,11 @@ * ATOMPTR_USER is currently unused (and available for atomic hash or skiplist * implementations.) */ -typedef uintptr_t atomptr_t; + +/* atomic_atomptr_t may look a bit odd, it's for the sake of C++ compat */ +typedef uintptr_t atomptr_t; +typedef atomic_uintptr_t atomic_atomptr_t; + #define ATOMPTR_MASK (UINTPTR_MAX - 3) #define ATOMPTR_LOCK (1) #define ATOMPTR_USER (2) @@ -104,13 +112,13 @@ static inline bool atomptr_u(atomptr_t val) /* don't use these structs directly */ struct atomlist_item { - _Atomic atomptr_t next; + atomic_uintptr_t next; }; #define atomlist_itemp(val) ((struct atomlist_item *)atomptr_p(val)) struct atomlist_head { - _Atomic atomptr_t first, last; - _Atomic size_t count; + atomic_uintptr_t first, last; + atomic_size_t count; }; /* use as: @@ -133,7 +141,7 @@ macro_inline void prefix ## _add_head(struct prefix##_head *h, type *item) \ macro_inline void prefix ## _add_tail(struct prefix##_head *h, type *item) \ { atomlist_add_tail(&h->ah, &item->field.ai); } \ macro_inline void prefix ## _del_hint(struct prefix##_head *h, type *item, \ - _Atomic atomptr_t *hint) \ + atomic_atomptr_t *hint) \ { atomlist_del_hint(&h->ah, &item->field.ai, hint); } \ macro_inline type *prefix ## _del(struct prefix##_head *h, type *item) \ { atomlist_del_hint(&h->ah, &item->field.ai, NULL); \ @@ -189,7 +197,7 @@ void atomlist_add_tail(struct atomlist_head *h, struct atomlist_item *item); * reads starting later. */ void atomlist_del_hint(struct atomlist_head *h, struct atomlist_item *item, - _Atomic atomptr_t *hint); + atomic_atomptr_t *hint); /* pop: * @@ -202,13 +210,13 @@ struct atomlist_item *atomlist_pop(struct atomlist_head *h); struct atomsort_item { - _Atomic atomptr_t next; + atomic_atomptr_t next; }; #define atomsort_itemp(val) ((struct atomsort_item *)atomptr_p(val)) struct atomsort_head { - _Atomic atomptr_t first; - _Atomic size_t count; + atomic_atomptr_t first; + atomic_size_t count; }; #define _PREDECL_ATOMSORT(prefix) \ @@ -271,7 +279,7 @@ macro_inline type *prefix ## _find_lt(struct prefix##_head *h, \ return prev; \ } \ macro_inline void prefix ## _del_hint(struct prefix##_head *h, type *item, \ - _Atomic atomptr_t *hint) \ + atomic_atomptr_t *hint) \ { \ atomsort_del_hint(&h->ah, &item->field.ai, hint); \ } \ @@ -353,8 +361,12 @@ struct atomsort_item *atomsort_add(struct atomsort_head *h, const struct atomsort_item *)); void atomsort_del_hint(struct atomsort_head *h, - struct atomsort_item *item, _Atomic atomptr_t *hint); + struct atomsort_item *item, atomic_atomptr_t *hint); struct atomsort_item *atomsort_pop(struct atomsort_head *h); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_ATOMLIST_H */ diff --git a/lib/bitfield.h b/lib/bitfield.h index eebfc049d9..72980165f9 100644 --- a/lib/bitfield.h +++ b/lib/bitfield.h @@ -152,9 +152,8 @@ typedef unsigned int word_t; */ #define bf_free(v) \ do { \ - if ((v).data) { \ - free((v).data); \ - } \ + free((v).data); \ + (v).data = NULL; \ } while (0) #ifdef __cplusplus diff --git a/lib/clippy.c b/lib/clippy.c index cd8067f5eb..2e09c24c66 100644 --- a/lib/clippy.c +++ b/lib/clippy.c @@ -107,21 +107,11 @@ int main(int argc, char **argv) #include "log.h" #include "zassert.h" -#define ZLOG_FUNC(FUNCNAME) \ - void FUNCNAME(const char *format, ...) \ - { \ - va_list args; \ - va_start(args, format); \ - vfprintf(stderr, format, args); \ - fputs("\n", stderr); \ - va_end(args); \ - } - -ZLOG_FUNC(zlog_err) -ZLOG_FUNC(zlog_warn) -ZLOG_FUNC(zlog_info) -ZLOG_FUNC(zlog_notice) -ZLOG_FUNC(zlog_debug) +void vzlog(int prio, const char *format, va_list args) +{ + vfprintf(stderr, format, args); + fputs("\n", stderr); +} void _zlog_assert_failed(const char *assertion, const char *file, unsigned int line, const char *function) diff --git a/lib/command.c b/lib/command.c index 8811b3a791..38a7b3fe7c 100644 --- a/lib/command.c +++ b/lib/command.c @@ -31,7 +31,7 @@ #include "frrstr.h" #include "memory.h" #include "log.h" -#include "log_int.h" +#include "log_vty.h" #include "thread.h" #include "vector.h" #include "linklist.h" @@ -47,6 +47,7 @@ #include "hook.h" #include "lib_errors.h" #include "northbound_cli.h" +#include "network.h" DEFINE_MTYPE_STATIC(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, COMPLETION, "Completion item") @@ -73,86 +74,6 @@ const struct message tokennames[] = { item(END_TKN), {0}, }; - -const char *const node_names[] = { - "auth", // AUTH_NODE, - "view", // VIEW_NODE, - "auth enable", // AUTH_ENABLE_NODE, - "enable", // ENABLE_NODE, - "config", // CONFIG_NODE, - "debug", // DEBUG_NODE, - "vrf debug", // VRF_DEBUG_NODE, - "northbound debug", // NORTHBOUND_DEBUG_NODE, - "vnc debug", // DEBUG_VNC_NODE, - "route-map debug", /* RMAP_DEBUG_NODE */ - "resolver debug", /* RESOLVER_DEBUG_NODE */ - "aaa", // AAA_NODE, - "keychain", // KEYCHAIN_NODE, - "keychain key", // KEYCHAIN_KEY_NODE, - "static ip", // IP_NODE, - "vrf", // VRF_NODE, - "interface", // INTERFACE_NODE, - "nexthop-group", // NH_GROUP_NODE, - "zebra", // ZEBRA_NODE, - "table", // TABLE_NODE, - "rip", // RIP_NODE, - "ripng", // RIPNG_NODE, - "babel", // BABEL_NODE, - "eigrp", // EIGRP_NODE, - "bgp", // BGP_NODE, - "bgp vpnv4", // BGP_VPNV4_NODE, - "bgp vpnv6", // BGP_VPNV6_NODE, - "bgp ipv4 unicast", // BGP_IPV4_NODE, - "bgp ipv4 multicast", // BGP_IPV4M_NODE, - "bgp ipv4 labeled unicast", // BGP_IPV4L_NODE, - "bgp ipv6", // BGP_IPV6_NODE, - "bgp ipv6 multicast", // BGP_IPV6M_NODE, - "bgp ipv6 labeled unicast", // BGP_IPV6L_NODE, - "bgp vrf policy", // BGP_VRF_POLICY_NODE, - "bgp vnc defaults", // BGP_VNC_DEFAULTS_NODE, - "bgp vnc nve", // BGP_VNC_NVE_GROUP_NODE, - "bgp vnc l2", // BGP_VNC_L2_GROUP_NODE, - "rfp defaults", // RFP_DEFAULTS_NODE, - "bgp evpn", // BGP_EVPN_NODE, - "ospf", // OSPF_NODE, - "ospf6", // OSPF6_NODE, - "ldp", // LDP_NODE, - "ldp ipv4", // LDP_IPV4_NODE, - "ldp ipv6", // LDP_IPV6_NODE, - "ldp ipv4 interface", // LDP_IPV4_IFACE_NODE, - "ldp ipv6 interface", // LDP_IPV6_IFACE_NODE, - "ldp l2vpn", // LDP_L2VPN_NODE, - "ldp", // LDP_PSEUDOWIRE_NODE, - "isis", // ISIS_NODE, - "ipv4 access list", // ACCESS_NODE, - "ipv4 prefix list", // PREFIX_NODE, - "ipv6 access list", // ACCESS_IPV6_NODE, - "MAC access list", // ACCESS_MAC_NODE, - "ipv6 prefix list", // PREFIX_IPV6_NODE, - "as list", // AS_LIST_NODE, - "community list", // COMMUNITY_LIST_NODE, - "routemap", // RMAP_NODE, - "pbr-map", // PBRMAP_NODE, - "smux", // SMUX_NODE, - "dump", // DUMP_NODE, - "forwarding", // FORWARDING_NODE, - "protocol", // PROTOCOL_NODE, - "mpls", // MPLS_NODE, - "pw", // PW_NODE, - "vty", // VTY_NODE, - "link-params", // LINK_PARAMS_NODE, - "bgp evpn vni", // BGP_EVPN_VNI_NODE, - "rpki", // RPKI_NODE - "bgp ipv4 flowspec", /* BGP_FLOWSPECV4_NODE - */ - "bgp ipv6 flowspec", /* BGP_FLOWSPECV6_NODE - */ - "bfd", /* BFD_NODE */ - "bfd peer", /* BFD_PEER_NODE */ - "openfabric", // OPENFABRIC_NODE - "vrrp", /* VRRP_NODE */ - "bmp", /* BMP_NODE */ -}; /* clang-format on */ /* Command vector which includes some level of command lists. Normally @@ -179,84 +100,45 @@ const char *cmd_domainname_get(void) return host.domainname; } +static int root_on_exit(struct vty *vty); + /* Standard command node structures. */ static struct cmd_node auth_node = { - AUTH_NODE, "Password: ", + .name = "auth", + .node = AUTH_NODE, + .prompt = "Password: ", }; static struct cmd_node view_node = { - VIEW_NODE, "%s> ", + .name = "view", + .node = VIEW_NODE, + .prompt = "%s> ", + .node_exit = root_on_exit, }; static struct cmd_node auth_enable_node = { - AUTH_ENABLE_NODE, "Password: ", + .name = "auth enable", + .node = AUTH_ENABLE_NODE, + .prompt = "Password: ", }; static struct cmd_node enable_node = { - ENABLE_NODE, "%s# ", + .name = "enable", + .node = ENABLE_NODE, + .prompt = "%s# ", + .node_exit = root_on_exit, }; -static struct cmd_node config_node = {CONFIG_NODE, "%s(config)# ", 1}; - -static const struct facility_map { - int facility; - const char *name; - size_t match; -} syslog_facilities[] = { - {LOG_KERN, "kern", 1}, - {LOG_USER, "user", 2}, - {LOG_MAIL, "mail", 1}, - {LOG_DAEMON, "daemon", 1}, - {LOG_AUTH, "auth", 1}, - {LOG_SYSLOG, "syslog", 1}, - {LOG_LPR, "lpr", 2}, - {LOG_NEWS, "news", 1}, - {LOG_UUCP, "uucp", 2}, - {LOG_CRON, "cron", 1}, -#ifdef LOG_FTP - {LOG_FTP, "ftp", 1}, -#endif - {LOG_LOCAL0, "local0", 6}, - {LOG_LOCAL1, "local1", 6}, - {LOG_LOCAL2, "local2", 6}, - {LOG_LOCAL3, "local3", 6}, - {LOG_LOCAL4, "local4", 6}, - {LOG_LOCAL5, "local5", 6}, - {LOG_LOCAL6, "local6", 6}, - {LOG_LOCAL7, "local7", 6}, - {0, NULL, 0}, +static int config_write_host(struct vty *vty); +static struct cmd_node config_node = { + .name = "config", + .node = CONFIG_NODE, + .parent_node = ENABLE_NODE, + .prompt = "%s(config)# ", + .config_write = config_write_host, + .node_exit = vty_config_node_exit, }; -static const char *facility_name(int facility) -{ - const struct facility_map *fm; - - for (fm = syslog_facilities; fm->name; fm++) - if (fm->facility == facility) - return fm->name; - return ""; -} - -static int facility_match(const char *str) -{ - const struct facility_map *fm; - - for (fm = syslog_facilities; fm->name; fm++) - if (!strncmp(str, fm->name, fm->match)) - return fm->facility; - return -1; -} - -static int level_match(const char *s) -{ - int level; - - for (level = 0; zlog_priority[level] != NULL; level++) - if (!strncmp(s, zlog_priority[level], 2)) - return level; - return ZLOG_DISABLED; -} - /* This is called from main when a daemon is invoked with -v or --version. */ void print_version(const char *progname) { @@ -345,10 +227,9 @@ static bool cmd_hash_cmp(const void *a, const void *b) } /* Install top node of command vector. */ -void install_node(struct cmd_node *node, int (*func)(struct vty *)) +void install_node(struct cmd_node *node) { vector_set_index(cmdvec, node->node, node); - node->func = func; node->cmdgraph = graph_new(); node->cmd_vector = vector_init(VECTOR_MIN_SIZE); // add start node @@ -386,9 +267,9 @@ void install_element(enum node_type ntype, const struct cmd_element *cmd) if (cnode == NULL) { fprintf(stderr, "%s[%s]:\n" - "\tnode %d (%s) does not exist.\n" + "\tnode %d does not exist.\n" "\tplease call install_node() before install_element()\n", - cmd->name, cmd->string, ntype, node_names[ntype]); + cmd->name, cmd->string, ntype); exit(EXIT_FAILURE); } @@ -397,7 +278,7 @@ void install_element(enum node_type ntype, const struct cmd_element *cmd) "%s[%s]:\n" "\tnode %d (%s) already has this command installed.\n" "\tduplicate install_element call?\n", - cmd->name, cmd->string, ntype, node_names[ntype]); + cmd->name, cmd->string, ntype, cnode->name); return; } @@ -435,9 +316,9 @@ void uninstall_element(enum node_type ntype, const struct cmd_element *cmd) if (cnode == NULL) { fprintf(stderr, "%s[%s]:\n" - "\tnode %d (%s) does not exist.\n" + "\tnode %d does not exist.\n" "\tplease call install_node() before uninstall_element()\n", - cmd->name, cmd->string, ntype, node_names[ntype]); + cmd->name, cmd->string, ntype); exit(EXIT_FAILURE); } @@ -446,7 +327,7 @@ void uninstall_element(enum node_type ntype, const struct cmd_element *cmd) "%s[%s]:\n" "\tnode %d (%s) does not have this command installed.\n" "\tduplicate uninstall_element call?\n", - cmd->name, cmd->string, ntype, node_names[ntype]); + cmd->name, cmd->string, ntype, cnode->name); return; } @@ -486,13 +367,15 @@ static char *zencrypt(const char *passwd) gettimeofday(&tv, 0); - to64(&salt[0], random(), 3); + to64(&salt[0], frr_weak_random(), 3); to64(&salt[3], tv.tv_usec, 3); salt[5] = '\0'; return crypt(passwd, salt); } +static bool full_cli; + /* This function write configuration of this host. */ static int config_write_host(struct vty *vty) { @@ -508,7 +391,7 @@ static int config_write_host(struct vty *vty) * which would cause other daemons to then switch to syslog when they * parse frr.conf. */ - if (strcmp(zlog_default->protoname, "WATCHFRR")) { + if (full_cli) { if (host.encrypt) { if (host.password_encrypt) vty_out(vty, "password 8 %s\n", @@ -523,59 +406,7 @@ static int config_write_host(struct vty *vty) vty_out(vty, "enable password %s\n", host.enable); } - - if (host.logfile - && (zlog_default->maxlvl[ZLOG_DEST_FILE] - != ZLOG_DISABLED)) { - vty_out(vty, "log file %s", host.logfile); - if (zlog_default->maxlvl[ZLOG_DEST_FILE] - != zlog_default->default_lvl) - vty_out(vty, " %s", - zlog_priority - [zlog_default->maxlvl - [ZLOG_DEST_FILE]]); - vty_out(vty, "\n"); - } - - if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] != ZLOG_DISABLED) { - vty_out(vty, "log stdout"); - if (zlog_default->maxlvl[ZLOG_DEST_STDOUT] - != zlog_default->default_lvl) - vty_out(vty, " %s", - zlog_priority - [zlog_default->maxlvl - [ZLOG_DEST_STDOUT]]); - vty_out(vty, "\n"); - } - - if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED) - vty_out(vty, "no log monitor\n"); - else if (zlog_default->maxlvl[ZLOG_DEST_MONITOR] - != zlog_default->default_lvl) - vty_out(vty, "log monitor %s\n", - zlog_priority[zlog_default->maxlvl - [ZLOG_DEST_MONITOR]]); - - if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) { - vty_out(vty, "log syslog"); - if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] - != zlog_default->default_lvl) - vty_out(vty, " %s", - zlog_priority[zlog_default->maxlvl - [ZLOG_DEST_SYSLOG]]); - vty_out(vty, "\n"); - } - - if (zlog_default->facility != LOG_DAEMON) - vty_out(vty, "log facility %s\n", - facility_name(zlog_default->facility)); - - if (zlog_default->record_priority == 1) - vty_out(vty, "log record-priority\n"); - - if (zlog_default->timestamp_precision > 0) - vty_out(vty, "log timestamp precision %d\n", - zlog_default->timestamp_precision); + log_config_write(vty); if (host.advanced) vty_out(vty, "service advanced-vty\n"); @@ -1448,90 +1279,25 @@ DEFUN (config_exit, return CMD_SUCCESS; } +static int root_on_exit(struct vty *vty) +{ + if (vty_shell(vty)) + exit(0); + else + vty->status = VTY_CLOSE; + return 0; +} + void cmd_exit(struct vty *vty) { - switch (vty->node) { - case VIEW_NODE: - case ENABLE_NODE: - if (vty_shell(vty)) - exit(0); - else - vty->status = VTY_CLOSE; - break; - case CONFIG_NODE: - vty->node = ENABLE_NODE; - vty_config_exit(vty); - break; - case INTERFACE_NODE: - case PW_NODE: - case VRF_NODE: - case NH_GROUP_NODE: - case ZEBRA_NODE: - case BGP_NODE: - case RIP_NODE: - case EIGRP_NODE: - case BABEL_NODE: - case RIPNG_NODE: - case OSPF_NODE: - case OSPF6_NODE: - case LDP_NODE: - case LDP_L2VPN_NODE: - case ISIS_NODE: - case OPENFABRIC_NODE: - case KEYCHAIN_NODE: - case RMAP_NODE: - case PBRMAP_NODE: - case VTY_NODE: - case BFD_NODE: - vty->node = CONFIG_NODE; - break; - case BGP_IPV4_NODE: - case BGP_IPV4M_NODE: - case BGP_IPV4L_NODE: - case BGP_VPNV4_NODE: - case BGP_VPNV6_NODE: - case BGP_FLOWSPECV4_NODE: - case BGP_FLOWSPECV6_NODE: - case BGP_VRF_POLICY_NODE: - case BGP_VNC_DEFAULTS_NODE: - case BGP_VNC_NVE_GROUP_NODE: - case BGP_VNC_L2_GROUP_NODE: - case BGP_IPV6_NODE: - case BGP_IPV6M_NODE: - case BGP_EVPN_NODE: - case BGP_IPV6L_NODE: - case BMP_NODE: - vty->node = BGP_NODE; - break; - case BGP_EVPN_VNI_NODE: - vty->node = BGP_EVPN_NODE; - break; - case LDP_IPV4_NODE: - case LDP_IPV6_NODE: - vty->node = LDP_NODE; - break; - case LDP_IPV4_IFACE_NODE: - vty->node = LDP_IPV4_NODE; - break; - case LDP_IPV6_IFACE_NODE: - vty->node = LDP_IPV6_NODE; - break; - case LDP_PSEUDOWIRE_NODE: - vty->node = LDP_L2VPN_NODE; - break; - case KEYCHAIN_KEY_NODE: - vty->node = KEYCHAIN_NODE; - break; - case LINK_PARAMS_NODE: - vty->node = INTERFACE_NODE; - break; - case BFD_PEER_NODE: - vty->node = BFD_NODE; - break; - default: - break; - } + struct cmd_node *cnode = vector_lookup(cmdvec, vty->node); + if (cnode->node_exit) { + if (!cnode->node_exit(vty)) + return; + } + if (cnode->parent_node) + vty->node = cnode->parent_node; if (vty->xpath_index > 0) vty->xpath_index--; } @@ -1556,7 +1322,6 @@ DEFUN (config_end, vty_config_exit(vty); vty->node = ENABLE_NODE; } - return CMD_SUCCESS; } @@ -1716,9 +1481,8 @@ static int vty_write_config(struct vty *vty) vty_out(vty, "!\n"); for (i = 0; i < vector_active(cmdvec); i++) - if ((node = vector_slot(cmdvec, i)) && node->func - && (node->vtysh || vty->type != VTY_SHELL)) { - if ((*node->func)(vty)) + if ((node = vector_slot(cmdvec, i)) && node->config_write) { + if ((*node->config_write)(vty)) vty_out(vty, "!\n"); } @@ -1772,7 +1536,8 @@ static int file_write_config(struct vty *vty) config_file_tmp = XMALLOC(MTYPE_TMP, strlen(config_file) + 8); - sprintf(config_file_tmp, "%s.XXXXXX", config_file); + snprintf(config_file_tmp, strlen(config_file) + 8, "%s.XXXXXX", + config_file); /* Open file to configuration write. */ fd = mkstemp(config_file_tmp); @@ -2273,7 +2038,8 @@ DEFUN (config_logmsg, int level; char *message; - if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED) + level = log_level_match(argv[idx_log_level]->arg); + if (level == ZLOG_DISABLED) return CMD_ERR_NO_MATCH; zlog(level, "%s", @@ -2284,348 +2050,6 @@ DEFUN (config_logmsg, return CMD_SUCCESS; } -DEFUN (show_logging, - show_logging_cmd, - "show logging", - SHOW_STR - "Show current logging configuration\n") -{ - struct zlog *zl = zlog_default; - - vty_out(vty, "Syslog logging: "); - if (zl->maxlvl[ZLOG_DEST_SYSLOG] == ZLOG_DISABLED) - vty_out(vty, "disabled"); - else - vty_out(vty, "level %s, facility %s, ident %s", - zlog_priority[zl->maxlvl[ZLOG_DEST_SYSLOG]], - facility_name(zl->facility), zl->ident); - vty_out(vty, "\n"); - - vty_out(vty, "Stdout logging: "); - if (zl->maxlvl[ZLOG_DEST_STDOUT] == ZLOG_DISABLED) - vty_out(vty, "disabled"); - else - vty_out(vty, "level %s", - zlog_priority[zl->maxlvl[ZLOG_DEST_STDOUT]]); - vty_out(vty, "\n"); - - vty_out(vty, "Monitor logging: "); - if (zl->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED) - vty_out(vty, "disabled"); - else - vty_out(vty, "level %s", - zlog_priority[zl->maxlvl[ZLOG_DEST_MONITOR]]); - vty_out(vty, "\n"); - - vty_out(vty, "File logging: "); - if ((zl->maxlvl[ZLOG_DEST_FILE] == ZLOG_DISABLED) || !zl->fp) - vty_out(vty, "disabled"); - else - vty_out(vty, "level %s, filename %s", - zlog_priority[zl->maxlvl[ZLOG_DEST_FILE]], - zl->filename); - vty_out(vty, "\n"); - - vty_out(vty, "Protocol name: %s\n", zl->protoname); - vty_out(vty, "Record priority: %s\n", - (zl->record_priority ? "enabled" : "disabled")); - vty_out(vty, "Timestamp precision: %d\n", zl->timestamp_precision); - - return CMD_SUCCESS; -} - -DEFUN (config_log_stdout, - config_log_stdout_cmd, - "log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", - "Logging control\n" - "Set stdout logging level\n" - LOG_LEVEL_DESC) -{ - int idx_log_level = 2; - - if (argc == idx_log_level) { - zlog_set_level(ZLOG_DEST_STDOUT, zlog_default->default_lvl); - return CMD_SUCCESS; - } - int level; - - if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED) - return CMD_ERR_NO_MATCH; - zlog_set_level(ZLOG_DEST_STDOUT, level); - return CMD_SUCCESS; -} - -DEFUN (no_config_log_stdout, - no_config_log_stdout_cmd, - "no log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", - NO_STR - "Logging control\n" - "Cancel logging to stdout\n" - LOG_LEVEL_DESC) -{ - zlog_set_level(ZLOG_DEST_STDOUT, ZLOG_DISABLED); - return CMD_SUCCESS; -} - -DEFUN (config_log_monitor, - config_log_monitor_cmd, - "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", - "Logging control\n" - "Set terminal line (monitor) logging level\n" - LOG_LEVEL_DESC) -{ - int idx_log_level = 2; - - if (argc == idx_log_level) { - zlog_set_level(ZLOG_DEST_MONITOR, zlog_default->default_lvl); - return CMD_SUCCESS; - } - int level; - - if ((level = level_match(argv[idx_log_level]->arg)) == ZLOG_DISABLED) - return CMD_ERR_NO_MATCH; - zlog_set_level(ZLOG_DEST_MONITOR, level); - return CMD_SUCCESS; -} - -DEFUN (no_config_log_monitor, - no_config_log_monitor_cmd, - "no log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", - NO_STR - "Logging control\n" - "Disable terminal line (monitor) logging\n" - LOG_LEVEL_DESC) -{ - zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); - return CMD_SUCCESS; -} - -static int set_log_file(struct vty *vty, const char *fname, int loglevel) -{ - int ret; - char *p = NULL; - const char *fullpath; - - /* Path detection. */ - if (!IS_DIRECTORY_SEP(*fname)) { - char cwd[MAXPATHLEN + 1]; - cwd[MAXPATHLEN] = '\0'; - - if (getcwd(cwd, MAXPATHLEN) == NULL) { - flog_err_sys(EC_LIB_SYSTEM_CALL, - "config_log_file: Unable to alloc mem!"); - return CMD_WARNING_CONFIG_FAILED; - } - - p = XMALLOC(MTYPE_TMP, strlen(cwd) + strlen(fname) + 2); - sprintf(p, "%s/%s", cwd, fname); - fullpath = p; - } else - fullpath = fname; - - ret = zlog_set_file(fullpath, loglevel); - - XFREE(MTYPE_TMP, p); - - if (!ret) { - if (vty) - vty_out(vty, "can't open logfile %s\n", fname); - return CMD_WARNING_CONFIG_FAILED; - } - - XFREE(MTYPE_HOST, host.logfile); - - host.logfile = XSTRDUP(MTYPE_HOST, fname); - -#if defined(HAVE_CUMULUS) - if (zlog_default->maxlvl[ZLOG_DEST_SYSLOG] != ZLOG_DISABLED) - zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED); -#endif - return CMD_SUCCESS; -} - -void command_setup_early_logging(const char *dest, const char *level) -{ - char *token; - - if (level) { - int nlevel = level_match(level); - - if (nlevel != ZLOG_DISABLED) - zlog_default->default_lvl = nlevel; - } - - if (!dest) - return; - - if (strcmp(dest, "stdout") == 0) { - zlog_set_level(ZLOG_DEST_STDOUT, zlog_default->default_lvl); - return; - } - - if (strcmp(dest, "syslog") == 0) { - zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl); - return; - } - - token = strstr(dest, ":"); - if (token == NULL) - return; - - token++; - - set_log_file(NULL, token, zlog_default->default_lvl); -} - -DEFUN (config_log_file, - config_log_file_cmd, - "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", - "Logging control\n" - "Logging to file\n" - "Logging filename\n" - LOG_LEVEL_DESC) -{ - int idx_filename = 2; - int idx_log_levels = 3; - if (argc == 4) { - int level; - if ((level = level_match(argv[idx_log_levels]->arg)) - == ZLOG_DISABLED) - return CMD_ERR_NO_MATCH; - return set_log_file(vty, argv[idx_filename]->arg, level); - } else - return set_log_file(vty, argv[idx_filename]->arg, - zlog_default->default_lvl); -} - -static void disable_log_file(void) -{ - zlog_reset_file(); - - XFREE(MTYPE_HOST, host.logfile); -} - -DEFUN (no_config_log_file, - no_config_log_file_cmd, - "no log file [FILENAME [LEVEL]]", - NO_STR - "Logging control\n" - "Cancel logging to file\n" - "Logging file name\n" - "Logging level\n") -{ - disable_log_file(); - return CMD_SUCCESS; -} - -DEFUN (config_log_syslog, - config_log_syslog_cmd, - "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", - "Logging control\n" - "Set syslog logging level\n" - LOG_LEVEL_DESC) -{ - int idx_log_levels = 2; - - if (argc == 3) { - int level; - if ((level = level_match(argv[idx_log_levels]->arg)) - == ZLOG_DISABLED) - return CMD_ERR_NO_MATCH; - zlog_set_level(ZLOG_DEST_SYSLOG, level); - return CMD_SUCCESS; - } else { - zlog_set_level(ZLOG_DEST_SYSLOG, zlog_default->default_lvl); - return CMD_SUCCESS; - } -} - -DEFUN (no_config_log_syslog, - no_config_log_syslog_cmd, - "no log syslog [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>] [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", - NO_STR - "Logging control\n" - "Cancel logging to syslog\n" - LOG_FACILITY_DESC - LOG_LEVEL_DESC) -{ - zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED); - return CMD_SUCCESS; -} - -DEFUN (config_log_facility, - config_log_facility_cmd, - "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>", - "Logging control\n" - "Facility parameter for syslog messages\n" - LOG_FACILITY_DESC) -{ - int idx_target = 2; - int facility = facility_match(argv[idx_target]->arg); - - zlog_default->facility = facility; - return CMD_SUCCESS; -} - -DEFUN (no_config_log_facility, - no_config_log_facility_cmd, - "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]", - NO_STR - "Logging control\n" - "Reset syslog facility to default (daemon)\n" - LOG_FACILITY_DESC) -{ - zlog_default->facility = LOG_DAEMON; - return CMD_SUCCESS; -} - -DEFUN (config_log_record_priority, - config_log_record_priority_cmd, - "log record-priority", - "Logging control\n" - "Log the priority of the message within the message\n") -{ - zlog_default->record_priority = 1; - return CMD_SUCCESS; -} - -DEFUN (no_config_log_record_priority, - no_config_log_record_priority_cmd, - "no log record-priority", - NO_STR - "Logging control\n" - "Do not log the priority of the message within the message\n") -{ - zlog_default->record_priority = 0; - return CMD_SUCCESS; -} - -DEFUN (config_log_timestamp_precision, - config_log_timestamp_precision_cmd, - "log timestamp precision (0-6)", - "Logging control\n" - "Timestamp configuration\n" - "Set the timestamp precision\n" - "Number of subsecond digits\n") -{ - int idx_number = 3; - zlog_default->timestamp_precision = - strtoul(argv[idx_number]->arg, NULL, 10); - return CMD_SUCCESS; -} - -DEFUN (no_config_log_timestamp_precision, - no_config_log_timestamp_precision_cmd, - "no log timestamp precision", - NO_STR - "Logging control\n" - "Timestamp configuration\n" - "Reset the timestamp precision to the default value of 0\n") -{ - zlog_default->timestamp_precision = 0; - return CMD_SUCCESS; -} - DEFUN (debug_memstats, debug_memstats_cmd, "[no] debug memstats-at-exit", @@ -2800,7 +2224,7 @@ DEFUN(find, if (regexec(&exp, cli->string, 0, NULL, 0) == 0) vty_out(vty, " (%s) %s\n", - node_names[node->node], cli->string); + node->name, cli->string); } } @@ -2848,9 +2272,6 @@ void cmd_init(int terminal) { struct utsname names; - if (array_size(node_names) != NODE_TYPE_MAX) - assert(!"Update the CLI node description array!"); - uname(&names); qobj_init(); @@ -2875,7 +2296,6 @@ void cmd_init(int terminal) #endif host.password = NULL; host.enable = NULL; - host.logfile = NULL; host.config = NULL; host.noconfig = (terminal < 0); host.lines = -1; @@ -2883,11 +2303,11 @@ void cmd_init(int terminal) host.motdfile = NULL; /* Install top nodes. */ - install_node(&view_node, NULL); - install_node(&enable_node, NULL); - install_node(&auth_node, NULL); - install_node(&auth_enable_node, NULL); - install_node(&config_node, config_write_host); + install_node(&view_node); + install_node(&enable_node); + install_node(&auth_node); + install_node(&auth_enable_node); + install_node(&config_node); /* Each node's basic commands. */ install_element(VIEW_NODE, &show_version_cmd); @@ -2903,7 +2323,6 @@ void cmd_init(int terminal) install_element(VIEW_NODE, &config_enable_cmd); install_element(VIEW_NODE, &config_terminal_length_cmd); install_element(VIEW_NODE, &config_terminal_no_length_cmd); - install_element(VIEW_NODE, &show_logging_cmd); install_element(VIEW_NODE, &show_commandtree_cmd); install_element(VIEW_NODE, &echo_cmd); install_element(VIEW_NODE, &autocomplete_cmd); @@ -2930,6 +2349,8 @@ void cmd_init(int terminal) install_element(CONFIG_NODE, &no_domainname_cmd); if (terminal > 0) { + full_cli = true; + install_element(CONFIG_NODE, &debug_memstats_cmd); install_element(CONFIG_NODE, &password_cmd); @@ -2937,23 +2358,6 @@ void cmd_init(int terminal) install_element(CONFIG_NODE, &enable_password_cmd); install_element(CONFIG_NODE, &no_enable_password_cmd); - install_element(CONFIG_NODE, &config_log_stdout_cmd); - install_element(CONFIG_NODE, &no_config_log_stdout_cmd); - install_element(CONFIG_NODE, &config_log_monitor_cmd); - install_element(CONFIG_NODE, &no_config_log_monitor_cmd); - install_element(CONFIG_NODE, &config_log_file_cmd); - install_element(CONFIG_NODE, &no_config_log_file_cmd); - install_element(CONFIG_NODE, &config_log_syslog_cmd); - install_element(CONFIG_NODE, &no_config_log_syslog_cmd); - install_element(CONFIG_NODE, &config_log_facility_cmd); - install_element(CONFIG_NODE, &no_config_log_facility_cmd); - install_element(CONFIG_NODE, &config_log_record_priority_cmd); - install_element(CONFIG_NODE, - &no_config_log_record_priority_cmd); - install_element(CONFIG_NODE, - &config_log_timestamp_precision_cmd); - install_element(CONFIG_NODE, - &no_config_log_timestamp_precision_cmd); install_element(CONFIG_NODE, &service_password_encrypt_cmd); install_element(CONFIG_NODE, &no_service_password_encrypt_cmd); install_element(CONFIG_NODE, &banner_motd_default_cmd); @@ -2963,6 +2367,7 @@ void cmd_init(int terminal) install_element(CONFIG_NODE, &service_terminal_length_cmd); install_element(CONFIG_NODE, &no_service_terminal_length_cmd); + log_cmd_init(); vrf_install_commands(); } @@ -3000,7 +2405,6 @@ void cmd_terminate(void) XFREE(MTYPE_HOST, host.password_encrypt); XFREE(MTYPE_HOST, host.enable); XFREE(MTYPE_HOST, host.enable_encrypt); - XFREE(MTYPE_HOST, host.logfile); XFREE(MTYPE_HOST, host.motdfile); XFREE(MTYPE_HOST, host.config); XFREE(MTYPE_HOST, host.motd); diff --git a/lib/command.h b/lib/command.h index ea8a76a964..725a201446 100644 --- a/lib/command.h +++ b/lib/command.h @@ -66,9 +66,6 @@ struct host { /* System wide terminal lines. */ int lines; - /* Log filename. */ - char *logfile; - /* config file name of this host */ char *config; int noconfig; @@ -149,6 +146,7 @@ enum node_type { MPLS_NODE, /* MPLS config node */ PW_NODE, /* Pseudowire config node */ VTY_NODE, /* Vty node. */ + FPM_NODE, /* Dataplane FPM node. */ LINK_PARAMS_NODE, /* Link-parameters node */ BGP_EVPN_VNI_NODE, /* BGP EVPN VNI */ RPKI_NODE, /* RPKI node for configuration of RPKI cache server @@ -165,22 +163,29 @@ enum node_type { extern vector cmdvec; extern const struct message tokennames[]; -extern const char *const node_names[]; + +/* for external users depending on struct layout */ +#define FRR_CMD_NODE_20200416 /* Node which has some commands and prompt string and configuration function pointer . */ struct cmd_node { + const char *name; + /* Node index. */ enum node_type node; + enum node_type parent_node; /* Prompt character at vty interface. */ const char *prompt; - /* Is this node's configuration goes to vtysh ? */ - int vtysh; - /* Node's configuration write function */ - int (*func)(struct vty *); + int (*config_write)(struct vty *); + + /* called when leaving the node on a VTY session. + * return 1 if normal exit processing should happen, 0 to suppress + */ + int (*node_exit)(struct vty *); /* Node's command graph */ struct graph *cmdgraph; @@ -434,7 +439,7 @@ struct cmd_node { #define NO_GR_NEIGHBOR_HELPER_CMD "Undo Graceful Restart Helper command for a neighbor\n" /* Prototypes. */ -extern void install_node(struct cmd_node *node, int (*)(struct vty *)); +extern void install_node(struct cmd_node *node); extern void install_default(enum node_type); extern void install_element(enum node_type, const struct cmd_element *); @@ -1,5 +1,5 @@ /* CSV - * Copyright (C) 2013 Cumulus Networks, Inc. + * Copyright (C) 2013,2020 Cumulus Networks, Inc. * * This file is part of Quagga. * @@ -22,6 +22,8 @@ #include "config.h" #endif +#include <zebra.h> + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -419,7 +421,7 @@ void csv_clone_record(csv_t *csv, csv_record_t *in_rec, csv_record_t **out_rec) } rec->record = curr; rec->rec_len = in_rec->rec_len; - strcpy(rec->record, in_rec->record); + strlcpy(rec->record, in_rec->record, csv->buflen); /* decode record into fields */ csv_decode_record(rec); @@ -635,10 +637,10 @@ void csv_dump(csv_t *csv) static int get_memory_usage(pid_t pid) { int fd, data, stack; - char buf[4096], status_child[BUFSIZ]; + char buf[4096], status_child[PATH_MAX]; char *vm; - sprintf(status_child, "/proc/%d/status", pid); + snprintf(status_child, sizeof(status_child), "/proc/%d/status", pid); if ((fd = open(status_child, O_RDONLY)) < 0) return -1; @@ -670,8 +672,8 @@ int main() log_verbose("Mem: %d\n", get_memory_usage(getpid())); csv_init(&csv, buf, 256); - sprintf(hdr1, "%4d", 0); - sprintf(hdr2, "%4d", 1); + snprintf(hdr1, sizeof(hdr1), "%4d", 0); + snprintf(hdr2, sizeof(hdr2), "%4d", 1); log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), atoi(hdr2)); rec = csv_encode(&csv, 2, hdr1, hdr2); @@ -683,8 +685,8 @@ int main() } csv_encode(&csv, 2, "pdfadfadfadsadsaddfdfdsfdsd", "35444554545454545"); log_verbose("%s\n", buf); - sprintf(hdr1, "%4d", csv.csv_len); - sprintf(hdr2, "%4d", 1); + snprintf(hdr1, sizeof(hdr1), "%4d", csv.csv_len); + snprintf(hdr2, sizeof(hdr2), "%4d", 1); log_verbose("(%zu/%zu/%d/%d)\n", strlen(hdr1), strlen(hdr2), atoi(hdr1), atoi(hdr2)); rec = csv_encode_record(&csv, rec, 2, hdr1, hdr2); diff --git a/lib/defaults.h b/lib/defaults.h index 7cdd18120e..20ef28db31 100644 --- a/lib/defaults.h +++ b/lib/defaults.h @@ -22,6 +22,10 @@ #include "compiler.h" +#ifdef __cplusplus +extern "C" { +#endif + /* frr_default wraps information about a default that has different * values depending on FRR version or default-set * @@ -135,4 +139,8 @@ extern bool frr_defaults_profile_valid(const char *profile); /* like strcmp(), but with version ordering */ extern int frr_version_cmp(const char *aa, const char *bb); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_DEFAULTS_H */ diff --git a/lib/filter.c b/lib/filter.c index 3226fb2f5e..da02a77763 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -2294,6 +2294,7 @@ DEFUN (ipv6_access_list_exact, if (argv_find(argv, argc, "exact-match", &idx)) exact = 1; + assert(prefix); return filter_set_zebra(vty, argv[idx_word]->arg, seq, permit_deny, AFI_IP6, prefix, exact, 1); } @@ -2812,9 +2813,13 @@ static int config_write_access(struct vty *vty, afi_t afi) return write; } +static int config_write_access_mac(struct vty *vty); static struct cmd_node access_mac_node = { - ACCESS_MAC_NODE, "", /* Access list has no interface. */ - 1}; + .name = "MAC access list", + .node = ACCESS_MAC_NODE, + .prompt = "", + .config_write = config_write_access_mac, +}; static int config_write_access_mac(struct vty *vty) { @@ -2850,7 +2855,7 @@ static void access_list_reset_mac(void) /* Install vty related command. */ static void access_list_init_mac(void) { - install_node(&access_mac_node, config_write_access_mac); + install_node(&access_mac_node); install_element(ENABLE_NODE, &show_mac_access_list_cmd); install_element(ENABLE_NODE, &show_mac_access_list_name_cmd); @@ -2863,9 +2868,13 @@ static void access_list_init_mac(void) } /* Access-list node. */ -static struct cmd_node access_node = {ACCESS_NODE, - "", /* Access list has no interface. */ - 1}; +static int config_write_access_ipv4(struct vty *vty); +static struct cmd_node access_node = { + .name = "ipv4 access list", + .node = ACCESS_NODE, + .prompt = "", + .config_write = config_write_access_ipv4, +}; static int config_write_access_ipv4(struct vty *vty) { @@ -2901,7 +2910,7 @@ static void access_list_reset_ipv4(void) /* Install vty related command. */ static void access_list_init_ipv4(void) { - install_node(&access_node, config_write_access_ipv4); + install_node(&access_node); install_element(ENABLE_NODE, &show_ip_access_list_cmd); install_element(ENABLE_NODE, &show_ip_access_list_name_cmd); @@ -2948,7 +2957,13 @@ static void access_list_init_ipv4(void) install_element(CONFIG_NODE, &no_access_list_remark_comment_cmd); } -static struct cmd_node access_ipv6_node = {ACCESS_IPV6_NODE, "", 1}; +static int config_write_access_ipv6(struct vty *vty); +static struct cmd_node access_ipv6_node = { + .name = "ipv6 access list", + .node = ACCESS_IPV6_NODE, + .prompt = "", + .config_write = config_write_access_ipv6, +}; static int config_write_access_ipv6(struct vty *vty) { @@ -2983,7 +2998,7 @@ static void access_list_reset_ipv6(void) static void access_list_init_ipv6(void) { - install_node(&access_ipv6_node, config_write_access_ipv6); + install_node(&access_ipv6_node); install_element(ENABLE_NODE, &show_ipv6_access_list_cmd); install_element(ENABLE_NODE, &show_ipv6_access_list_name_cmd); diff --git a/lib/frr_pthread.c b/lib/frr_pthread.c index 55f0b55ed6..e237934f81 100644 --- a/lib/frr_pthread.c +++ b/lib/frr_pthread.c @@ -27,6 +27,7 @@ #include "frr_pthread.h" #include "memory.h" #include "linklist.h" +#include "zlog.h" DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread") DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives") @@ -273,6 +274,8 @@ static void *fpt_run(void *arg) struct frr_pthread *fpt = arg; fpt->master->owner = pthread_self(); + zlog_tls_buffer_init(); + int sleeper[2]; pipe(sleeper); thread_add_read(fpt->master, &fpt_dummy, NULL, sleeper[0], NULL); @@ -294,5 +297,7 @@ static void *fpt_run(void *arg) close(sleeper[1]); close(sleeper[0]); + zlog_tls_buffer_fini(); + return NULL; } diff --git a/lib/frratomic.h b/lib/frratomic.h index 1e28253f2b..bafc6445e5 100644 --- a/lib/frratomic.h +++ b/lib/frratomic.h @@ -41,6 +41,7 @@ using std::memory_order_seq_cst; typedef std::atomic<bool> atomic_bool; typedef std::atomic<size_t> atomic_size_t; typedef std::atomic<uint_fast32_t> atomic_uint_fast32_t; +typedef std::atomic<uintptr_t> atomic_uintptr_t; #elif defined(HAVE_STDATOMIC_H) #include <stdatomic.h> @@ -230,6 +231,7 @@ typedef std::atomic<uint_fast32_t> atomic_uint_fast32_t; typedef _Atomic bool atomic_bool; typedef _Atomic size_t atomic_size_t; typedef _Atomic uint_fast32_t atomic_uint_fast32_t; +typedef _Atomic uintptr_t atomic_uintptr_t; #endif #endif /* _FRRATOMIC_H */ diff --git a/lib/frrcu.h b/lib/frrcu.h index 06d87c39f1..47751ae7df 100644 --- a/lib/frrcu.h +++ b/lib/frrcu.h @@ -19,7 +19,10 @@ #include "memory.h" #include "atomlist.h" -#include "seqlock.h" + +#ifdef __cplusplus +extern "C" { +#endif /* quick RCU primer: * There's a global sequence counter. Whenever a thread does a @@ -171,4 +174,8 @@ extern void rcu_enqueue(struct rcu_head *head, const struct rcu_action *action); extern void rcu_close(struct rcu_head_close *head, int fd); +#ifdef __cplusplus +} +#endif + #endif /* _FRRCU_H */ diff --git a/lib/grammar_sandbox.c b/lib/grammar_sandbox.c index 8ccdbfcbc1..a40b815caa 100644 --- a/lib/grammar_sandbox.c +++ b/lib/grammar_sandbox.c @@ -399,7 +399,7 @@ DEFUN (grammar_findambig, if (!nodegraph) continue; vty_out(vty, "scanning node %d (%s)\n", scannode - 1, - node_names[scannode - 1]); + cnode->name); } commands = cmd_graph_permutations(nodegraph); diff --git a/lib/grammar_sandbox_main.c b/lib/grammar_sandbox_main.c index aa54720dab..fbb97d2dd5 100644 --- a/lib/grammar_sandbox_main.c +++ b/lib/grammar_sandbox_main.c @@ -45,11 +45,7 @@ int main(int argc, char **argv) master = thread_master_create(NULL); - openzlog("grammar_sandbox", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_DAEMON); - zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED); - zlog_set_level(ZLOG_DEST_STDOUT, LOG_DEBUG); - zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); + zlog_aux_init("NONE: ", LOG_DEBUG); /* Library inits. */ cmd_init(1); diff --git a/lib/hook.c b/lib/hook.c index 870d158aac..5a8ad00d66 100644 --- a/lib/hook.c +++ b/lib/hook.c @@ -18,16 +18,26 @@ #include "config.h" #endif +#include <string.h> + #include "memory.h" #include "hook.h" DEFINE_MTYPE_STATIC(LIB, HOOK_ENTRY, "Hook entry") -void _hook_register(struct hook *hook, void *funcptr, void *arg, bool has_arg, - struct frrmod_runtime *module, const char *funcname, - int priority) +void _hook_register(struct hook *hook, struct hookent *stackent, void *funcptr, + void *arg, bool has_arg, struct frrmod_runtime *module, + const char *funcname, int priority) { - struct hookent *he = XCALLOC(MTYPE_HOOK_ENTRY, sizeof(*he)), **pos; + struct hookent *he, **pos; + + if (!stackent->ent_used) + he = stackent; + else { + he = XCALLOC(MTYPE_HOOK_ENTRY, sizeof(*he)); + he->ent_on_heap = true; + } + he->ent_used = true; he->hookfn = funcptr; he->hookarg = arg; he->has_arg = has_arg; @@ -52,7 +62,10 @@ void _hook_unregister(struct hook *hook, void *funcptr, void *arg, bool has_arg) if (he->hookfn == funcptr && he->hookarg == arg && he->has_arg == has_arg) { *prev = he->next; - XFREE(MTYPE_HOOK_ENTRY, he); + if (he->ent_on_heap) + XFREE(MTYPE_HOOK_ENTRY, he); + else + memset(he, 0, sizeof(*he)); break; } } diff --git a/lib/hook.h b/lib/hook.h index f7fb7b8a5c..3823cebe6a 100644 --- a/lib/hook.h +++ b/lib/hook.h @@ -114,7 +114,9 @@ struct hookent { struct hookent *next; void *hookfn; /* actually a function pointer */ void *hookarg; - bool has_arg; + bool has_arg : 1; + bool ent_on_heap : 1; + bool ent_used : 1; int priority; struct frrmod_runtime *module; const char *fnname; @@ -133,21 +135,33 @@ struct hook { * always use hook_register(), which uses the static inline helper from * DECLARE_HOOK in order to get type safety */ -extern void _hook_register(struct hook *hook, void *funcptr, void *arg, - bool has_arg, struct frrmod_runtime *module, +extern void _hook_register(struct hook *hook, struct hookent *stackent, + void *funcptr, void *arg, bool has_arg, + struct frrmod_runtime *module, const char *funcname, int priority); + +/* most hook_register calls are not in a loop or similar and can use a + * statically allocated "struct hookent" from the data segment + */ +#define _hook_reg_svar(hook, funcptr, arg, has_arg, module, funcname, prio) \ + do { \ + static struct hookent stack_hookent = { .ent_on_heap = 0, }; \ + _hook_register(hook, &stack_hookent, funcptr, arg, has_arg, \ + module, funcname, prio); \ + } while (0) + #define hook_register(hookname, func) \ - _hook_register(&_hook_##hookname, _hook_typecheck_##hookname(func), \ + _hook_reg_svar(&_hook_##hookname, _hook_typecheck_##hookname(func), \ NULL, false, THIS_MODULE, #func, HOOK_DEFAULT_PRIORITY) #define hook_register_arg(hookname, func, arg) \ - _hook_register(&_hook_##hookname, \ + _hook_reg_svar(&_hook_##hookname, \ _hook_typecheck_arg_##hookname(func), arg, true, \ THIS_MODULE, #func, HOOK_DEFAULT_PRIORITY) #define hook_register_prio(hookname, prio, func) \ - _hook_register(&_hook_##hookname, _hook_typecheck_##hookname(func), \ + _hook_reg_svar(&_hook_##hookname, _hook_typecheck_##hookname(func), \ NULL, false, THIS_MODULE, #func, prio) #define hook_register_arg_prio(hookname, prio, func, arg) \ - _hook_register(&_hook_##hookname, \ + _hook_reg_svar(&_hook_##hookname, \ _hook_typecheck_arg_##hookname(func), arg, true, \ THIS_MODULE, #func, prio) diff --git a/lib/iana_afi.h b/lib/iana_afi.h index ac03f73193..56e8a24b86 100644 --- a/lib/iana_afi.h +++ b/lib/iana_afi.h @@ -21,6 +21,10 @@ #include <prefix.h> +#ifdef __cplusplus +extern "C" { +#endif + /* * The above AFI and SAFI definitions are for internal use. The protocol * definitions (IANA values) as for example used in BGP protocol packets @@ -130,4 +134,8 @@ static inline const char *iana_safi2str(iana_safi_t safi) return safi2str(safi_iana2int(safi)); } +#ifdef __cplusplus +} +#endif + #endif @@ -949,8 +949,9 @@ connected_log(struct connected *connected, char *str) p = connected->address; vrf = vrf_lookup_by_id(ifp->vrf_id); - snprintf(logbuf, BUFSIZ, "%s interface %s vrf %s(%u) %s %s/%d ", str, - ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, prefix_family_str(p), + snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %s/%d ", + str, ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, + prefix_family_str(p), inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); p = connected->destination; @@ -973,8 +974,8 @@ nbr_connected_log(struct nbr_connected *connected, char *str) ifp = connected->ifp; p = connected->address; - snprintf(logbuf, BUFSIZ, "%s interface %s %s %s/%d ", str, ifp->name, - prefix_family_str(p), + snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %s/%d ", str, + ifp->name, prefix_family_str(p), inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); zlog_info("%s", logbuf); @@ -1489,19 +1490,17 @@ void if_zapi_callbacks(int (*create)(struct interface *ifp), /* * XPath: /frr-interface:lib/interface */ -static int lib_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_create(struct nb_cb_create_args *args) { const char *ifname; const char *vrfname; struct vrf *vrf; struct interface *ifp; - ifname = yang_dnode_get_string(dnode, "./name"); - vrfname = yang_dnode_get_string(dnode, "./vrf"); + ifname = yang_dnode_get_string(args->dnode, "./name"); + vrfname = yang_dnode_get_string(args->dnode, "./vrf"); - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: vrf = vrf_lookup_by_name(vrfname); if (!vrf) { @@ -1542,22 +1541,21 @@ static int lib_interface_create(enum nb_event event, #endif /* SUNOS_5 */ ifp->configured = true; - nb_running_set_entry(dnode, ifp); + nb_running_set_entry(args->dnode, ifp); break; } return NB_OK; } -static int lib_interface_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_interface_destroy(struct nb_cb_destroy_args *args) { struct interface *ifp; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { zlog_warn("%s: only inactive interfaces can be deleted", __func__); @@ -1568,7 +1566,7 @@ static int lib_interface_destroy(enum nb_event event, case NB_EV_ABORT: break; case NB_EV_APPLY: - ifp = nb_running_unset_entry(dnode); + ifp = nb_running_unset_entry(args->dnode); ifp->configured = false; if_delete(&ifp); @@ -1581,13 +1579,12 @@ static int lib_interface_destroy(enum nb_event event, /* * XPath: /frr-interface:lib/interface */ -static const void *lib_interface_get_next(const void *parent_list_entry, - const void *list_entry) +static const void *lib_interface_get_next(struct nb_cb_get_next_args *args) { struct vrf *vrf; - struct interface *pif = (struct interface *)list_entry; + struct interface *pif = (struct interface *)args->list_entry; - if (list_entry == NULL) { + if (args->list_entry == NULL) { vrf = RB_MIN(vrf_name_head, &vrfs_by_name); assert(vrf); pif = RB_MIN(if_name_head, &vrf->ifaces_by_name); @@ -1606,27 +1603,26 @@ static const void *lib_interface_get_next(const void *parent_list_entry, return pif; } -static int lib_interface_get_keys(const void *list_entry, - struct yang_list_keys *keys) +static int lib_interface_get_keys(struct nb_cb_get_keys_args *args) { - const struct interface *ifp = list_entry; + const struct interface *ifp = args->list_entry; struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); assert(vrf); - keys->num = 2; - strlcpy(keys->key[0], ifp->name, sizeof(keys->key[0])); - strlcpy(keys->key[1], vrf->name, sizeof(keys->key[1])); + args->keys->num = 2; + strlcpy(args->keys->key[0], ifp->name, sizeof(args->keys->key[0])); + strlcpy(args->keys->key[1], vrf->name, sizeof(args->keys->key[1])); return NB_OK; } -static const void *lib_interface_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +static const void * +lib_interface_lookup_entry(struct nb_cb_lookup_entry_args *args) { - const char *ifname = keys->key[0]; - const char *vrfname = keys->key[1]; + const char *ifname = args->keys->key[0]; + const char *vrfname = args->keys->key[1]; struct vrf *vrf = vrf_lookup_by_name(vrfname); return vrf ? if_lookup_by_name(ifname, vrf->vrf_id) : NULL; @@ -1635,40 +1631,125 @@ static const void *lib_interface_lookup_entry(const void *parent_list_entry, /* * XPath: /frr-interface:lib/interface/description */ -static int lib_interface_description_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_description_modify(struct nb_cb_modify_args *args) { struct interface *ifp; const char *description; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); XFREE(MTYPE_TMP, ifp->desc); - description = yang_dnode_get_string(dnode, NULL); + description = yang_dnode_get_string(args->dnode, NULL); ifp->desc = XSTRDUP(MTYPE_TMP, description); return NB_OK; } -static int lib_interface_description_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_interface_description_destroy(struct nb_cb_destroy_args *args) { struct interface *ifp; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); XFREE(MTYPE_TMP, ifp->desc); return NB_OK; } -/* clang-format off */ +/* + * XPath: /frr-interface:lib/interface/state/if-index + */ +static struct yang_data * +lib_interface_state_if_index_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + + return yang_data_new_int32(args->xpath, ifp->ifindex); +} + +/* + * XPath: /frr-interface:lib/interface/state/mtu + */ +static struct yang_data * +lib_interface_state_mtu_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + + return yang_data_new_uint16(args->xpath, ifp->mtu); +} + +/* + * XPath: /frr-interface:lib/interface/state/mtu6 + */ +static struct yang_data * +lib_interface_state_mtu6_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + + return yang_data_new_uint32(args->xpath, ifp->mtu6); +} + +/* + * XPath: /frr-interface:lib/interface/state/speed + */ +static struct yang_data * +lib_interface_state_speed_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + + return yang_data_new_uint32(args->xpath, ifp->speed); +} + +/* + * XPath: /frr-interface:lib/interface/state/metric + */ +static struct yang_data * +lib_interface_state_metric_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + + return yang_data_new_uint32(args->xpath, ifp->metric); +} + +/* + * XPath: /frr-interface:lib/interface/state/flags + */ +static struct yang_data * +lib_interface_state_flags_get_elem(struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-interface:lib/interface/state/type + */ +static struct yang_data * +lib_interface_state_type_get_elem(struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-interface:lib/interface/state/phy-address + */ +static struct yang_data * +lib_interface_state_phy_address_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + struct ethaddr macaddr; + memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); + + return yang_data_new_mac(args->xpath, &macaddr); +} + +/* clang-format off */ const struct frr_yang_module_info frr_interface_info = { .name = "frr-interface", .nodes = { @@ -1692,6 +1773,54 @@ const struct frr_yang_module_info frr_interface_info = { }, }, { + .xpath = "/frr-interface:lib/interface/state/if-index", + .cbs = { + .get_elem = lib_interface_state_if_index_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/mtu", + .cbs = { + .get_elem = lib_interface_state_mtu_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/mtu6", + .cbs = { + .get_elem = lib_interface_state_mtu6_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/speed", + .cbs = { + .get_elem = lib_interface_state_speed_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/metric", + .cbs = { + .get_elem = lib_interface_state_metric_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/flags", + .cbs = { + .get_elem = lib_interface_state_flags_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/type", + .cbs = { + .get_elem = lib_interface_state_type_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/phy-address", + .cbs = { + .get_elem = lib_interface_state_phy_address_get_elem, + } + }, + { .xpath = NULL, }, } diff --git a/lib/keychain.c b/lib/keychain.c index ea512a2699..251211734b 100644 --- a/lib/keychain.c +++ b/lib/keychain.c @@ -959,11 +959,21 @@ DEFUN (no_send_lifetime, return CMD_SUCCESS; } -static struct cmd_node keychain_node = {KEYCHAIN_NODE, "%s(config-keychain)# ", - 1}; - -static struct cmd_node keychain_key_node = {KEYCHAIN_KEY_NODE, - "%s(config-keychain-key)# ", 1}; +static int keychain_config_write(struct vty *vty); +static struct cmd_node keychain_node = { + .name = "keychain", + .node = KEYCHAIN_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-keychain)# ", + .config_write = keychain_config_write, +}; + +static struct cmd_node keychain_key_node = { + .name = "keychain key", + .node = KEYCHAIN_KEY_NODE, + .parent_node = KEYCHAIN_NODE, + .prompt = "%s(config-keychain-key)# ", +}; static int keychain_strftime(char *buf, int bufsiz, time_t *time) { @@ -1042,8 +1052,8 @@ void keychain_init(void) { keychain_list = list_new(); - install_node(&keychain_node, keychain_config_write); - install_node(&keychain_key_node, NULL); + install_node(&keychain_node); + install_node(&keychain_key_node); install_default(KEYCHAIN_NODE); install_default(KEYCHAIN_KEY_NODE); diff --git a/lib/libfrr.c b/lib/libfrr.c index 9a681103d4..ac165f254e 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -33,7 +33,6 @@ #include "lib_vty.h" #include "log_vty.h" #include "zclient.h" -#include "log_int.h" #include "module.h" #include "network.h" #include "lib_errors.h" @@ -630,6 +629,7 @@ struct thread_master *frr_init(void) { struct option_chain *oc; struct frrmod_runtime *module; + struct zprivs_ids_t ids; char moderr[256]; char p_instance[16] = "", p_pathspace[256] = ""; const char *dir; @@ -657,9 +657,11 @@ struct thread_master *frr_init(void) #endif zprivs_preinit(di->privs); + zprivs_get_ids(&ids); - openzlog(di->progname, di->logname, di->instance, - LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); + zlog_init(di->progname, di->logname, di->instance, + ids.uid_normal, ids.gid_normal); + zlog_tls_buffer_init(); command_setup_early_logging(di->early_logging, di->early_loglevel); @@ -709,7 +711,6 @@ struct thread_master *frr_init(void) vty_init(master, di->log_always); lib_cmd_init(); - log_filter_cmd_init(); frr_pthread_init(); @@ -1086,7 +1087,7 @@ void frr_run(struct thread_master *master) } /* end fixed stderr startup logging */ - zlog_startup_stderr = false; + zlog_startup_end(); struct thread thread; while (thread_fetch(master, &thread)) @@ -1119,7 +1120,8 @@ void frr_fini(void) /* signal_init -> nothing needed */ thread_master_free(master); master = NULL; - closezlog(); + zlog_tls_buffer_fini(); + zlog_fini(); /* frrmod_init -> nothing needed / hooks */ rcu_shutdown(); @@ -25,7 +25,6 @@ #include "zclient.h" #include "log.h" -#include "log_int.h" #include "memory.h" #include "command.h" #include "lib_errors.h" @@ -33,154 +32,12 @@ #include "printfrr.h" #include "frr_pthread.h" -#ifndef SUNOS_5 -#include <sys/un.h> -#endif -/* for printstack on solaris */ -#ifdef HAVE_UCONTEXT_H -#include <ucontext.h> -#endif - #ifdef HAVE_LIBUNWIND #define UNW_LOCAL_ONLY #include <libunwind.h> #include <dlfcn.h> #endif -DEFINE_MTYPE_STATIC(LIB, ZLOG, "Logging") - -/* hook for external logging */ -DEFINE_HOOK(zebra_ext_log, (int priority, const char *format, va_list args), - (priority, format, args)); - -static int logfile_fd = -1; /* Used in signal handler. */ - -struct zlog *zlog_default = NULL; -bool zlog_startup_stderr = true; - -/* lock protecting zlog_default for mt-safe zlog */ -static pthread_mutex_t loglock = PTHREAD_MUTEX_INITIALIZER; - -const char *zlog_priority[] = { - "emergencies", "alerts", "critical", "errors", "warnings", - "notifications", "informational", "debugging", NULL, -}; - -static char zlog_filters[ZLOG_FILTERS_MAX][ZLOG_FILTER_LENGTH_MAX + 1]; -static uint8_t zlog_filter_count; - -/* - * look for a match on the filter in the current filters, loglock must be held - */ -static int zlog_filter_lookup(const char *lookup) -{ - for (int i = 0; i < zlog_filter_count; i++) { - if (strncmp(lookup, zlog_filters[i], sizeof(zlog_filters[0])) - == 0) - return i; - } - return -1; -} - -void zlog_filter_clear(void) -{ - frr_with_mutex(&loglock) { - zlog_filter_count = 0; - } -} - -int zlog_filter_add(const char *filter) -{ - frr_with_mutex(&loglock) { - if (zlog_filter_count >= ZLOG_FILTERS_MAX) - return 1; - - if (zlog_filter_lookup(filter) != -1) - /* Filter already present */ - return -1; - - strlcpy(zlog_filters[zlog_filter_count], filter, - sizeof(zlog_filters[0])); - - if (zlog_filters[zlog_filter_count][0] == '\0') - /* Filter was either empty or didn't get copied - * correctly - */ - return -1; - - zlog_filter_count++; - } - return 0; -} - -int zlog_filter_del(const char *filter) -{ - frr_with_mutex(&loglock) { - int found_idx = zlog_filter_lookup(filter); - int last_idx = zlog_filter_count - 1; - - if (found_idx == -1) - /* Didn't find the filter to delete */ - return -1; - - /* Adjust the filter array */ - memmove(zlog_filters[found_idx], zlog_filters[found_idx + 1], - (last_idx - found_idx) * sizeof(zlog_filters[0])); - - zlog_filter_count--; - } - return 0; -} - -/* Dump all filters to buffer, delimited by new line */ -int zlog_filter_dump(char *buf, size_t max_size) -{ - int len = 0; - - frr_with_mutex(&loglock) { - for (int i = 0; i < zlog_filter_count; i++) { - int ret; - ret = snprintf(buf + len, max_size - len, " %s\n", - zlog_filters[i]); - len += ret; - if ((ret < 0) || ((size_t)len >= max_size)) - return -1; - } - } - - return len; -} - -/* - * write_wrapper - * - * glibc has declared that the return value from write *must* not be - * ignored. - * gcc see's this problem and issues a warning for the line. - * - * Why is this a big deal you say? Because both of them are right - * and if you have -Werror enabled then all calls to write - * generate a build error and the build stops. - * - * clang has helpfully allowed this construct: - * (void)write(...) - * to tell the compiler yeah I know it has a return value - * I don't care about it at this time. - * gcc doesn't have this ability. - * - * This code was written such that it didn't care about the - * return value from write. At this time do I want - * to go through and fix and test this code for correctness. - * So just wrapper the bad behavior and move on. - */ -static void write_wrapper(int fd, const void *buf, size_t count) -{ - if (write(fd, buf, count) <= 0) - return; - - return; -} - /** * Looks up a message in a message list by key. * @@ -264,274 +121,12 @@ size_t quagga_timestamp(int timestamp_precision, char *buf, size_t buflen) return 0; } -static inline void timestamp_control_render(struct timestamp_control *ctl) -{ - if (!ctl->already_rendered) { - ctl->len = quagga_timestamp(ctl->precision, ctl->buf, - sizeof(ctl->buf)); - ctl->already_rendered = 1; - } -} - -/* Utility routine for current time printing. */ -static void time_print(FILE *fp, struct timestamp_control *ctl) -{ - timestamp_control_render(ctl); - fprintf(fp, "%s ", ctl->buf); -} - -static int time_print_buf(char *buf, int len, int max_size, - struct timestamp_control *ctl) -{ - timestamp_control_render(ctl); - - if (ctl->len + 1 >= (unsigned long)max_size) - return -1; - - return snprintf(buf + len, max_size - len, "%s ", ctl->buf); -} - -static void vzlog_file(struct zlog *zl, struct timestamp_control *tsctl, - const char *proto_str, int record_priority, int priority, - FILE *fp, const char *msg) -{ - time_print(fp, tsctl); - if (record_priority) - fprintf(fp, "%s: ", zlog_priority[priority]); - - fprintf(fp, "%s%s\n", proto_str, msg); - fflush(fp); -} - -/* Search a buf for the filter strings, loglock must be held */ -static int search_buf(const char *buf) -{ - char *found = NULL; - - for (int i = 0; i < zlog_filter_count; i++) { - found = strstr(buf, zlog_filters[i]); - if (found != NULL) - return 0; - } - - return -1; -} - -/* Filter out a log */ -static int vzlog_filter(struct zlog *zl, struct timestamp_control *tsctl, - const char *proto_str, int priority, const char *msg) -{ - int len = 0; - int ret = 0; - char buf[1024] = ""; - - ret = time_print_buf(buf, len, sizeof(buf), tsctl); - - len += ret; - if ((ret < 0) || ((size_t)len >= sizeof(buf))) - goto search; - - if (zl && zl->record_priority) - snprintf(buf + len, sizeof(buf) - len, "%s: %s: %s", - zlog_priority[priority], proto_str, msg); - else - snprintf(buf + len, sizeof(buf) - len, "%s: %s", proto_str, - msg); - -search: - return search_buf(buf); -} - -/* va_list version of zlog. */ -void vzlog(int priority, const char *format, va_list args) -{ - frr_mutex_lock_autounlock(&loglock); - - char proto_str[32] = ""; - int original_errno = errno; - struct timestamp_control tsctl = {}; - tsctl.already_rendered = 0; - struct zlog *zl = zlog_default; - char buf[256], *msg; - - if (zl == NULL) { - tsctl.precision = 0; - } else { - tsctl.precision = zl->timestamp_precision; - if (zl->instance) - sprintf(proto_str, "%s[%d]: ", zl->protoname, - zl->instance); - else - sprintf(proto_str, "%s: ", zl->protoname); - } - - msg = vasnprintfrr(MTYPE_TMP, buf, sizeof(buf), format, args); - - /* If it doesn't match on a filter, do nothing with the debug log */ - if ((priority == LOG_DEBUG) && zlog_filter_count - && vzlog_filter(zl, &tsctl, proto_str, priority, msg)) - goto out; - - /* call external hook */ - hook_call(zebra_ext_log, priority, format, args); - - /* When zlog_default is also NULL, use stderr for logging. */ - if (zl == NULL) { - time_print(stderr, &tsctl); - fprintf(stderr, "%s: %s\n", "unknown", msg); - fflush(stderr); - goto out; - } - - /* Syslog output */ - if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) - syslog(priority | zlog_default->facility, "%s", msg); - - /* File output. */ - if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) - vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority, - zl->fp, msg); - - /* fixed-config logging to stderr while we're stating up & haven't - * daemonized / reached mainloop yet - * - * note the "else" on stdout output -- we don't want to print the same - * message to both stderr and stdout. */ - if (zlog_startup_stderr && priority <= LOG_WARNING) - vzlog_file(zl, &tsctl, proto_str, 1, priority, stderr, msg); - else if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) - vzlog_file(zl, &tsctl, proto_str, zl->record_priority, priority, - stdout, msg); - - /* Terminal monitor. */ - if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) - vty_log((zl->record_priority ? zlog_priority[priority] : NULL), - proto_str, msg, &tsctl); - -out: - if (msg != buf) - XFREE(MTYPE_TMP, msg); - errno = original_errno; -} - -int vzlog_test(int priority) -{ - frr_mutex_lock_autounlock(&loglock); - - struct zlog *zl = zlog_default; - - /* When zlog_default is also NULL, use stderr for logging. */ - if (zl == NULL) - return 1; - /* Syslog output */ - else if (priority <= zl->maxlvl[ZLOG_DEST_SYSLOG]) - return 1; - /* File output. */ - else if ((priority <= zl->maxlvl[ZLOG_DEST_FILE]) && zl->fp) - return 1; - /* stdout output. */ - else if (priority <= zl->maxlvl[ZLOG_DEST_STDOUT]) - return 1; - /* Terminal monitor. */ - else if (priority <= zl->maxlvl[ZLOG_DEST_MONITOR]) - return 1; - - return 0; -} - /* * crash handling * * NB: only AS-Safe (async-signal) functions can be used here! */ -/* Needs to be enhanced to support Solaris. */ -static int syslog_connect(void) -{ -#ifdef SUNOS_5 - return -1; -#else - int fd; - struct sockaddr_un addr; - - if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) - return -1; - addr.sun_family = AF_UNIX; -#ifdef _PATH_LOG -#define SYSLOG_SOCKET_PATH _PATH_LOG -#else -#define SYSLOG_SOCKET_PATH "/dev/log" -#endif - strlcpy(addr.sun_path, SYSLOG_SOCKET_PATH, sizeof(addr.sun_path)); -#undef SYSLOG_SOCKET_PATH - if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - close(fd); - return -1; - } - return fd; -#endif -} - -static void syslog_sigsafe(int priority, const char *msg, size_t msglen) -{ - static int syslog_fd = -1; - char buf[sizeof("<1234567890>ripngd[1234567890]: ") + msglen + 50]; - struct fbuf fb = { .buf = buf, .pos = buf, .len = sizeof(buf) }; - - if ((syslog_fd < 0) && ((syslog_fd = syslog_connect()) < 0)) - return; - - /* forget about the timestamp, too difficult in a signal handler */ - bprintfrr(&fb, "<%d>%s", priority, zlog_default->ident); - if (zlog_default->syslog_options & LOG_PID) - bprintfrr(&fb, "[%ld]", (long)getpid()); - bprintfrr(&fb, ": %s", msg); - write_wrapper(syslog_fd, fb.buf, fb.pos - fb.buf); -} - -static int open_crashlog(void) -{ - char crashlog_buf[PATH_MAX]; - const char *crashlog_default = "/var/tmp/frr.crashlog", *crashlog; - - if (!zlog_default || !zlog_default->ident) - crashlog = crashlog_default; - else { - snprintfrr(crashlog_buf, sizeof(crashlog_buf), - "/var/tmp/frr.%s.crashlog", zlog_default->ident); - crashlog = crashlog_buf; - } - return open(crashlog, O_WRONLY | O_CREAT | O_EXCL, LOGFILE_MASK); -} - -/* N.B. implicit priority is most severe */ -#define PRI LOG_CRIT - -static void crash_write(struct fbuf *fb, char *msgstart) -{ - if (fb->pos == fb->buf) - return; - if (!msgstart) - msgstart = fb->buf; - - /* If no file logging configured, try to write to fallback log file. */ - if ((logfile_fd >= 0) || ((logfile_fd = open_crashlog()) >= 0)) - write(logfile_fd, fb->buf, fb->pos - fb->buf); - if (!zlog_default) - write(STDERR_FILENO, fb->buf, fb->pos - fb->buf); - else { - if (PRI <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) - write(STDOUT_FILENO, fb->buf, fb->pos - fb->buf); - /* Remove trailing '\n' for monitor and syslog */ - fb->pos--; - if (PRI <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) - vty_log_fixed(fb->buf, fb->pos - fb->buf); - if (PRI <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG]) - syslog_sigsafe(PRI | zlog_default->facility, msgstart, - fb->pos - msgstart); - } -} - /* Note: the goal here is to use only async-signal-safe functions. */ void zlog_signal(int signo, const char *action, void *siginfo_v, void *program_counter) @@ -540,14 +135,9 @@ void zlog_signal(int signo, const char *action, void *siginfo_v, time_t now; char buf[sizeof("DEFAULT: Received signal S at T (si_addr 0xP, PC 0xP); aborting...") + 100]; - char *msgstart; struct fbuf fb = { .buf = buf, .pos = buf, .len = sizeof(buf) }; time(&now); - if (zlog_default) - bprintfrr(&fb, "%s: ", zlog_default->protoname); - - msgstart = fb.pos; bprintfrr(&fb, "Received signal %d at %lld", signo, (long long)now); if (program_counter) @@ -559,9 +149,9 @@ void zlog_signal(int signo, const char *action, void *siginfo_v, (ptrdiff_t)siginfo->si_addr); bprintfrr(&fb, "; %s\n", action); - crash_write(&fb, msgstart); + zlog_sigsafe(fb.buf, fb.pos - fb.buf); - zlog_backtrace_sigsafe(PRI, program_counter); + zlog_backtrace_sigsafe(LOG_CRIT, program_counter); fb.pos = buf; @@ -574,7 +164,7 @@ void zlog_signal(int signo, const char *action, void *siginfo_v, bprintfrr(&fb, "in thread %s scheduled from %s:%d\n", tc->funcname, tc->schedfrom, tc->schedfrom_line); - crash_write(&fb, NULL); + zlog_sigsafe(fb.buf, fb.pos - fb.buf); } /* Log a backtrace using only async-signal-safe functions. @@ -609,85 +199,35 @@ void zlog_backtrace_sigsafe(int priority, void *program_counter) bprintfrr(&fb, " %s (mapped at %p)", dlinfo.dli_fname, dlinfo.dli_fbase); bprintfrr(&fb, "\n"); - crash_write(&fb, NULL); + zlog_sigsafe(fb.buf, fb.pos - fb.buf); } -#elif defined(HAVE_GLIBC_BACKTRACE) || defined(HAVE_PRINTSTACK) - static const char pclabel[] = "Program counter: "; +#elif defined(HAVE_GLIBC_BACKTRACE) void *array[64]; - int size; + int size, i; char buf[128]; struct fbuf fb = { .buf = buf, .pos = buf, .len = sizeof(buf) }; char **bt = NULL; -#ifdef HAVE_GLIBC_BACKTRACE size = backtrace(array, array_size(array)); if (size <= 0 || (size_t)size > array_size(array)) return; -#define DUMP(FD) \ - { \ - if (program_counter) { \ - write_wrapper(FD, pclabel, sizeof(pclabel) - 1); \ - backtrace_symbols_fd(&program_counter, 1, FD); \ - } \ - write_wrapper(FD, fb.buf, fb.pos - fb.buf); \ - backtrace_symbols_fd(array, size, FD); \ - } -#elif defined(HAVE_PRINTSTACK) - size = 0; - -#define DUMP(FD) \ - { \ - if (program_counter) \ - write_wrapper((FD), pclabel, sizeof(pclabel) - 1); \ - write_wrapper((FD), fb.buf, fb.pos - fb.buf); \ - printstack((FD)); \ - } -#endif /* HAVE_GLIBC_BACKTRACE, HAVE_PRINTSTACK */ + bprintfrr(&fb, "Backtrace for %d stack frames:", size); + zlog_sigsafe(fb.pos, fb.buf - fb.pos); - bprintfrr(&fb, "Backtrace for %d stack frames:\n", size); + bt = backtrace_symbols(array, size); - if ((logfile_fd >= 0) || ((logfile_fd = open_crashlog()) >= 0)) - DUMP(logfile_fd) - if (!zlog_default) - DUMP(STDERR_FILENO) - else { - if (priority <= zlog_default->maxlvl[ZLOG_DEST_STDOUT]) - DUMP(STDOUT_FILENO) - /* Remove trailing '\n' for monitor and syslog */ - fb.pos--; - if (priority <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) - vty_log_fixed(fb.buf, fb.pos - fb.buf); - if (priority <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG]) - syslog_sigsafe(priority | zlog_default->facility, - fb.buf, fb.pos - fb.buf); - { - int i; -#ifdef HAVE_GLIBC_BACKTRACE - bt = backtrace_symbols(array, size); -#endif - /* Just print the function addresses. */ - for (i = 0; i < size; i++) { - fb.pos = buf; - if (bt) - bprintfrr(&fb, "%s", bt[i]); - else - bprintfrr(&fb, "[bt %d] 0x%tx", i, - (ptrdiff_t)(array[i])); - if (priority - <= zlog_default->maxlvl[ZLOG_DEST_MONITOR]) - vty_log_fixed(fb.buf, fb.pos - fb.buf); - if (priority - <= zlog_default->maxlvl[ZLOG_DEST_SYSLOG]) - syslog_sigsafe(priority - | zlog_default->facility, - fb.buf, fb.pos - fb.buf); - } - if (bt) - free(bt); - } + for (i = 0; i < size; i++) { + fb.pos = buf; + if (bt) + bprintfrr(&fb, "%s", bt[i]); + else + bprintfrr(&fb, "[bt %d] 0x%tx", i, + (ptrdiff_t)(array[i])); + zlog_sigsafe(fb.buf, fb.pos - fb.buf); } -#undef DUMP + if (bt) + free(bt); #endif /* HAVE_STRACK_TRACE */ } @@ -754,36 +294,6 @@ void zlog_backtrace(int priority) #endif } -void zlog(int priority, const char *format, ...) -{ - va_list args; - - va_start(args, format); - vzlog(priority, format, args); - va_end(args); -} - -#define ZLOG_FUNC(FUNCNAME, PRIORITY) \ - void FUNCNAME(const char *format, ...) \ - { \ - va_list args; \ - va_start(args, format); \ - vzlog(PRIORITY, format, args); \ - va_end(args); \ - } - -ZLOG_FUNC(zlog_err, LOG_ERR) - -ZLOG_FUNC(zlog_warn, LOG_WARNING) - -ZLOG_FUNC(zlog_info, LOG_INFO) - -ZLOG_FUNC(zlog_notice, LOG_NOTICE) - -ZLOG_FUNC(zlog_debug, LOG_DEBUG) - -#undef ZLOG_FUNC - void zlog_thread_info(int log_level) { struct thread *tc; @@ -801,11 +311,6 @@ void zlog_thread_info(int log_level) void _zlog_assert_failed(const char *assertion, const char *file, unsigned int line, const char *function) { - /* Force fallback file logging? */ - if (zlog_default && !zlog_default->fp - && ((logfile_fd = open_crashlog()) >= 0) - && ((zlog_default->fp = fdopen(logfile_fd, "w")) != NULL)) - zlog_default->maxlvl[ZLOG_DEST_FILE] = LOG_ERR; zlog(LOG_CRIT, "Assertion `%s' failed in file %s, line %u, function %s", assertion, file, line, (function ? function : "?")); zlog_backtrace(LOG_CRIT); @@ -816,174 +321,14 @@ void _zlog_assert_failed(const char *assertion, const char *file, void memory_oom(size_t size, const char *name) { - flog_err_sys(EC_LIB_SYSTEM_CALL, - "out of memory: failed to allocate %zu bytes for %s" - "object", - size, name); - zlog_backtrace(LOG_ERR); + zlog(LOG_CRIT, + "out of memory: failed to allocate %zu bytes for %s object", + size, name); + zlog_backtrace(LOG_CRIT); + log_memstats(stderr, "log"); abort(); } -/* Open log stream */ -void openzlog(const char *progname, const char *protoname, - unsigned short instance, int syslog_flags, int syslog_facility) -{ - struct zlog *zl; - unsigned int i; - - zl = XCALLOC(MTYPE_ZLOG, sizeof(struct zlog)); - - zl->ident = progname; - zl->protoname = protoname; - zl->instance = instance; - zl->facility = syslog_facility; - zl->syslog_options = syslog_flags; - - /* Set default logging levels. */ - for (i = 0; i < array_size(zl->maxlvl); i++) - zl->maxlvl[i] = ZLOG_DISABLED; - zl->maxlvl[ZLOG_DEST_MONITOR] = LOG_DEBUG; - zl->default_lvl = LOG_DEBUG; - - openlog(progname, syslog_flags, zl->facility); - - frr_with_mutex(&loglock) { - zlog_default = zl; - } - -#ifdef HAVE_GLIBC_BACKTRACE - /* work around backtrace() using lazily resolved dynamically linked - * symbols, which will otherwise cause funny breakage in the SEGV - * handler. - * (particularly, the dynamic linker can call malloc(), which uses locks - * in programs linked with -pthread, thus can deadlock.) */ - void *bt[4]; - backtrace(bt, array_size(bt)); - free(backtrace_symbols(bt, 0)); - backtrace_symbols_fd(bt, 0, 0); -#endif -} - -void closezlog(void) -{ - frr_mutex_lock_autounlock(&loglock); - - struct zlog *zl = zlog_default; - - closelog(); - - if (zl->fp != NULL) - fclose(zl->fp); - - XFREE(MTYPE_ZLOG, zl->filename); - - XFREE(MTYPE_ZLOG, zl); - zlog_default = NULL; -} - -/* Called from command.c. */ -void zlog_set_level(zlog_dest_t dest, int log_level) -{ - frr_with_mutex(&loglock) { - zlog_default->maxlvl[dest] = log_level; - } -} - -int zlog_set_file(const char *filename, int log_level) -{ - struct zlog *zl; - FILE *fp; - mode_t oldumask; - int ret = 1; - - /* There is opend file. */ - zlog_reset_file(); - - /* Open file. */ - oldumask = umask(0777 & ~LOGFILE_MASK); - fp = fopen(filename, "a"); - umask(oldumask); - if (fp == NULL) { - ret = 0; - } else { - frr_with_mutex(&loglock) { - zl = zlog_default; - - /* Set flags. */ - zl->filename = XSTRDUP(MTYPE_ZLOG, filename); - zl->maxlvl[ZLOG_DEST_FILE] = log_level; - zl->fp = fp; - logfile_fd = fileno(fp); - } - } - - return ret; -} - -/* Reset opend file. */ -int zlog_reset_file(void) -{ - frr_mutex_lock_autounlock(&loglock); - - struct zlog *zl = zlog_default; - - if (zl->fp) - fclose(zl->fp); - zl->fp = NULL; - logfile_fd = -1; - zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED; - - XFREE(MTYPE_ZLOG, zl->filename); - - return 1; -} - -/* Reopen log file. */ -int zlog_rotate(void) -{ - pthread_mutex_lock(&loglock); - - struct zlog *zl = zlog_default; - int level; - int ret = 1; - - if (zl->fp) - fclose(zl->fp); - zl->fp = NULL; - logfile_fd = -1; - level = zl->maxlvl[ZLOG_DEST_FILE]; - zl->maxlvl[ZLOG_DEST_FILE] = ZLOG_DISABLED; - - if (zl->filename) { - mode_t oldumask; - int save_errno; - - oldumask = umask(0777 & ~LOGFILE_MASK); - zl->fp = fopen(zl->filename, "a"); - save_errno = errno; - umask(oldumask); - if (zl->fp == NULL) { - - pthread_mutex_unlock(&loglock); - - flog_err_sys( - EC_LIB_SYSTEM_CALL, - "Log rotate failed: cannot open file %s for append: %s", - zl->filename, safe_strerror(save_errno)); - ret = -1; - - pthread_mutex_lock(&loglock); - } else { - logfile_fd = fileno(zl->fp); - zl->maxlvl[ZLOG_DEST_FILE] = level; - } - } - - pthread_mutex_unlock(&loglock); - - return ret; -} - /* Wrapper around strerror to handle case where it returns NULL. */ const char *safe_strerror(int errnum) { @@ -22,21 +22,22 @@ #ifndef _ZEBRA_LOG_H #define _ZEBRA_LOG_H +#include "zassert.h" + #include <syslog.h> #include <stdint.h> #include <stdbool.h> #include <stdio.h> #include <stdarg.h> + #include "lib/hook.h" +#include "lib/zlog.h" +#include "lib/zlog_targets.h" #ifdef __cplusplus extern "C" { #endif -/* Hook for external logging function */ -DECLARE_HOOK(zebra_ext_log, (int priority, const char *format, va_list args), - (priority, format, args)); - /* Here is some guidance on logging levels to use: * * LOG_DEBUG - For all messages that are enabled by optional debugging @@ -53,19 +54,7 @@ DECLARE_HOOK(zebra_ext_log, (int priority, const char *format, va_list args), * please use LOG_ERR instead. */ -/* If maxlvl is set to ZLOG_DISABLED, then no messages will be sent - to that logging destination. */ -#define ZLOG_DISABLED (LOG_EMERG-1) - -typedef enum { - ZLOG_DEST_SYSLOG = 0, - ZLOG_DEST_STDOUT, - ZLOG_DEST_MONITOR, - ZLOG_DEST_FILE -} zlog_dest_t; -#define ZLOG_NUM_DESTS (ZLOG_DEST_FILE+1) - -extern bool zlog_startup_stderr; +extern void zlog_rotate(void); /* Message structure. */ struct message { @@ -73,22 +62,6 @@ struct message { const char *str; }; -/* Open zlog function */ -extern void openzlog(const char *progname, const char *protoname, - uint16_t instance, int syslog_options, - int syslog_facility); - -/* Close zlog function. */ -extern void closezlog(void); - -/* Handy zlog functions. */ -extern void zlog_err(const char *format, ...) PRINTFRR(1, 2); -extern void zlog_warn(const char *format, ...) PRINTFRR(1, 2); -extern void zlog_info(const char *format, ...) PRINTFRR(1, 2); -extern void zlog_notice(const char *format, ...) PRINTFRR(1, 2); -extern void zlog_debug(const char *format, ...) PRINTFRR(1, 2); -extern void zlog(int priority, const char *format, ...) PRINTFRR(2, 3); - /* For logs which have error codes associated with them */ #define flog_err(ferr_id, format, ...) \ zlog_err("[EC %" PRIu32 "] " format, ferr_id, ##__VA_ARGS__) @@ -101,23 +74,16 @@ extern void zlog(int priority, const char *format, ...) PRINTFRR(2, 3); extern void zlog_thread_info(int log_level); -/* Set logging level for the given destination. If the log_level - argument is ZLOG_DISABLED, then the destination is disabled. - This function should not be used for file logging (use zlog_set_file - or zlog_reset_file instead). */ -extern void zlog_set_level(zlog_dest_t, int log_level); - -/* Set logging to the given filename at the specified level. */ -extern int zlog_set_file(const char *filename, int log_level); -/* Disable file logging. */ -extern int zlog_reset_file(void); - -/* Rotate log. */ -extern int zlog_rotate(void); - #define ZLOG_FILTERS_MAX 100 /* Max # of filters at once */ #define ZLOG_FILTER_LENGTH_MAX 80 /* 80 character filter limit */ +struct zlog_cfg_filterfile { + struct zlog_cfg_file parent; +}; + +extern void zlog_filterfile_init(struct zlog_cfg_filterfile *zcf); +extern void zlog_filterfile_fini(struct zlog_cfg_filterfile *zcf); + /* Add/Del/Dump log filters */ extern void zlog_filter_clear(void); extern int zlog_filter_add(const char *filter); @@ -176,8 +142,6 @@ extern int proto_redistnum(int afi, const char *s); extern const char *zserv_command_string(unsigned int command); -extern int vzlog_test(int priority); - /* structure useful for avoiding repeated rendering of the same timestamp */ struct timestamp_control { size_t len; /* length of rendered timestamp */ diff --git a/lib/log_filter.c b/lib/log_filter.c new file mode 100644 index 0000000000..721e57a628 --- /dev/null +++ b/lib/log_filter.c @@ -0,0 +1,156 @@ +/* + * Logging - Filtered file log target + * Copyright (C) 2019 Cumulus Networks, Inc. + * Stephen Worley + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "frr_pthread.h" +#include "log.h" + +static pthread_mutex_t logfilterlock = PTHREAD_MUTEX_INITIALIZER; +static char zlog_filters[ZLOG_FILTERS_MAX][ZLOG_FILTER_LENGTH_MAX + 1]; +static uint8_t zlog_filter_count; + +/* + * look for a match on the filter in the current filters, + * logfilterlock must be held + */ +static int zlog_filter_lookup(const char *lookup) +{ + for (int i = 0; i < zlog_filter_count; i++) { + if (strncmp(lookup, zlog_filters[i], sizeof(zlog_filters[0])) + == 0) + return i; + } + return -1; +} + +void zlog_filter_clear(void) +{ + frr_with_mutex(&logfilterlock) { + zlog_filter_count = 0; + } +} + +int zlog_filter_add(const char *filter) +{ + frr_with_mutex(&logfilterlock) { + if (zlog_filter_count >= ZLOG_FILTERS_MAX) + return 1; + + if (zlog_filter_lookup(filter) != -1) + /* Filter already present */ + return -1; + + strlcpy(zlog_filters[zlog_filter_count], filter, + sizeof(zlog_filters[0])); + + if (zlog_filters[zlog_filter_count][0] == '\0') + /* Filter was either empty or didn't get copied + * correctly + */ + return -1; + + zlog_filter_count++; + } + return 0; +} + +int zlog_filter_del(const char *filter) +{ + frr_with_mutex(&logfilterlock) { + int found_idx = zlog_filter_lookup(filter); + int last_idx = zlog_filter_count - 1; + + if (found_idx == -1) + /* Didn't find the filter to delete */ + return -1; + + /* Adjust the filter array */ + memmove(zlog_filters[found_idx], zlog_filters[found_idx + 1], + (last_idx - found_idx) * sizeof(zlog_filters[0])); + + zlog_filter_count--; + } + return 0; +} + +/* Dump all filters to buffer, delimited by new line */ +int zlog_filter_dump(char *buf, size_t max_size) +{ + int len = 0; + + frr_with_mutex(&logfilterlock) { + for (int i = 0; i < zlog_filter_count; i++) { + int ret; + + ret = snprintf(buf + len, max_size - len, " %s\n", + zlog_filters[i]); + len += ret; + if ((ret < 0) || ((size_t)len >= max_size)) + return -1; + } + } + + return len; +} + +static int search_buf(const char *buf) +{ + char *found = NULL; + + frr_with_mutex(&logfilterlock) { + for (int i = 0; i < zlog_filter_count; i++) { + found = strstr(buf, zlog_filters[i]); + if (found != NULL) + return 0; + } + } + + return -1; +} + +static void zlog_filterfile_fd(struct zlog_target *zt, struct zlog_msg *msgs[], + size_t nmsgs) +{ + struct zlog_msg *msgfilt[nmsgs]; + size_t i, o = 0; + + for (i = 0; i < nmsgs; i++) { + if (zlog_msg_prio(msgs[i]) >= LOG_DEBUG + && search_buf(zlog_msg_text(msgs[i], NULL)) < 0) + continue; + + msgfilt[o++] = msgs[i]; + } + + if (o) + zlog_fd(zt, msgfilt, o); +} + +void zlog_filterfile_init(struct zlog_cfg_filterfile *zcf) +{ + zlog_file_init(&zcf->parent); + zcf->parent.zlog_wrap = zlog_filterfile_fd; +} + +void zlog_filterfile_fini(struct zlog_cfg_filterfile *zcf) +{ + zlog_file_fini(&zcf->parent); +} diff --git a/lib/log_int.h b/lib/log_int.h deleted file mode 100644 index 287e626eab..0000000000 --- a/lib/log_int.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Zebra logging funcions. - * Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro - * - * This file is part of GNU Zebra. - * - * GNU Zebra is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * GNU Zebra is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _ZEBRA_LOG_PRIVATE_H -#define _ZEBRA_LOG_PRIVATE_H - -#include "log.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct zlog { - const char *ident; /* daemon name (first arg to openlog) */ - const char *protoname; - unsigned short instance; - int maxlvl[ZLOG_NUM_DESTS]; /* maximum priority to send to associated - logging destination */ - int default_lvl; /* maxlvl to use if none is specified */ - FILE *fp; - char *filename; - int facility; /* as per syslog facility */ - int record_priority; /* should messages logged through stdio include the - priority of the message? */ - int syslog_options; /* 2nd arg to openlog */ - int timestamp_precision; /* # of digits of subsecond precision */ -}; - -/* Default logging strucutre. */ -extern struct zlog *zlog_default; - -extern const char *zlog_priority[]; - -/* Generic function for zlog. */ -extern void vzlog(int priority, const char *format, va_list args); - -#ifdef __cplusplus -} -#endif - -#endif /* _ZEBRA_LOG_PRIVATE_H */ diff --git a/lib/log_vty.c b/lib/log_vty.c index 68d598f565..d1dcac2340 100644 --- a/lib/log_vty.c +++ b/lib/log_vty.c @@ -22,12 +22,548 @@ #include "lib/log_vty.h" #include "command.h" -#include "lib/vty.h" #include "lib/log.h" +#include "lib/zlog_targets.h" +#include "lib/lib_errors.h" +#include "lib/printfrr.h" + #ifndef VTYSH_EXTRACT_PL #include "lib/log_vty_clippy.c" #endif +#define ZLOG_MAXLVL(a, b) MAX(a, b) + +DEFINE_HOOK(zlog_rotate, (), ()) + +static const int log_default_lvl = LOG_DEBUG; + +static int log_config_stdout_lvl = ZLOG_DISABLED; +static int log_config_syslog_lvl = ZLOG_DISABLED; +static int log_cmdline_stdout_lvl = ZLOG_DISABLED; +static int log_cmdline_syslog_lvl = ZLOG_DISABLED; + +static struct zlog_cfg_file zt_file_cmdline = { + .prio_min = ZLOG_DISABLED, +}; +static struct zlog_cfg_file zt_file = { + .prio_min = ZLOG_DISABLED, +}; +static struct zlog_cfg_file zt_stdout = { + .prio_min = ZLOG_DISABLED, +}; +static struct zlog_cfg_filterfile zt_filterfile = { + .parent = { + .prio_min = ZLOG_DISABLED, + }, +}; + +static const char *zlog_progname; +static const char *zlog_protoname; + +static const struct facility_map { + int facility; + const char *name; + size_t match; +} syslog_facilities[] = { + {LOG_KERN, "kern", 1}, + {LOG_USER, "user", 2}, + {LOG_MAIL, "mail", 1}, + {LOG_DAEMON, "daemon", 1}, + {LOG_AUTH, "auth", 1}, + {LOG_SYSLOG, "syslog", 1}, + {LOG_LPR, "lpr", 2}, + {LOG_NEWS, "news", 1}, + {LOG_UUCP, "uucp", 2}, + {LOG_CRON, "cron", 1}, +#ifdef LOG_FTP + {LOG_FTP, "ftp", 1}, +#endif + {LOG_LOCAL0, "local0", 6}, + {LOG_LOCAL1, "local1", 6}, + {LOG_LOCAL2, "local2", 6}, + {LOG_LOCAL3, "local3", 6}, + {LOG_LOCAL4, "local4", 6}, + {LOG_LOCAL5, "local5", 6}, + {LOG_LOCAL6, "local6", 6}, + {LOG_LOCAL7, "local7", 6}, + {0, NULL, 0}, +}; + +static const char * const zlog_priority[] = { + "emergencies", "alerts", "critical", "errors", "warnings", + "notifications", "informational", "debugging", NULL, +}; + +static const char *facility_name(int facility) +{ + const struct facility_map *fm; + + for (fm = syslog_facilities; fm->name; fm++) + if (fm->facility == facility) + return fm->name; + return ""; +} + +static int facility_match(const char *str) +{ + const struct facility_map *fm; + + for (fm = syslog_facilities; fm->name; fm++) + if (!strncmp(str, fm->name, fm->match)) + return fm->facility; + return -1; +} + +int log_level_match(const char *s) +{ + int level; + + for (level = 0; zlog_priority[level] != NULL; level++) + if (!strncmp(s, zlog_priority[level], 2)) + return level; + return ZLOG_DISABLED; +} + +void zlog_rotate(void) +{ + zlog_file_rotate(&zt_file); + zlog_file_rotate(&zt_filterfile.parent); + hook_call(zlog_rotate); +} + + +void log_show_syslog(struct vty *vty) +{ + int level = zlog_syslog_get_prio_min(); + + vty_out(vty, "Syslog logging: "); + if (level == ZLOG_DISABLED) + vty_out(vty, "disabled\n"); + else + vty_out(vty, "level %s, facility %s, ident %s\n", + zlog_priority[level], + facility_name(zlog_syslog_get_facility()), + zlog_progname); +} + +DEFUN (show_logging, + show_logging_cmd, + "show logging", + SHOW_STR + "Show current logging configuration\n") +{ + log_show_syslog(vty); + + vty_out(vty, "Stdout logging: "); + if (zt_stdout.prio_min == ZLOG_DISABLED) + vty_out(vty, "disabled"); + else + vty_out(vty, "level %s", + zlog_priority[zt_stdout.prio_min]); + vty_out(vty, "\n"); + + vty_out(vty, "File logging: "); + if (zt_file.prio_min == ZLOG_DISABLED || !zt_file.filename) + vty_out(vty, "disabled"); + else + vty_out(vty, "level %s, filename %s", + zlog_priority[zt_file.prio_min], zt_file.filename); + vty_out(vty, "\n"); + + if (zt_filterfile.parent.prio_min != ZLOG_DISABLED + && zt_filterfile.parent.filename) + vty_out(vty, "Filtered-file logging: level %s, filename %s\n", + zlog_priority[zt_filterfile.parent.prio_min], + zt_filterfile.parent.filename); + + if (log_cmdline_syslog_lvl != ZLOG_DISABLED) + vty_out(vty, + "From command line: \"--log syslog --log-level %s\"\n", + zlog_priority[log_cmdline_syslog_lvl]); + if (log_cmdline_stdout_lvl != ZLOG_DISABLED) + vty_out(vty, + "From command line: \"--log stdout --log-level %s\"\n", + zlog_priority[log_cmdline_stdout_lvl]); + if (zt_file_cmdline.prio_min != ZLOG_DISABLED) + vty_out(vty, + "From command line: \"--log file:%s --log-level %s\"\n", + zt_file_cmdline.filename, + zlog_priority[zt_file_cmdline.prio_min]); + + vty_out(vty, "Protocol name: %s\n", zlog_protoname); + vty_out(vty, "Record priority: %s\n", + (zt_file.record_priority ? "enabled" : "disabled")); + vty_out(vty, "Timestamp precision: %d\n", zt_file.ts_subsec); + return CMD_SUCCESS; +} + +DEFPY (config_log_stdout, + config_log_stdout_cmd, + "log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]", + "Logging control\n" + "Set stdout logging level\n" + LOG_LEVEL_DESC) +{ + int level; + + if (levelarg) { + level = log_level_match(levelarg); + if (level == ZLOG_DISABLED) + return CMD_ERR_NO_MATCH; + } else + level = log_default_lvl; + + log_config_stdout_lvl = level; + zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl, + log_cmdline_stdout_lvl); + zlog_file_set_other(&zt_stdout); + return CMD_SUCCESS; +} + +DEFUN (no_config_log_stdout, + no_config_log_stdout_cmd, + "no log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", + NO_STR + "Logging control\n" + "Cancel logging to stdout\n" + LOG_LEVEL_DESC) +{ + log_config_stdout_lvl = ZLOG_DISABLED; + zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl, + log_cmdline_stdout_lvl); + zlog_file_set_other(&zt_stdout); + return CMD_SUCCESS; +} + +DEFUN_HIDDEN (config_log_monitor, + config_log_monitor_cmd, + "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", + "Logging control\n" + "Set terminal line (monitor) logging level\n" + LOG_LEVEL_DESC) +{ + vty_out(vty, "%% \"log monitor\" is deprecated and does nothing.\n"); + return CMD_SUCCESS; +} + +DEFUN_HIDDEN (no_config_log_monitor, + no_config_log_monitor_cmd, + "no log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", + NO_STR + "Logging control\n" + "Disable terminal line (monitor) logging\n" + LOG_LEVEL_DESC) +{ + return CMD_SUCCESS; +} + +static int set_log_file(struct zlog_cfg_file *target, struct vty *vty, + const char *fname, int loglevel) +{ + char path[MAXPATHLEN + 1]; + const char *fullpath; + bool ok; + + + /* Path detection. */ + if (!IS_DIRECTORY_SEP(*fname)) { + char cwd[MAXPATHLEN + 1]; + + cwd[MAXPATHLEN] = '\0'; + + if (getcwd(cwd, MAXPATHLEN) == NULL) { + flog_err_sys(EC_LIB_SYSTEM_CALL, + "config_log_file: Unable to alloc mem!"); + return CMD_WARNING_CONFIG_FAILED; + } + + int pr = snprintf(path, sizeof(path), "%s/%s", cwd, fname); + if (pr < 0 || (unsigned int)pr >= sizeof(path)) { + flog_err_sys( + EC_LIB_SYSTEM_CALL, + "%s: Path too long ('%s/%s'); system maximum is %u", + __func__, cwd, fname, MAXPATHLEN); + return CMD_WARNING_CONFIG_FAILED; + } + + fullpath = path; + } else + fullpath = fname; + + target->prio_min = loglevel; + ok = zlog_file_set_filename(target, fullpath); + + if (!ok) { + if (vty) + vty_out(vty, "can't open logfile %s\n", fname); + return CMD_WARNING_CONFIG_FAILED; + } + return CMD_SUCCESS; +} + +void command_setup_early_logging(const char *dest, const char *level) +{ + int nlevel; + char *sep; + int len; + char type[8]; + + if (level) { + nlevel = log_level_match(level); + + if (nlevel == ZLOG_DISABLED) { + fprintf(stderr, "invalid log level \"%s\"\n", level); + exit(1); + } + } else + nlevel = log_default_lvl; + + if (!dest) + return; + + sep = strchr(dest, ':'); + len = sep ? (int)(sep - dest) : (int)strlen(dest); + + snprintfrr(type, sizeof(type), "%.*s", len, dest); + + if (strcmp(type, "stdout") == 0) { + log_cmdline_stdout_lvl = nlevel; + zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl, + log_cmdline_stdout_lvl); + zlog_file_set_other(&zt_stdout); + return; + } + if (strcmp(type, "syslog") == 0) { + log_cmdline_syslog_lvl = nlevel; + zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl, + log_cmdline_syslog_lvl)); + return; + } + if (strcmp(type, "file") == 0 && sep) { + sep++; + set_log_file(&zt_file_cmdline, NULL, sep, nlevel); + return; + } + + fprintf(stderr, "invalid log target \"%s\" (\"%s\")\n", type, dest); + exit(1); +} + +DEFUN (clear_log_cmdline, + clear_log_cmdline_cmd, + "clear log cmdline-targets", + CLEAR_STR + "Logging control\n" + "Disable log targets specified at startup by --log option\n") +{ + zt_file_cmdline.prio_min = ZLOG_DISABLED; + zlog_file_set_other(&zt_file_cmdline); + + log_cmdline_syslog_lvl = ZLOG_DISABLED; + zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl, + log_cmdline_syslog_lvl)); + + log_cmdline_stdout_lvl = ZLOG_DISABLED; + zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl, + log_cmdline_stdout_lvl); + zlog_file_set_other(&zt_stdout); + + return CMD_SUCCESS; +} + +DEFPY (config_log_file, + config_log_file_cmd, + "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]", + "Logging control\n" + "Logging to file\n" + "Logging filename\n" + LOG_LEVEL_DESC) +{ + int level = log_default_lvl; + + if (levelarg) { + level = log_level_match(levelarg); + if (level == ZLOG_DISABLED) + return CMD_ERR_NO_MATCH; + } + return set_log_file(&zt_file, vty, filename, level); +} + +DEFUN (no_config_log_file, + no_config_log_file_cmd, + "no log file [FILENAME [LEVEL]]", + NO_STR + "Logging control\n" + "Cancel logging to file\n" + "Logging file name\n" + "Logging level\n") +{ + zt_file.prio_min = ZLOG_DISABLED; + zlog_file_set_other(&zt_file); + return CMD_SUCCESS; +} + +DEFPY (config_log_syslog, + config_log_syslog_cmd, + "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]", + "Logging control\n" + "Set syslog logging level\n" + LOG_LEVEL_DESC) +{ + int level; + + if (levelarg) { + level = log_level_match(levelarg); + + if (level == ZLOG_DISABLED) + return CMD_ERR_NO_MATCH; + } else + level = log_default_lvl; + + log_config_syslog_lvl = level; + zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl, + log_cmdline_syslog_lvl)); + return CMD_SUCCESS; +} + +DEFUN (no_config_log_syslog, + no_config_log_syslog_cmd, + "no log syslog [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>] [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]", + NO_STR + "Logging control\n" + "Cancel logging to syslog\n" + LOG_FACILITY_DESC + LOG_LEVEL_DESC) +{ + log_config_syslog_lvl = ZLOG_DISABLED; + zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl, + log_cmdline_syslog_lvl)); + return CMD_SUCCESS; +} + +DEFPY (config_log_facility, + config_log_facility_cmd, + "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>$facilityarg", + "Logging control\n" + "Facility parameter for syslog messages\n" + LOG_FACILITY_DESC) +{ + int facility = facility_match(facilityarg); + + zlog_syslog_set_facility(facility); + return CMD_SUCCESS; +} + +DEFUN (no_config_log_facility, + no_config_log_facility_cmd, + "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]", + NO_STR + "Logging control\n" + "Reset syslog facility to default (daemon)\n" + LOG_FACILITY_DESC) +{ + zlog_syslog_set_facility(LOG_DAEMON); + return CMD_SUCCESS; +} + +DEFUN (config_log_record_priority, + config_log_record_priority_cmd, + "log record-priority", + "Logging control\n" + "Log the priority of the message within the message\n") +{ + zt_file.record_priority = true; + zlog_file_set_other(&zt_file); + zt_stdout.record_priority = true; + zlog_file_set_other(&zt_stdout); + zt_filterfile.parent.record_priority = true; + zlog_file_set_other(&zt_filterfile.parent); + return CMD_SUCCESS; +} + +DEFUN (no_config_log_record_priority, + no_config_log_record_priority_cmd, + "no log record-priority", + NO_STR + "Logging control\n" + "Do not log the priority of the message within the message\n") +{ + zt_file.record_priority = false; + zlog_file_set_other(&zt_file); + zt_stdout.record_priority = false; + zlog_file_set_other(&zt_stdout); + zt_filterfile.parent.record_priority = false; + zlog_file_set_other(&zt_filterfile.parent); + return CMD_SUCCESS; +} + +DEFPY (config_log_timestamp_precision, + config_log_timestamp_precision_cmd, + "log timestamp precision (0-6)", + "Logging control\n" + "Timestamp configuration\n" + "Set the timestamp precision\n" + "Number of subsecond digits\n") +{ + zt_file.ts_subsec = precision; + zlog_file_set_other(&zt_file); + zt_stdout.ts_subsec = precision; + zlog_file_set_other(&zt_stdout); + zt_filterfile.parent.ts_subsec = precision; + zlog_file_set_other(&zt_filterfile.parent); + return CMD_SUCCESS; +} + +DEFUN (no_config_log_timestamp_precision, + no_config_log_timestamp_precision_cmd, + "no log timestamp precision [(0-6)]", + NO_STR + "Logging control\n" + "Timestamp configuration\n" + "Reset the timestamp precision to the default value of 0\n" + "Number of subsecond digits\n") +{ + zt_file.ts_subsec = 0; + zlog_file_set_other(&zt_file); + zt_stdout.ts_subsec = 0; + zlog_file_set_other(&zt_stdout); + zt_filterfile.parent.ts_subsec = 0; + zlog_file_set_other(&zt_filterfile.parent); + return CMD_SUCCESS; +} + +DEFPY (config_log_filterfile, + config_log_filterfile_cmd, + "log filtered-file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]", + "Logging control\n" + "Logging to file with string filter\n" + "Logging filename\n" + LOG_LEVEL_DESC) +{ + int level = log_default_lvl; + + if (levelarg) { + level = log_level_match(levelarg); + if (level == ZLOG_DISABLED) + return CMD_ERR_NO_MATCH; + } + return set_log_file(&zt_filterfile.parent, vty, filename, level); +} + +DEFUN (no_config_log_filterfile, + no_config_log_filterfile_cmd, + "no log filtered-file [FILENAME [LEVEL]]", + NO_STR + "Logging control\n" + "Cancel logging to file with string filter\n" + "Logging file name\n" + "Logging level\n") +{ + zt_filterfile.parent.prio_min = ZLOG_DISABLED; + zlog_file_set_other(&zt_filterfile.parent); + return CMD_SUCCESS; +} + DEFPY (log_filter, log_filter_cmd, "[no] log-filter WORD$filter", @@ -89,9 +625,122 @@ DEFPY (show_log_filter, return CMD_SUCCESS; } -void log_filter_cmd_init(void) +void log_config_write(struct vty *vty) { + bool show_cmdline_hint = false; + + if (zt_file.prio_min != ZLOG_DISABLED && zt_file.filename) { + vty_out(vty, "log file %s", zt_file.filename); + + if (zt_file.prio_min != log_default_lvl) + vty_out(vty, " %s", zlog_priority[zt_file.prio_min]); + vty_out(vty, "\n"); + } + + if (zt_filterfile.parent.prio_min != ZLOG_DISABLED + && zt_filterfile.parent.filename) { + vty_out(vty, "log filtered-file %s", + zt_filterfile.parent.filename); + + if (zt_filterfile.parent.prio_min != log_default_lvl) + vty_out(vty, " %s", + zlog_priority[zt_filterfile.parent.prio_min]); + vty_out(vty, "\n"); + } + + if (log_config_stdout_lvl != ZLOG_DISABLED) { + vty_out(vty, "log stdout"); + + if (log_config_stdout_lvl != log_default_lvl) + vty_out(vty, " %s", + zlog_priority[log_config_stdout_lvl]); + vty_out(vty, "\n"); + } + + if (log_config_syslog_lvl != ZLOG_DISABLED) { + vty_out(vty, "log syslog"); + + if (log_config_syslog_lvl != log_default_lvl) + vty_out(vty, " %s", + zlog_priority[log_config_syslog_lvl]); + vty_out(vty, "\n"); + } + + if (log_cmdline_syslog_lvl != ZLOG_DISABLED) { + vty_out(vty, + "! \"log syslog %s\" enabled by \"--log\" startup option\n", + zlog_priority[log_cmdline_syslog_lvl]); + show_cmdline_hint = true; + } + if (log_cmdline_stdout_lvl != ZLOG_DISABLED) { + vty_out(vty, + "! \"log stdout %s\" enabled by \"--log\" startup option\n", + zlog_priority[log_cmdline_stdout_lvl]); + show_cmdline_hint = true; + } + if (zt_file_cmdline.prio_min != ZLOG_DISABLED) { + vty_out(vty, + "! \"log file %s %s\" enabled by \"--log\" startup option\n", + zt_file_cmdline.filename, + zlog_priority[zt_file_cmdline.prio_min]); + show_cmdline_hint = true; + } + if (show_cmdline_hint) + vty_out(vty, + "! use \"clear log cmdline-targets\" to remove this target\n"); + + if (zlog_syslog_get_facility() != LOG_DAEMON) + vty_out(vty, "log facility %s\n", + facility_name(zlog_syslog_get_facility())); + + if (zt_file.record_priority == 1) + vty_out(vty, "log record-priority\n"); + + if (zt_file.ts_subsec > 0) + vty_out(vty, "log timestamp precision %d\n", + zt_file.ts_subsec); +} + +static int log_vty_init(const char *progname, const char *protoname, + unsigned short instance, uid_t uid, gid_t gid) +{ + zlog_progname = progname; + zlog_protoname = protoname; + + zlog_filterfile_init(&zt_filterfile); + + zlog_file_set_fd(&zt_stdout, STDOUT_FILENO); + return 0; +} + +__attribute__((_CONSTRUCTOR(475))) static void log_vty_preinit(void) +{ + hook_register(zlog_init, log_vty_init); +} + +void log_cmd_init(void) +{ + install_element(VIEW_NODE, &show_logging_cmd); + install_element(ENABLE_NODE, &clear_log_cmdline_cmd); + + install_element(CONFIG_NODE, &config_log_stdout_cmd); + install_element(CONFIG_NODE, &no_config_log_stdout_cmd); + install_element(CONFIG_NODE, &config_log_monitor_cmd); + install_element(CONFIG_NODE, &no_config_log_monitor_cmd); + install_element(CONFIG_NODE, &config_log_file_cmd); + install_element(CONFIG_NODE, &no_config_log_file_cmd); + install_element(CONFIG_NODE, &config_log_syslog_cmd); + install_element(CONFIG_NODE, &no_config_log_syslog_cmd); + install_element(CONFIG_NODE, &config_log_facility_cmd); + install_element(CONFIG_NODE, &no_config_log_facility_cmd); + install_element(CONFIG_NODE, &config_log_record_priority_cmd); + install_element(CONFIG_NODE, &no_config_log_record_priority_cmd); + install_element(CONFIG_NODE, &config_log_timestamp_precision_cmd); + install_element(CONFIG_NODE, &no_config_log_timestamp_precision_cmd); + install_element(VIEW_NODE, &show_log_filter_cmd); install_element(CONFIG_NODE, &log_filter_cmd); install_element(CONFIG_NODE, &log_filter_clear_cmd); + install_element(CONFIG_NODE, &config_log_filterfile_cmd); + install_element(CONFIG_NODE, &no_config_log_filterfile_cmd); } diff --git a/lib/log_vty.h b/lib/log_vty.h index fa5627e4bd..16c4475467 100644 --- a/lib/log_vty.h +++ b/lib/log_vty.h @@ -20,5 +20,25 @@ #ifndef __LOG_VTY_H__ #define __LOG_VTY_H__ -extern void log_filter_cmd_init(void); + +#include "lib/hook.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct vty; + +extern void log_cmd_init(void); +extern void log_config_write(struct vty *vty); +extern int log_level_match(const char *s); +extern void log_show_syslog(struct vty *vty); + +DECLARE_HOOK(zlog_rotate, (), ()) +extern void zlog_rotate(void); + +#ifdef __cplusplus +} +#endif + #endif /* __LOG_VTY_H__ */ diff --git a/lib/memory.c b/lib/memory.c index 149e294d50..3a29404827 100644 --- a/lib/memory.c +++ b/lib/memory.c @@ -163,7 +163,8 @@ static int qmem_exit_walker(void *arg, struct memgroup *mg, struct memtype *mt) } else if (mt->n_alloc) { char size[32]; - eda->error++; + if (!mg->active_at_exit) + eda->error++; snprintf(size, sizeof(size), "%10zu", mt->size); fprintf(eda->fp, "%s: memstats: %-30s: %6zu * %s\n", eda->prefix, mt->name, mt->n_alloc, diff --git a/lib/memory.h b/lib/memory.h index e4e05faa4f..13f2f9b11a 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -17,6 +17,7 @@ #ifndef _QUAGGA_MEMORY_H #define _QUAGGA_MEMORY_H +#include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <frratomic.h> @@ -48,6 +49,8 @@ struct memgroup { struct memgroup *next, **ref; struct memtype *types, **insert; const char *name; + /* ignore group on dumping memleaks at exit */ + bool active_at_exit; }; /* macro usage: @@ -76,7 +79,7 @@ struct memgroup { */ #define DECLARE_MGROUP(name) extern struct memgroup _mg_##name; -#define DEFINE_MGROUP(mname, desc) \ +#define _DEFINE_MGROUP(mname, desc, ...) \ struct memgroup _mg_##mname \ __attribute__((section(".data.mgroups"))) = { \ .name = desc, \ @@ -84,6 +87,7 @@ struct memgroup { .next = NULL, \ .insert = NULL, \ .ref = NULL, \ + __VA_ARGS__ \ }; \ static void _mginit_##mname(void) __attribute__((_CONSTRUCTOR(1000))); \ static void _mginit_##mname(void) \ @@ -99,7 +103,13 @@ struct memgroup { if (_mg_##mname.next) \ _mg_##mname.next->ref = _mg_##mname.ref; \ *_mg_##mname.ref = _mg_##mname.next; \ - } + } \ + /* end */ + +#define DEFINE_MGROUP(mname, desc) \ + _DEFINE_MGROUP(mname, desc, ) +#define DEFINE_MGROUP_ACTIVEATEXIT(mname, desc) \ + _DEFINE_MGROUP(mname, desc, .active_at_exit = true) #define DECLARE_MTYPE(name) \ extern struct memtype MTYPE_##name[1]; \ diff --git a/lib/netns_linux.c b/lib/netns_linux.c index 4d4376250f..98f359401e 100644 --- a/lib/netns_linux.c +++ b/lib/netns_linux.c @@ -431,7 +431,7 @@ char *ns_netns_pathname(struct vty *vty, const char *name) /* relevant pathname */ char tmp_name[PATH_MAX]; - snprintf(tmp_name, PATH_MAX, "%s/%s", NS_RUN_DIR, name); + snprintf(tmp_name, sizeof(tmp_name), "%s/%s", NS_RUN_DIR, name); result = realpath(tmp_name, pathname); } diff --git a/lib/network.c b/lib/network.c index 411661a5e1..d2482bd55e 100644 --- a/lib/network.c +++ b/lib/network.c @@ -121,3 +121,21 @@ float ntohf(float net) { return htonf(net); } + +/** + * Helper function that returns a random long value. The main purpose of + * this function is to hide a `random()` call that gets flagged by coverity + * scan and put it into one place. + * + * The main usage of this function should be for generating jitter or weak + * random values for simple purposes. + * + * See 'man 3 random' for more information. + * + * \returns random long integer. + */ +long frr_weak_random(void) +{ + /* coverity[dont_call] */ + return random(); +} diff --git a/lib/network.h b/lib/network.h index a00c5a0a65..83c9e59e76 100644 --- a/lib/network.h +++ b/lib/network.h @@ -45,6 +45,8 @@ extern int set_cloexec(int fd); extern float htonf(float); extern float ntohf(float); +extern long frr_weak_random(void); + #ifdef __cplusplus } #endif diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index a4c823e37a..c23c57d2e1 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -933,10 +933,13 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, return CMD_SUCCESS; } +static int nexthop_group_write(struct vty *vty); static struct cmd_node nexthop_group_node = { - NH_GROUP_NODE, - "%s(config-nh-group)# ", - 1 + .name = "nexthop-group", + .node = NH_GROUP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-nh-group)# ", + .config_write = nexthop_group_write, }; void nexthop_group_write_nexthop(struct vty *vty, struct nexthop *nh) @@ -1210,7 +1213,7 @@ void nexthop_group_init(void (*new)(const char *name), cmd_variable_handler_register(nhg_name_handlers); - install_node(&nexthop_group_node, nexthop_group_write); + install_node(&nexthop_group_node); install_element(CONFIG_NODE, &nexthop_group_cmd); install_element(CONFIG_NODE, &no_nexthop_group_cmd); diff --git a/lib/northbound.c b/lib/northbound.c index 85e723d7cf..18bd4f5fd8 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -62,11 +62,10 @@ static struct { */ static bool transaction_in_progress; +static int nb_callback_pre_validate(const struct nb_node *nb_node, + const struct lyd_node *dnode); static int nb_callback_configuration(const enum nb_event event, struct nb_config_change *change); -static void nb_log_callback(const enum nb_event event, - enum nb_operation operation, const char *xpath, - const char *value); static struct nb_transaction *nb_transaction_new(struct nb_config *config, struct nb_config_cbs *changes, enum nb_client client, @@ -609,18 +608,7 @@ static int nb_candidate_validate_code(struct nb_config *candidate, if (!nb_node->cbs.pre_validate) goto next; - if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, - DEBUG_MODE_ALL)) { - char xpath[XPATH_MAXLEN]; - - yang_dnode_get_path(child, xpath, - sizeof(xpath)); - nb_log_callback(NB_EV_VALIDATE, - NB_OP_PRE_VALIDATE, xpath, - NULL); - } - - ret = (*nb_node->cbs.pre_validate)(child); + ret = nb_callback_pre_validate(nb_node, child); if (ret != NB_OK) return NB_ERR_VALIDATION; @@ -791,14 +779,173 @@ int nb_running_lock_check(enum nb_client client, const void *user) return ret; } -static void nb_log_callback(const enum nb_event event, - enum nb_operation operation, const char *xpath, - const char *value) +static void nb_log_config_callback(const enum nb_event event, + enum nb_operation operation, + const struct lyd_node *dnode) { + const char *value; + char xpath[XPATH_MAXLEN]; + + if (!DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) + return; + + yang_dnode_get_path(dnode, xpath, sizeof(xpath)); + if (yang_snode_is_typeless_data(dnode->schema)) + value = "(none)"; + else + value = yang_dnode_get_string(dnode, NULL); + zlog_debug( "northbound callback: event [%s] op [%s] xpath [%s] value [%s]", nb_event_name(event), nb_operation_name(operation), xpath, - value ? value : "(NULL)"); + value); +} + +static int nb_callback_create(const struct nb_node *nb_node, + enum nb_event event, const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct nb_cb_create_args args = {}; + + nb_log_config_callback(event, NB_OP_CREATE, dnode); + + args.event = event; + args.dnode = dnode; + args.resource = resource; + return nb_node->cbs.create(&args); +} + +static int nb_callback_modify(const struct nb_node *nb_node, + enum nb_event event, const struct lyd_node *dnode, + union nb_resource *resource) +{ + struct nb_cb_modify_args args = {}; + + nb_log_config_callback(event, NB_OP_MODIFY, dnode); + + args.event = event; + args.dnode = dnode; + args.resource = resource; + return nb_node->cbs.modify(&args); +} + +static int nb_callback_destroy(const struct nb_node *nb_node, + enum nb_event event, + const struct lyd_node *dnode) +{ + struct nb_cb_destroy_args args = {}; + + nb_log_config_callback(event, NB_OP_DESTROY, dnode); + + args.event = event; + args.dnode = dnode; + return nb_node->cbs.destroy(&args); +} + +static int nb_callback_move(const struct nb_node *nb_node, enum nb_event event, + const struct lyd_node *dnode) +{ + struct nb_cb_move_args args = {}; + + nb_log_config_callback(event, NB_OP_MOVE, dnode); + + args.event = event; + args.dnode = dnode; + return nb_node->cbs.move(&args); +} + +static int nb_callback_pre_validate(const struct nb_node *nb_node, + const struct lyd_node *dnode) +{ + struct nb_cb_pre_validate_args args = {}; + + nb_log_config_callback(NB_EV_VALIDATE, NB_OP_PRE_VALIDATE, dnode); + + args.dnode = dnode; + return nb_node->cbs.pre_validate(&args); +} + +static void nb_callback_apply_finish(const struct nb_node *nb_node, + const struct lyd_node *dnode) +{ + struct nb_cb_apply_finish_args args = {}; + + nb_log_config_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, dnode); + + args.dnode = dnode; + nb_node->cbs.apply_finish(&args); +} + +struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node, + const char *xpath, + const void *list_entry) +{ + struct nb_cb_get_elem_args args = {}; + + DEBUGD(&nb_dbg_cbs_state, + "northbound callback (get_elem): xpath [%s] list_entry [%p]", + xpath, list_entry); + + args.xpath = xpath; + args.list_entry = list_entry; + return nb_node->cbs.get_elem(&args); +} + +const void *nb_callback_get_next(const struct nb_node *nb_node, + const void *parent_list_entry, + const void *list_entry) +{ + struct nb_cb_get_next_args args = {}; + + DEBUGD(&nb_dbg_cbs_state, + "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]", + nb_node->xpath, parent_list_entry, list_entry); + + args.parent_list_entry = parent_list_entry; + args.list_entry = list_entry; + return nb_node->cbs.get_next(&args); +} + +int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry, + struct yang_list_keys *keys) +{ + struct nb_cb_get_keys_args args = {}; + + DEBUGD(&nb_dbg_cbs_state, + "northbound callback (get_keys): node [%s] list_entry [%p]", + nb_node->xpath, list_entry); + + args.list_entry = list_entry; + args.keys = keys; + return nb_node->cbs.get_keys(&args); +} + +const void *nb_callback_lookup_entry(const struct nb_node *nb_node, + const void *parent_list_entry, + const struct yang_list_keys *keys) +{ + struct nb_cb_lookup_entry_args args = {}; + + DEBUGD(&nb_dbg_cbs_state, + "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]", + nb_node->xpath, parent_list_entry); + + args.parent_list_entry = parent_list_entry; + args.keys = keys; + return nb_node->cbs.lookup_entry(&args); +} + +int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, + const struct list *input, struct list *output) +{ + struct nb_cb_rpc_args args = {}; + + DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath); + + args.xpath = xpath; + args.input = input; + args.output = output; + return nb_node->cbs.rpc(&args); } /* @@ -815,15 +962,6 @@ static int nb_callback_configuration(const enum nb_event event, union nb_resource *resource; int ret = NB_ERR; - if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) { - const char *value = "(none)"; - - if (dnode && !yang_snode_is_typeless_data(dnode->schema)) - value = yang_dnode_get_string(dnode, NULL); - - yang_dnode_get_path(dnode, xpath, sizeof(xpath)); - nb_log_callback(event, operation, xpath, value); - } if (event == NB_EV_VALIDATE) resource = NULL; @@ -832,16 +970,16 @@ static int nb_callback_configuration(const enum nb_event event, switch (operation) { case NB_OP_CREATE: - ret = (*nb_node->cbs.create)(event, dnode, resource); + ret = nb_callback_create(nb_node, event, dnode, resource); break; case NB_OP_MODIFY: - ret = (*nb_node->cbs.modify)(event, dnode, resource); + ret = nb_callback_modify(nb_node, event, dnode, resource); break; case NB_OP_DESTROY: - ret = (*nb_node->cbs.destroy)(event, dnode); + ret = nb_callback_destroy(nb_node, event, dnode); break; case NB_OP_MOVE: - ret = (*nb_node->cbs.move)(event, dnode); + ret = nb_callback_move(nb_node, event, dnode); break; default: yang_dnode_get_path(dnode, xpath, sizeof(xpath)); @@ -890,57 +1028,6 @@ static int nb_callback_configuration(const enum nb_event event, return ret; } -struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node, - const char *xpath, - const void *list_entry) -{ - DEBUGD(&nb_dbg_cbs_state, - "northbound callback (get_elem): xpath [%s] list_entry [%p]", - xpath, list_entry); - - return nb_node->cbs.get_elem(xpath, list_entry); -} - -const void *nb_callback_get_next(const struct nb_node *nb_node, - const void *parent_list_entry, - const void *list_entry) -{ - DEBUGD(&nb_dbg_cbs_state, - "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]", - nb_node->xpath, parent_list_entry, list_entry); - - return nb_node->cbs.get_next(parent_list_entry, list_entry); -} - -int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry, - struct yang_list_keys *keys) -{ - DEBUGD(&nb_dbg_cbs_state, - "northbound callback (get_keys): node [%s] list_entry [%p]", - nb_node->xpath, list_entry); - - return nb_node->cbs.get_keys(list_entry, keys); -} - -const void *nb_callback_lookup_entry(const struct nb_node *nb_node, - const void *parent_list_entry, - const struct yang_list_keys *keys) -{ - DEBUGD(&nb_dbg_cbs_state, - "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]", - nb_node->xpath, parent_list_entry); - - return nb_node->cbs.lookup_entry(parent_list_entry, keys); -} - -int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, - const struct list *input, struct list *output) -{ - DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath); - - return nb_node->cbs.rpc(xpath, input, output); -} - static struct nb_transaction * nb_transaction_new(struct nb_config *config, struct nb_config_cbs *changes, enum nb_client client, const void *user, const char *comment) @@ -1058,7 +1145,6 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction) { struct nb_config_cbs cbs; struct nb_config_cb *cb; - char xpath[XPATH_MAXLEN]; /* Initialize tree of 'apply_finish' callbacks. */ RB_INIT(nb_config_cbs, &cbs); @@ -1075,6 +1161,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction) * be called though). */ if (change->cb.operation == NB_OP_DESTROY) { + char xpath[XPATH_MAXLEN]; + dnode = dnode->parent; if (!dnode) break; @@ -1111,15 +1199,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction) } /* Call the 'apply_finish' callbacks, sorted by their priorities. */ - RB_FOREACH (cb, nb_config_cbs, &cbs) { - if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) { - yang_dnode_get_path(cb->dnode, xpath, sizeof(xpath)); - nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, xpath, - NULL); - } - - (*cb->nb_node->cbs.apply_finish)(cb->dnode); - } + RB_FOREACH (cb, nb_config_cbs, &cbs) + nb_callback_apply_finish(cb->nb_node, cb->dnode); /* Release memory. */ while (!RB_EMPTY(nb_config_cbs, &cbs)) { diff --git a/lib/northbound.h b/lib/northbound.h index 19a2ba0865..84382eeb60 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -86,6 +86,129 @@ union nb_resource { void *ptr; }; +/* + * Northbound callbacks parameters. + */ + +struct nb_cb_create_args { + /* + * The transaction phase. Refer to the documentation comments of + * nb_event for more details. + */ + enum nb_event event; + + /* libyang data node that is being created. */ + const struct lyd_node *dnode; + + /* + * Pointer to store resource(s) allocated during the NB_EV_PREPARE + * phase. The same pointer can be used during the NB_EV_ABORT and + * NB_EV_APPLY phases to either release or make use of the allocated + * resource(s). It's set to NULL when the event is NB_EV_VALIDATE. + */ + union nb_resource *resource; +}; + +struct nb_cb_modify_args { + /* + * The transaction phase. Refer to the documentation comments of + * nb_event for more details. + */ + enum nb_event event; + + /* libyang data node that is being modified. */ + const struct lyd_node *dnode; + + /* + * Pointer to store resource(s) allocated during the NB_EV_PREPARE + * phase. The same pointer can be used during the NB_EV_ABORT and + * NB_EV_APPLY phases to either release or make use of the allocated + * resource(s). It's set to NULL when the event is NB_EV_VALIDATE. + */ + union nb_resource *resource; +}; + +struct nb_cb_destroy_args { + /* + * The transaction phase. Refer to the documentation comments of + * nb_event for more details. + */ + enum nb_event event; + + /* libyang data node that is being deleted. */ + const struct lyd_node *dnode; +}; + +struct nb_cb_move_args { + /* + * The transaction phase. Refer to the documentation comments of + * nb_event for more details. + */ + enum nb_event event; + + /* libyang data node that is being moved. */ + const struct lyd_node *dnode; +}; + +struct nb_cb_pre_validate_args { + /* libyang data node associated with the 'pre_validate' callback. */ + const struct lyd_node *dnode; +}; + +struct nb_cb_apply_finish_args { + /* libyang data node associated with the 'apply_finish' callback. */ + const struct lyd_node *dnode; +}; + +struct nb_cb_get_elem_args { + /* YANG data path of the data we want to get. */ + const char *xpath; + + /* Pointer to list entry (might be NULL). */ + const void *list_entry; +}; + +struct nb_cb_get_next_args { + /* Pointer to parent list entry. */ + const void *parent_list_entry; + + /* Pointer to (leaf-)list entry. */ + const void *list_entry; +}; + +struct nb_cb_get_keys_args { + /* Pointer to list entry. */ + const void *list_entry; + + /* + * Structure to be filled based on the attributes of the provided list + * entry. + */ + struct yang_list_keys *keys; +}; + +struct nb_cb_lookup_entry_args { + /* Pointer to parent list entry. */ + const void *parent_list_entry; + + /* Structure containing the keys of the list entry. */ + const struct yang_list_keys *keys; +}; + +struct nb_cb_rpc_args { + /* XPath of the YANG RPC or action. */ + const char *xpath; + + /* Read-only list of input parameters. */ + const struct list *input; + + /* List of output parameters to be populated by the callback. */ + struct list *output; +}; + +/* + * Set of configuration callbacks that can be associated to a northbound node. + */ struct nb_callbacks { /* * Configuration callback. @@ -97,18 +220,9 @@ struct nb_callbacks { * initialize the default values of its children (if any) from the YANG * models. * - * event - * The transaction phase. Refer to the documentation comments of - * nb_event for more details. - * - * dnode - * libyang data node that is being created. - * - * resource - * Pointer to store resource(s) allocated during the NB_EV_PREPARE - * phase. The same pointer can be used during the NB_EV_ABORT and - * NB_EV_APPLY phases to either release or make use of the allocated - * resource(s). It's set to NULL when the event is NB_EV_VALIDATE. + * args + * Refer to the documentation comments of nb_cb_create_args for + * details. * * Returns: * - NB_OK on success. @@ -117,8 +231,7 @@ struct nb_callbacks { * - NB_ERR_INCONSISTENCY when an inconsistency was detected. * - NB_ERR for other errors. */ - int (*create)(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + int (*create)(struct nb_cb_create_args *args); /* * Configuration callback. @@ -129,18 +242,9 @@ struct nb_callbacks { * modified, the northbound treats this as if the list was deleted and a * new one created with the updated key value. * - * event - * The transaction phase. Refer to the documentation comments of - * nb_event for more details. - * - * dnode - * libyang data node that is being modified - * - * resource - * Pointer to store resource(s) allocated during the NB_EV_PREPARE - * phase. The same pointer can be used during the NB_EV_ABORT and - * NB_EV_APPLY phases to either release or make use of the allocated - * resource(s). It's set to NULL when the event is NB_EV_VALIDATE. + * args + * Refer to the documentation comments of nb_cb_modify_args for + * details. * * Returns: * - NB_OK on success. @@ -149,8 +253,7 @@ struct nb_callbacks { * - NB_ERR_INCONSISTENCY when an inconsistency was detected. * - NB_ERR for other errors. */ - int (*modify)(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + int (*modify)(struct nb_cb_modify_args *args); /* * Configuration callback. @@ -161,12 +264,9 @@ struct nb_callbacks { * The callback is supposed to delete the entire configuration object, * including its children when they exist. * - * event - * The transaction phase. Refer to the documentation comments of - * nb_event for more details. - * - * dnode - * libyang data node that is being deleted. + * args + * Refer to the documentation comments of nb_cb_destroy_args for + * details. * * Returns: * - NB_OK on success. @@ -174,7 +274,7 @@ struct nb_callbacks { * - NB_ERR_INCONSISTENCY when an inconsistency was detected. * - NB_ERR for other errors. */ - int (*destroy)(enum nb_event event, const struct lyd_node *dnode); + int (*destroy)(struct nb_cb_destroy_args *args); /* * Configuration callback. @@ -182,12 +282,9 @@ struct nb_callbacks { * A list entry or leaf-list entry has been moved. Only applicable when * the "ordered-by user" statement is present. * - * event - * The transaction phase. Refer to the documentation comments of - * nb_event for more details. - * - * dnode - * libyang data node that is being moved. + * args + * Refer to the documentation comments of nb_cb_move_args for + * details. * * Returns: * - NB_OK on success. @@ -195,7 +292,7 @@ struct nb_callbacks { * - NB_ERR_INCONSISTENCY when an inconsistency was detected. * - NB_ERR for other errors. */ - int (*move)(enum nb_event event, const struct lyd_node *dnode); + int (*move)(struct nb_cb_move_args *args); /* * Optional configuration callback. @@ -205,10 +302,11 @@ struct nb_callbacks { * changes themselves. It's useful to perform more complex validations * that depend on the relationship between multiple nodes. * - * dnode - * libyang data node associated with the 'pre_validate' callback. + * args + * Refer to the documentation comments of nb_cb_pre_validate_args for + * details. */ - int (*pre_validate)(const struct lyd_node *dnode); + int (*pre_validate)(struct nb_cb_pre_validate_args *args); /* * Optional configuration callback. @@ -224,10 +322,11 @@ struct nb_callbacks { * once even if multiple changes occurred within the descendants of the * data node. * - * dnode - * libyang data node associated with the 'apply_finish' callback. + * args + * Refer to the documentation comments of nb_cb_apply_finish_args for + * details. */ - void (*apply_finish)(const struct lyd_node *dnode); + void (*apply_finish)(struct nb_cb_apply_finish_args *args); /* * Operational data callback. @@ -236,18 +335,15 @@ struct nb_callbacks { * leaf-list entry or inform if a typeless value (presence containers or * leafs of type empty) exists or not. * - * xpath - * YANG data path of the data we want to get. - * - * list_entry - * Pointer to list entry (might be NULL). + * args + * Refer to the documentation comments of nb_cb_get_elem_args for + * details. * * Returns: * Pointer to newly created yang_data structure, or NULL to indicate * the absence of data. */ - struct yang_data *(*get_elem)(const char *xpath, - const void *list_entry); + struct yang_data *(*get_elem)(struct nb_cb_get_elem_args *args); /* * Operational data callback for YANG lists and leaf-lists. @@ -256,18 +352,15 @@ struct nb_callbacks { * leaf-list. The 'list_entry' parameter will be NULL on the first * invocation. * - * parent_list_entry - * Pointer to parent list entry. - * - * list_entry - * Pointer to (leaf-)list entry. + * args + * Refer to the documentation comments of nb_cb_get_next_args for + * details. * * Returns: * Pointer to the next entry in the (leaf-)list, or NULL to signal * that the end of the (leaf-)list was reached. */ - const void *(*get_next)(const void *parent_list_entry, - const void *list_entry); + const void *(*get_next)(struct nb_cb_get_next_args *args); /* * Operational data callback for YANG lists. @@ -276,17 +369,14 @@ struct nb_callbacks { * given list_entry. Keyless lists don't need to implement this * callback. * - * list_entry - * Pointer to list entry. - * - * keys - * Structure to be filled based on the attributes of the provided - * list entry. + * args + * Refer to the documentation comments of nb_cb_get_keys_args for + * details. * * Returns: * NB_OK on success, NB_ERR otherwise. */ - int (*get_keys)(const void *list_entry, struct yang_list_keys *keys); + int (*get_keys)(struct nb_cb_get_keys_args *args); /* * Operational data callback for YANG lists. @@ -295,17 +385,14 @@ struct nb_callbacks { * keys given as a parameter. Keyless lists don't need to implement this * callback. * - * parent_list_entry - * Pointer to parent list entry. - * - * keys - * Structure containing the keys of the list entry. + * args + * Refer to the documentation comments of nb_cb_lookup_entry_args for + * details. * * Returns: * Pointer to the list entry if found, or NULL if not found. */ - const void *(*lookup_entry)(const void *parent_list_entry, - const struct yang_list_keys *keys); + const void *(*lookup_entry)(struct nb_cb_lookup_entry_args *args); /* * RPC and action callback. @@ -314,20 +401,13 @@ struct nb_callbacks { * callback should fetch all the input parameters from the 'input' list, * and add output parameters to the 'output' list if necessary. * - * xpath - * XPath of the YANG RPC or action. - * - * input - * Read-only list of input parameters. - * - * output - * List of output parameters to be populated by the callback. + * args + * Refer to the documentation comments of nb_cb_rpc_args for details. * * Returns: * NB_OK on success, NB_ERR otherwise. */ - int (*rpc)(const char *xpath, const struct list *input, - struct list *output); + int (*rpc)(struct nb_cb_rpc_args *args); /* * Optional callback to show the CLI command associated to the given diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 17dc256281..d4467facaf 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -1674,7 +1674,12 @@ static int nb_debug_config_write(struct vty *vty) } static struct debug_callbacks nb_dbg_cbs = {.debug_set_all = nb_debug_set_all}; -static struct cmd_node nb_debug_node = {NORTHBOUND_DEBUG_NODE, "", 1}; +static struct cmd_node nb_debug_node = { + .name = "northbound debug", + .node = NORTHBOUND_DEBUG_NODE, + .prompt = "", + .config_write = nb_debug_config_write, +}; void nb_cli_install_default(int node) { @@ -1738,7 +1743,7 @@ void nb_cli_init(struct thread_master *tm) debug_init(&nb_dbg_cbs); - install_node(&nb_debug_node, nb_debug_config_write); + install_node(&nb_debug_node); install_element(ENABLE_NODE, &debug_nb_cmd); install_element(CONFIG_NODE, &debug_nb_cmd); diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp index b195f1aeca..66bf05c1ab 100644 --- a/lib/northbound_grpc.cpp +++ b/lib/northbound_grpc.cpp @@ -545,7 +545,8 @@ class NorthboundImpl final : public frr::Northbound::Service } // Execute callback registered for this XPath. - if (nb_node->cbs.rpc(xpath, input_list, output_list) != NB_OK) { + if (nb_callback_rpc(nb_node, xpath, input_list, output_list) + != NB_OK) { flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s", __func__, xpath); diff --git a/lib/pid_output.c b/lib/pid_output.c index f5f7b1d171..bd1d89a94c 100644 --- a/lib/pid_output.c +++ b/lib/pid_output.c @@ -65,7 +65,7 @@ pid_t pid_output(const char *path) exit(1); } - sprintf(buf, "%d\n", (int)pid); + snprintf(buf, sizeof(buf), "%d\n", (int)pid); pidsize = strlen(buf); if ((tmp = write(fd, buf, pidsize)) != (int)pidsize) flog_err_sys( diff --git a/lib/plist.c b/lib/plist.c index b7a020c6f7..d18d51618a 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -348,14 +348,14 @@ static void prefix_list_delete(struct prefix_list *plist) static struct prefix_list_entry * prefix_list_entry_make(struct prefix *prefix, enum prefix_list_type type, - int64_t seq, int le, int ge, int any) + int64_t seq, int le, int ge, bool any) { struct prefix_list_entry *pentry; pentry = prefix_list_entry_new(); if (any) - pentry->any = 1; + pentry->any = true; prefix_copy(&pentry->prefix, prefix); pentry->type = type; @@ -851,7 +851,7 @@ static int vty_prefix_list_install(struct vty *vty, afi_t afi, const char *name, struct prefix_list_entry *pentry; struct prefix_list_entry *dup; struct prefix p, p_tmp; - int any = 0; + bool any = false; int64_t seqnum = -1; int lenum = 0; int genum = 0; @@ -889,7 +889,7 @@ static int vty_prefix_list_install(struct vty *vty, afi_t afi, const char *name, (struct prefix_ipv4 *)&p); genum = 0; lenum = IPV4_MAX_BITLEN; - any = 1; + any = true; } else ret = str2prefix_ipv4(prefix, (struct prefix_ipv4 *)&p); @@ -908,7 +908,7 @@ static int vty_prefix_list_install(struct vty *vty, afi_t afi, const char *name, ret = str2prefix_ipv6("::/0", (struct prefix_ipv6 *)&p); genum = 0; lenum = IPV6_MAX_BITLEN; - any = 1; + any = true; } else ret = str2prefix_ipv6(prefix, (struct prefix_ipv6 *)&p); @@ -1898,7 +1898,7 @@ int prefix_bgp_orf_set(char *name, afi_t afi, struct orf_prefix *orfp, if (set) { pentry = prefix_list_entry_make( &orfp->p, (permit ? PREFIX_PERMIT : PREFIX_DENY), - orfp->seq, orfp->le, orfp->ge, 0); + orfp->seq, orfp->le, orfp->ge, false); if (prefix_entry_dup_check(plist, pentry)) { prefix_list_entry_free(pentry); @@ -1961,10 +1961,9 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name, char buf_a[BUFSIZ]; char buf_b[BUFSIZ]; - sprintf(buf_a, "%s/%d", - inet_ntop(p->family, p->u.val, buf_b, - BUFSIZ), - p->prefixlen); + snprintf(buf_a, sizeof(buf_a), "%s/%d", + inet_ntop(p->family, p->u.val, buf_b, BUFSIZ), + p->prefixlen); json_object_int_add(json_list, "seq", pentry->seq); json_object_string_add(json_list, "seqPrefixListType", @@ -2044,10 +2043,14 @@ static void prefix_list_reset_afi(afi_t afi, int orf) } +static int config_write_prefix_ipv4(struct vty *vty); /* Prefix-list node. */ -static struct cmd_node prefix_node = {PREFIX_NODE, - "", /* Prefix list has no interface. */ - 1}; +static struct cmd_node prefix_node = { + .name = "ipv4 prefix list", + .node = PREFIX_NODE, + .prompt = "", + .config_write = config_write_prefix_ipv4, +}; static int config_write_prefix_ipv4(struct vty *vty) { @@ -2085,7 +2088,7 @@ static const struct cmd_variable_handler plist_var_handlers[] = { static void prefix_list_init_ipv4(void) { - install_node(&prefix_node, config_write_prefix_ipv4); + install_node(&prefix_node); install_element(CONFIG_NODE, &ip_prefix_list_cmd); install_element(CONFIG_NODE, &no_ip_prefix_list_cmd); @@ -2107,10 +2110,14 @@ static void prefix_list_init_ipv4(void) install_element(ENABLE_NODE, &clear_ip_prefix_list_cmd); } +static int config_write_prefix_ipv6(struct vty *vty); /* Prefix-list node. */ static struct cmd_node prefix_ipv6_node = { - PREFIX_IPV6_NODE, "", /* Prefix list has no interface. */ - 1}; + .name = "ipv6 prefix list", + .node = PREFIX_IPV6_NODE, + .prompt = "", + .config_write = config_write_prefix_ipv6, +}; static int config_write_prefix_ipv6(struct vty *vty) { @@ -2119,7 +2126,7 @@ static int config_write_prefix_ipv6(struct vty *vty) static void prefix_list_init_ipv6(void) { - install_node(&prefix_ipv6_node, config_write_prefix_ipv6); + install_node(&prefix_ipv6_node); install_element(CONFIG_NODE, &ipv6_prefix_list_cmd); install_element(CONFIG_NODE, &no_ipv6_prefix_list_cmd); diff --git a/lib/plist_int.h b/lib/plist_int.h index 443b0c614d..ec8bbe1315 100644 --- a/lib/plist_int.h +++ b/lib/plist_int.h @@ -59,7 +59,7 @@ struct prefix_list_entry { enum prefix_list_type type; - int any; + bool any; struct prefix prefix; unsigned long refcnt; diff --git a/lib/printfrr.h b/lib/printfrr.h index 7d9e288655..a775e1517b 100644 --- a/lib/printfrr.h +++ b/lib/printfrr.h @@ -24,6 +24,10 @@ #include "compiler.h" #include "memory.h" +#ifdef __cplusplus +extern "C" { +#endif + struct fbuf { char *buf; char *pos; @@ -156,4 +160,8 @@ void printfrr_ext_reg(const struct printfrr_ext *); } \ /* end */ +#ifdef __cplusplus +} +#endif + #endif diff --git a/lib/ptm_lib.c b/lib/ptm_lib.c index b66ae221cf..e00dd54290 100644 --- a/lib/ptm_lib.c +++ b/lib/ptm_lib.c @@ -65,10 +65,10 @@ static csv_record_t *_ptm_lib_encode_header(csv_t *csv, csv_record_t *rec, char client_buf[32]; csv_record_t *rec1; - sprintf(msglen_buf, "%4d", msglen); - sprintf(vers_buf, "%4d", version); - sprintf(type_buf, "%4d", type); - sprintf(cmdid_buf, "%4d", cmd_id); + snprintf(msglen_buf, sizeof(msglen_buf), "%4d", msglen); + snprintf(vers_buf, sizeof(vers_buf), "%4d", version); + snprintf(type_buf, sizeof(type_buf), "%4d", type); + snprintf(cmdid_buf, sizeof(cmdid_buf), "%4d", cmd_id); snprintf(client_buf, 17, "%16.16s", client_name); if (rec) { rec1 = csv_encode_record(csv, rec, 5, msglen_buf, vers_buf, diff --git a/lib/pullwr.h b/lib/pullwr.h index 601eac1b79..a0e89e0c30 100644 --- a/lib/pullwr.h +++ b/lib/pullwr.h @@ -26,6 +26,10 @@ #include "thread.h" #include "stream.h" +#ifdef __cplusplus +extern "C" { +#endif + struct pullwr; /* This is a "pull-driven" write event handler. Instead of having some buffer @@ -107,4 +111,8 @@ static inline void pullwr_write_stream(struct pullwr *pullwr, extern void pullwr_stats(struct pullwr *pullwr, uint64_t *total_written, size_t *pending, size_t *kernel_pending); +#ifdef __cplusplus +} +#endif + #endif /* _WRITEPOLL_H */ diff --git a/lib/qobj.c b/lib/qobj.c index 1e48b541dc..cb3254cbe9 100644 --- a/lib/qobj.c +++ b/lib/qobj.c @@ -26,6 +26,7 @@ #include "log.h" #include "qobj.h" #include "jhash.h" +#include "network.h" static uint32_t qobj_hash(const struct qobj_node *node) { @@ -53,8 +54,8 @@ void qobj_reg(struct qobj_node *node, const struct qobj_nodetype *type) node->type = type; pthread_rwlock_wrlock(&nodes_lock); do { - node->nid = (uint64_t)random(); - node->nid ^= (uint64_t)random() << 32; + node->nid = (uint64_t)frr_weak_random(); + node->nid ^= (uint64_t)frr_weak_random() << 32; } while (!node->nid || qobj_nodes_find(&nodes, node)); qobj_nodes_add(&nodes, node); pthread_rwlock_unlock(&nodes_lock); diff --git a/lib/resolver.c b/lib/resolver.c index 1be47bd6e1..e5caadb2d0 100644 --- a/lib/resolver.c +++ b/lib/resolver.c @@ -245,7 +245,13 @@ DEFUN(debug_resolver, return CMD_SUCCESS; } -static struct cmd_node resolver_debug_node = {RESOLVER_DEBUG_NODE, "", 1}; +static int resolver_config_write_debug(struct vty *vty); +static struct cmd_node resolver_debug_node = { + .name = "resolver debug", + .node = RESOLVER_DEBUG_NODE, + .prompt = "", + .config_write = resolver_config_write_debug, +}; static int resolver_config_write_debug(struct vty *vty) { @@ -274,7 +280,7 @@ void resolver_init(struct thread_master *tm) ARES_OPT_SOCK_STATE_CB | ARES_OPT_TIMEOUT | ARES_OPT_TRIES); - install_node(&resolver_debug_node, resolver_config_write_debug); + install_node(&resolver_debug_node); install_element(CONFIG_NODE, &debug_resolver_cmd); install_element(ENABLE_NODE, &debug_resolver_cmd); } diff --git a/lib/resolver.h b/lib/resolver.h index 59bf0d0f55..5f922dcb57 100644 --- a/lib/resolver.h +++ b/lib/resolver.h @@ -13,6 +13,10 @@ #include "thread.h" #include "sockunion.h" +#ifdef __cplusplus +extern "C" { +#endif + struct resolver_query { void (*callback)(struct resolver_query *, const char *errstr, int n, union sockunion *); @@ -28,4 +32,8 @@ void resolver_resolve(struct resolver_query *query, int af, const char *, int, union sockunion *)); +#ifdef __cplusplus +} +#endif + #endif /* _FRR_RESOLVER_H */ diff --git a/lib/routemap.c b/lib/routemap.c index e2baa36f24..210512212d 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -3015,7 +3015,13 @@ DEFUN (no_debug_rmap, } /* Debug node. */ -static struct cmd_node rmap_debug_node = {RMAP_DEBUG_NODE, "", 1}; +static int rmap_config_write_debug(struct vty *vty); +static struct cmd_node rmap_debug_node = { + .name = "route-map debug", + .node = RMAP_DEBUG_NODE, + .prompt = "", + .config_write = rmap_config_write_debug, +}; /* Configuration write function. */ static int rmap_config_write_debug(struct vty *vty) @@ -3242,7 +3248,7 @@ void route_map_init(void) route_map_cli_init(); /* Install route map top node. */ - install_node(&rmap_debug_node, rmap_config_write_debug); + install_node(&rmap_debug_node); /* Install route map commands. */ install_element(CONFIG_NODE, &debug_rmap_cmd); diff --git a/lib/routemap.h b/lib/routemap.h index e8cab64b47..62195b8349 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -681,10 +681,8 @@ struct routemap_hook_context { TAILQ_ENTRY(routemap_hook_context) rhc_entry; }; -int lib_route_map_entry_match_destroy(enum nb_event event, - const struct lyd_node *dnode); -int lib_route_map_entry_set_destroy(enum nb_event event, - const struct lyd_node *dnode); +int lib_route_map_entry_match_destroy(struct nb_cb_destroy_args *args); +int lib_route_map_entry_set_destroy(struct nb_cb_destroy_args *args); struct routemap_hook_context * routemap_hook_context_insert(struct route_map_index *rmi); diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index 41e8cacd81..2c45f09751 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -1064,7 +1064,14 @@ static int route_map_config_write(struct vty *vty) } /* Route map node structure. */ -static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# ", 1}; +static int route_map_config_write(struct vty *vty); +static struct cmd_node rmap_node = { + .name = "routemap", + .node = RMAP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-route-map)# ", + .config_write = route_map_config_write, +}; static void rmap_autocomplete(vector comps, struct cmd_token *token) { @@ -1087,7 +1094,7 @@ void route_map_cli_init(void) cmd_variable_handler_register(rmap_var_handlers); /* CLI commands. */ - install_node(&rmap_node, route_map_config_write); + install_node(&rmap_node); install_default(RMAP_NODE); install_element(CONFIG_NODE, &route_map_cmd); install_element(CONFIG_NODE, &no_route_map_cmd); diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c index dd4cbd7d99..f500a6c408 100644 --- a/lib/routemap_northbound.c +++ b/lib/routemap_northbound.c @@ -33,16 +33,15 @@ * lib_route_map_entry_set_destroy: unset `set` commands. * lib_route_map_entry_match_destroy: unset `match` commands. */ -int lib_route_map_entry_match_destroy(enum nb_event event, - const struct lyd_node *dnode) +int lib_route_map_entry_match_destroy(struct nb_cb_destroy_args *args) { struct routemap_hook_context *rhc; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rhc = nb_running_get_entry(dnode, NULL, true); + rhc = nb_running_get_entry(args->dnode, NULL, true); if (rhc->rhc_mhook == NULL) return NB_OK; @@ -54,16 +53,15 @@ int lib_route_map_entry_match_destroy(enum nb_event event, return NB_OK; } -int lib_route_map_entry_set_destroy(enum nb_event event, - const struct lyd_node *dnode) +int lib_route_map_entry_set_destroy(struct nb_cb_destroy_args *args) { struct routemap_hook_context *rhc; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rhc = nb_running_get_entry(dnode, NULL, true); + rhc = nb_running_get_entry(args->dnode, NULL, true); if (rhc->rhc_shook == NULL) return NB_OK; @@ -89,8 +87,7 @@ routemap_hook_context_insert(struct route_map_index *rmi) return rhc; } -void -routemap_hook_context_free(struct routemap_hook_context *rhc) +void routemap_hook_context_free(struct routemap_hook_context *rhc) { struct route_map_index *rmi = rhc->rhc_rmi; @@ -101,42 +98,39 @@ routemap_hook_context_free(struct routemap_hook_context *rhc) /* * XPath: /frr-route-map:lib/route-map */ -static int lib_route_map_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_create(struct nb_cb_create_args *args) { struct route_map *rm; const char *rm_name; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rm_name = yang_dnode_get_string(dnode, "./name"); + rm_name = yang_dnode_get_string(args->dnode, "./name"); rm = route_map_get(rm_name); - nb_running_set_entry(dnode, rm); + nb_running_set_entry(args->dnode, rm); break; } return NB_OK; } -static int lib_route_map_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_route_map_destroy(struct nb_cb_destroy_args *args) { struct route_map *rm; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rm = nb_running_unset_entry(dnode); + rm = nb_running_unset_entry(args->dnode); route_map_delete(rm); break; } @@ -147,48 +141,45 @@ static int lib_route_map_destroy(enum nb_event event, /* * XPath: /frr-route-map:lib/route-map/entry */ -static int lib_route_map_entry_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_create(struct nb_cb_create_args *args) { struct route_map_index *rmi; struct route_map *rm; uint16_t sequence; int action; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - sequence = yang_dnode_get_uint16(dnode, "./sequence"); - action = yang_dnode_get_enum(dnode, "./action") == 0 + sequence = yang_dnode_get_uint16(args->dnode, "./sequence"); + action = yang_dnode_get_enum(args->dnode, "./action") == 0 ? RMAP_PERMIT : RMAP_DENY; - rm = nb_running_get_entry(dnode, NULL, true); + rm = nb_running_get_entry(args->dnode, NULL, true); rmi = route_map_index_get(rm, action, sequence); - nb_running_set_entry(dnode, rmi); + nb_running_set_entry(args->dnode, rmi); break; } return NB_OK; } -static int lib_route_map_entry_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_route_map_entry_destroy(struct nb_cb_destroy_args *args) { struct route_map_index *rmi; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rmi = nb_running_unset_entry(dnode); + rmi = nb_running_unset_entry(args->dnode); route_map_index_delete(rmi, 1); break; } @@ -199,49 +190,48 @@ static int lib_route_map_entry_destroy(enum nb_event event, /* * XPath: /frr-route-map:lib/route-map/entry/description */ -static int lib_route_map_entry_description_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int +lib_route_map_entry_description_modify(struct nb_cb_modify_args *args) { struct route_map_index *rmi; const char *description; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* NOTHING */ break; case NB_EV_PREPARE: - description = yang_dnode_get_string(dnode, NULL); - resource->ptr = XSTRDUP(MTYPE_TMP, description); - if (resource->ptr == NULL) + description = yang_dnode_get_string(args->dnode, NULL); + args->resource->ptr = XSTRDUP(MTYPE_TMP, description); + if (args->resource->ptr == NULL) return NB_ERR_RESOURCE; break; case NB_EV_ABORT: - XFREE(MTYPE_TMP, resource->ptr); + XFREE(MTYPE_TMP, args->resource->ptr); break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); + rmi = nb_running_get_entry(args->dnode, NULL, true); XFREE(MTYPE_TMP, rmi->description); - rmi->description = resource->ptr; + rmi->description = args->resource->ptr; break; } return NB_OK; } -static int lib_route_map_entry_description_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int +lib_route_map_entry_description_destroy(struct nb_cb_destroy_args *args) { struct route_map_index *rmi; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); + rmi = nb_running_get_entry(args->dnode, NULL, true); XFREE(MTYPE_TMP, rmi->description); break; } @@ -252,21 +242,19 @@ static int lib_route_map_entry_description_destroy(enum nb_event event, /* * XPath: /frr-route-map:lib/route-map/entry/action */ -static int lib_route_map_entry_action_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_action_modify(struct nb_cb_modify_args *args) { struct route_map_index *rmi; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); - rmi->type = yang_dnode_get_enum(dnode, NULL); + rmi = nb_running_get_entry(args->dnode, NULL, true); + rmi->type = yang_dnode_get_enum(args->dnode, NULL); /* TODO: notify? */ break; } @@ -277,17 +265,15 @@ static int lib_route_map_entry_action_modify(enum nb_event event, /* * XPath: /frr-route-map:lib/route-map/entry/call */ -static int lib_route_map_entry_call_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_call_modify(struct nb_cb_modify_args *args) { struct route_map_index *rmi; const char *rm_name, *rmn_name; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - rm_name = yang_dnode_get_string(dnode, "../../name"); - rmn_name = yang_dnode_get_string(dnode, NULL); + rm_name = yang_dnode_get_string(args->dnode, "../../name"); + rmn_name = yang_dnode_get_string(args->dnode, NULL); /* Don't allow to jump to the same route map instance. */ if (strcmp(rm_name, rmn_name) == 0) return NB_ERR_VALIDATION; @@ -295,20 +281,20 @@ static int lib_route_map_entry_call_modify(enum nb_event event, /* TODO: detect circular route map sequences. */ break; case NB_EV_PREPARE: - rmn_name = yang_dnode_get_string(dnode, NULL); - resource->ptr = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmn_name); + rmn_name = yang_dnode_get_string(args->dnode, NULL); + args->resource->ptr = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmn_name); break; case NB_EV_ABORT: - XFREE(MTYPE_ROUTE_MAP_NAME, resource->ptr); + XFREE(MTYPE_ROUTE_MAP_NAME, args->resource->ptr); break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); + rmi = nb_running_get_entry(args->dnode, NULL, true); if (rmi->nextrm) { route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED, rmi->nextrm, rmi->map->name); XFREE(MTYPE_ROUTE_MAP_NAME, rmi->nextrm); } - rmi->nextrm = resource->ptr; + rmi->nextrm = args->resource->ptr; route_map_upd8_dependency(RMAP_EVENT_CALL_ADDED, rmi->nextrm, rmi->map->name); break; @@ -317,19 +303,18 @@ static int lib_route_map_entry_call_modify(enum nb_event event, return NB_OK; } -static int lib_route_map_entry_call_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_route_map_entry_call_destroy(struct nb_cb_destroy_args *args) { struct route_map_index *rmi; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); + rmi = nb_running_get_entry(args->dnode, NULL, true); route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED, rmi->nextrm, rmi->map->name); XFREE(MTYPE_ROUTE_MAP_NAME, rmi->nextrm); @@ -343,24 +328,24 @@ static int lib_route_map_entry_call_destroy(enum nb_event event, /* * XPath: /frr-route-map:lib/route-map/entry/exit-policy */ -static int lib_route_map_entry_exit_policy_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int +lib_route_map_entry_exit_policy_modify(struct nb_cb_modify_args *args) { struct route_map_index *rmi; int rm_action; int policy; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - policy = yang_dnode_get_enum(dnode, NULL); + policy = yang_dnode_get_enum(args->dnode, NULL); switch (policy) { case 0: /* permit-or-deny */ break; case 1: /* next */ /* FALLTHROUGH */ case 2: /* goto */ - rm_action = yang_dnode_get_enum(dnode, "../action"); + rm_action = + yang_dnode_get_enum(args->dnode, "../action"); if (rm_action == 1 /* deny */) { /* * On deny it is not possible to 'goto' @@ -375,8 +360,8 @@ static int lib_route_map_entry_exit_policy_modify(enum nb_event event, case NB_EV_ABORT: break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); - policy = yang_dnode_get_enum(dnode, NULL); + rmi = nb_running_get_entry(args->dnode, NULL, true); + policy = yang_dnode_get_enum(args->dnode, NULL); switch (policy) { case 0: /* permit-or-deny */ @@ -398,18 +383,16 @@ static int lib_route_map_entry_exit_policy_modify(enum nb_event event, /* * XPath: /frr-route-map:lib/route-map/entry/goto-value */ -static int lib_route_map_entry_goto_value_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_goto_value_modify(struct nb_cb_modify_args *args) { struct route_map_index *rmi; uint16_t rmi_index; uint16_t rmi_next; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: - rmi_index = yang_dnode_get_uint16(dnode, "../sequence"); - rmi_next = yang_dnode_get_uint16(dnode, NULL); + rmi_index = yang_dnode_get_uint16(args->dnode, "../sequence"); + rmi_next = yang_dnode_get_uint16(args->dnode, NULL); if (rmi_next <= rmi_index) { /* Can't jump backwards on a route map. */ return NB_ERR_VALIDATION; @@ -420,27 +403,27 @@ static int lib_route_map_entry_goto_value_modify(enum nb_event event, /* NOTHING */ break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); - rmi->nextpref = yang_dnode_get_uint16(dnode, NULL); + rmi = nb_running_get_entry(args->dnode, NULL, true); + rmi->nextpref = yang_dnode_get_uint16(args->dnode, NULL); break; } return NB_OK; } -static int lib_route_map_entry_goto_value_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int +lib_route_map_entry_goto_value_destroy(struct nb_cb_destroy_args *args) { struct route_map_index *rmi; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); + rmi = nb_running_get_entry(args->dnode, NULL, true); rmi->nextpref = 0; break; } @@ -452,23 +435,21 @@ static int lib_route_map_entry_goto_value_destroy(enum nb_event event, * XPath: /frr-route-map:lib/route-map/entry/match-condition */ static int -lib_route_map_entry_match_condition_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_route_map_entry_match_condition_create(struct nb_cb_create_args *args) { struct routemap_hook_context *rhc; struct route_map_index *rmi; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: case NB_EV_PREPARE: case NB_EV_ABORT: /* NOTHING */ break; case NB_EV_APPLY: - rmi = nb_running_get_entry(dnode, NULL, true); + rmi = nb_running_get_entry(args->dnode, NULL, true); rhc = routemap_hook_context_insert(rmi); - nb_running_set_entry(dnode, rhc); + nb_running_set_entry(args->dnode, rhc); break; } @@ -476,17 +457,16 @@ lib_route_map_entry_match_condition_create(enum nb_event event, } static int -lib_route_map_entry_match_condition_destroy(enum nb_event event, - const struct lyd_node *dnode) +lib_route_map_entry_match_condition_destroy(struct nb_cb_destroy_args *args) { struct routemap_hook_context *rhc; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rv = lib_route_map_entry_match_destroy(event, dnode); - rhc = nb_running_unset_entry(dnode); + rv = lib_route_map_entry_match_destroy(args); + rhc = nb_running_unset_entry(args->dnode); routemap_hook_context_free(rhc); return rv; @@ -496,14 +476,13 @@ lib_route_map_entry_match_condition_destroy(enum nb_event event, * XPath: /frr-route-map:lib/route-map/entry/match-condition/interface */ static int lib_route_map_entry_match_condition_interface_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *ifname; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook function. */ @@ -511,8 +490,8 @@ static int lib_route_map_entry_match_condition_interface_modify( return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_mhook = rmap_match_set_hook.no_match_interface; @@ -531,30 +510,29 @@ static int lib_route_map_entry_match_condition_interface_modify( } static int lib_route_map_entry_match_condition_interface_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_match_destroy(event, dnode); + return lib_route_map_entry_match_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/match-condition/access-list-num */ static int lib_route_map_entry_match_condition_access_list_num_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *acl; int condition, rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook function. */ rv = CMD_SUCCESS; - acl = yang_dnode_get_string(dnode, NULL); - rhc = nb_running_get_entry(dnode, NULL, true); - condition = yang_dnode_get_enum(dnode, "../condition"); + acl = yang_dnode_get_string(args->dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + condition = yang_dnode_get_enum(args->dnode, "../condition"); switch (condition) { case 1: /* ipv4-address-list */ if (rmap_match_set_hook.match_ip_address == NULL) @@ -586,9 +564,9 @@ static int lib_route_map_entry_match_condition_access_list_num_modify( } static int lib_route_map_entry_match_condition_access_list_num_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_match_destroy(event, dnode); + return lib_route_map_entry_match_destroy(args); } /* @@ -596,39 +574,36 @@ static int lib_route_map_entry_match_condition_access_list_num_destroy( * /frr-route-map:lib/route-map/entry/match-condition/access-list-num-extended */ static int lib_route_map_entry_match_condition_access_list_num_extended_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return lib_route_map_entry_match_condition_access_list_num_modify( - event, dnode, resource); + return lib_route_map_entry_match_condition_access_list_num_modify(args); } static int lib_route_map_entry_match_condition_access_list_num_extended_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { return lib_route_map_entry_match_condition_access_list_num_destroy( - event, dnode); + args); } /* * XPath: /frr-route-map:lib/route-map/entry/match-condition/list-name */ static int lib_route_map_entry_match_condition_list_name_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *acl; int condition; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook installation, otherwise we can just stop. */ - acl = yang_dnode_get_string(dnode, NULL); - rhc = nb_running_get_entry(dnode, NULL, true); - condition = yang_dnode_get_enum(dnode, "../condition"); + acl = yang_dnode_get_string(args->dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + condition = yang_dnode_get_enum(args->dnode, "../condition"); switch (condition) { case 1: /* ipv4-address-list */ if (rmap_match_set_hook.match_ip_address == NULL) @@ -706,23 +681,22 @@ static int lib_route_map_entry_match_condition_list_name_modify( } static int lib_route_map_entry_match_condition_list_name_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_match_destroy(event, dnode); + return lib_route_map_entry_match_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/match-condition/ipv4-next-hop-type */ static int lib_route_map_entry_match_condition_ipv4_next_hop_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *type; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook function. */ @@ -730,8 +704,8 @@ static int lib_route_map_entry_match_condition_ipv4_next_hop_type_modify( return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop_type; @@ -750,23 +724,22 @@ static int lib_route_map_entry_match_condition_ipv4_next_hop_type_modify( } static int lib_route_map_entry_match_condition_ipv4_next_hop_type_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_match_destroy(event, dnode); + return lib_route_map_entry_match_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/match-condition/ipv6-next-hop-type */ static int lib_route_map_entry_match_condition_ipv6_next_hop_type_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *type; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook function. */ @@ -774,8 +747,8 @@ static int lib_route_map_entry_match_condition_ipv6_next_hop_type_modify( return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_mhook = rmap_match_set_hook.no_match_ipv6_next_hop_type; @@ -794,24 +767,22 @@ static int lib_route_map_entry_match_condition_ipv6_next_hop_type_modify( } static int lib_route_map_entry_match_condition_ipv6_next_hop_type_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_match_destroy(event, dnode); + return lib_route_map_entry_match_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/match-condition/metric */ -static int -lib_route_map_entry_match_condition_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_match_condition_metric_modify( + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *type; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook function. */ @@ -819,8 +790,8 @@ lib_route_map_entry_match_condition_metric_modify(enum nb_event event, return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_mhook = rmap_match_set_hook.no_match_metric; @@ -837,26 +808,23 @@ lib_route_map_entry_match_condition_metric_modify(enum nb_event event, return NB_OK; } -static int -lib_route_map_entry_match_condition_metric_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_route_map_entry_match_condition_metric_destroy( + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_match_destroy(event, dnode); + return lib_route_map_entry_match_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/match-condition/tag */ static int -lib_route_map_entry_match_condition_tag_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_route_map_entry_match_condition_tag_modify(struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *tag; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook function. */ @@ -864,8 +832,8 @@ lib_route_map_entry_match_condition_tag_modify(enum nb_event event, return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - tag = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + tag = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_mhook = rmap_match_set_hook.no_match_tag; @@ -883,34 +851,30 @@ lib_route_map_entry_match_condition_tag_modify(enum nb_event event, } static int -lib_route_map_entry_match_condition_tag_destroy(enum nb_event event, - const struct lyd_node *dnode) +lib_route_map_entry_match_condition_tag_destroy(struct nb_cb_destroy_args *args) { - return lib_route_map_entry_match_destroy(event, dnode); + return lib_route_map_entry_match_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action */ -static int lib_route_map_entry_set_action_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_set_action_create(struct nb_cb_create_args *args) { - return lib_route_map_entry_match_condition_create(event, dnode, - resource); + return lib_route_map_entry_match_condition_create(args); } -static int lib_route_map_entry_set_action_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int +lib_route_map_entry_set_action_destroy(struct nb_cb_destroy_args *args) { struct routemap_hook_context *rhc; int rv; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rv = lib_route_map_entry_set_destroy(event, dnode); - rhc = nb_running_unset_entry(dnode); + rv = lib_route_map_entry_set_destroy(args); + rhc = nb_running_unset_entry(args->dnode); routemap_hook_context_free(rhc); return rv; @@ -919,24 +883,22 @@ static int lib_route_map_entry_set_action_destroy(enum nb_event event, /* * XPath: /frr-route-map:lib/route-map/entry/set-action/ipv4-address */ -static int -lib_route_map_entry_set_action_ipv4_address_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_set_action_ipv4_address_modify( + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *address; struct in_addr ia; int rv; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* * NOTE: validate if 'action' is 'ipv4-next-hop', * currently it is not necessary because this is the * only implemented action. */ - yang_dnode_get_ipv4(&ia, dnode, NULL); + yang_dnode_get_ipv4(&ia, args->dnode, NULL); if (ia.s_addr == INADDR_ANY || IPV4_CLASS_DE(ntohl(ia.s_addr))) return NB_ERR_VALIDATION; /* FALLTHROUGH */ @@ -952,8 +914,8 @@ lib_route_map_entry_set_action_ipv4_address_modify(enum nb_event event, return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - address = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + address = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_shook = rmap_match_set_hook.no_set_ip_nexthop; @@ -970,25 +932,23 @@ lib_route_map_entry_set_action_ipv4_address_modify(enum nb_event event, } static int lib_route_map_entry_set_action_ipv4_address_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_destroy(event, dnode); + return lib_route_map_entry_set_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action/ipv6-address */ -static int -lib_route_map_entry_set_action_ipv6_address_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_route_map_entry_set_action_ipv6_address_modify( + struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *address; struct in6_addr i6a; int rv; - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: /* * NOTE: validate if 'action' is 'ipv6-next-hop', @@ -996,7 +956,7 @@ lib_route_map_entry_set_action_ipv6_address_modify(enum nb_event event, * only implemented action. Other actions might have * different validations. */ - yang_dnode_get_ipv6(&i6a, dnode, NULL); + yang_dnode_get_ipv6(&i6a, args->dnode, NULL); if (!IN6_IS_ADDR_LINKLOCAL(&i6a)) return NB_ERR_VALIDATION; /* FALLTHROUGH */ @@ -1012,8 +972,8 @@ lib_route_map_entry_set_action_ipv6_address_modify(enum nb_event event, return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - address = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + address = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_shook = rmap_match_set_hook.no_set_ipv6_nexthop_local; @@ -1030,9 +990,9 @@ lib_route_map_entry_set_action_ipv6_address_modify(enum nb_event event, } static int lib_route_map_entry_set_action_ipv6_address_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_destroy(event, dnode); + return lib_route_map_entry_set_destroy(args); } /* @@ -1074,111 +1034,105 @@ static int set_action_modify(enum nb_event event, const struct lyd_node *dnode, } static int -lib_route_map_entry_set_action_value_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_route_map_entry_set_action_value_modify(struct nb_cb_modify_args *args) { - const char *metric = yang_dnode_get_string(dnode, NULL); + const char *metric = yang_dnode_get_string(args->dnode, NULL); - return set_action_modify(event, dnode, resource, metric); + return set_action_modify(args->event, args->dnode, args->resource, + metric); } static int -lib_route_map_entry_set_action_value_destroy(enum nb_event event, - const struct lyd_node *dnode) +lib_route_map_entry_set_action_value_destroy(struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_destroy(event, dnode); + return lib_route_map_entry_set_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action/add-metric */ static int -lib_route_map_entry_set_action_add_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_route_map_entry_set_action_add_metric_modify(struct nb_cb_modify_args *args) { - return set_action_modify(event, dnode, resource, "+metric"); + return set_action_modify(args->event, args->dnode, args->resource, + "+metric"); } -static int -lib_route_map_entry_set_action_add_metric_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int lib_route_map_entry_set_action_add_metric_destroy( + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_action_value_destroy(event, dnode); + return lib_route_map_entry_set_action_value_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action/subtract-metric */ static int lib_route_map_entry_set_action_subtract_metric_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return set_action_modify(event, dnode, resource, "-metric"); + return set_action_modify(args->event, args->dnode, args->resource, + "-metric"); } static int lib_route_map_entry_set_action_subtract_metric_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_action_value_destroy(event, dnode); + return lib_route_map_entry_set_action_value_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action/use-round-trip-time */ static int lib_route_map_entry_set_action_use_round_trip_time_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return set_action_modify(event, dnode, resource, "rtt"); + return set_action_modify(args->event, args->dnode, args->resource, + "rtt"); } static int lib_route_map_entry_set_action_use_round_trip_time_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_action_value_destroy(event, dnode); + return lib_route_map_entry_set_action_value_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action/add-round-trip-time */ static int lib_route_map_entry_set_action_add_round_trip_time_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return set_action_modify(event, dnode, resource, "+rtt"); + return set_action_modify(args->event, args->dnode, args->resource, + "+rtt"); } static int lib_route_map_entry_set_action_add_round_trip_time_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_action_value_destroy(event, dnode); + return lib_route_map_entry_set_action_value_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action/subtract-round-trip-time */ static int lib_route_map_entry_set_action_subtract_round_trip_time_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - return set_action_modify(event, dnode, resource, "-rtt"); + return set_action_modify(args->event, args->dnode, args->resource, + "-rtt"); } static int lib_route_map_entry_set_action_subtract_round_trip_time_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_action_value_destroy(event, dnode); + return lib_route_map_entry_set_action_value_destroy(args); } /* * XPath: /frr-route-map:lib/route-map/entry/set-action/tag */ static int -lib_route_map_entry_set_action_tag_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_route_map_entry_set_action_tag_modify(struct nb_cb_modify_args *args) { struct routemap_hook_context *rhc; const char *tag; @@ -1189,7 +1143,7 @@ lib_route_map_entry_set_action_tag_modify(enum nb_event event, * necessary because this is the only implemented action. Other * actions might have different validations. */ - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Check for hook function. */ @@ -1197,8 +1151,8 @@ lib_route_map_entry_set_action_tag_modify(enum nb_event event, return NB_OK; /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - tag = yang_dnode_get_string(dnode, NULL); + rhc = nb_running_get_entry(args->dnode, NULL, true); + tag = yang_dnode_get_string(args->dnode, NULL); /* Set destroy information. */ rhc->rhc_shook = rmap_match_set_hook.no_set_tag; @@ -1214,10 +1168,9 @@ lib_route_map_entry_set_action_tag_modify(enum nb_event event, } static int -lib_route_map_entry_set_action_tag_destroy(enum nb_event event, - const struct lyd_node *dnode) +lib_route_map_entry_set_action_tag_destroy(struct nb_cb_destroy_args *args) { - return lib_route_map_entry_set_destroy(event, dnode); + return lib_route_map_entry_set_destroy(args); } /* clang-format off */ diff --git a/lib/seqlock.h b/lib/seqlock.h index b551e3ffc4..bfbf97890e 100644 --- a/lib/seqlock.h +++ b/lib/seqlock.h @@ -27,6 +27,10 @@ #include <pthread.h> #include "frratomic.h" +#ifdef __cplusplus +extern "C" { +#endif + /* * this locking primitive is intended to use in a 1:N setup. * @@ -135,4 +139,8 @@ extern void seqlock_release(struct seqlock *sqlo); * anything other than reading RCU items was done */ +#ifdef __cplusplus +} +#endif + #endif /* _SEQLOCK_H */ diff --git a/lib/skiplist.c b/lib/skiplist.c index 790bd71c38..2bef18f525 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -61,6 +61,7 @@ #include "vty.h" #include "skiplist.h" #include "lib_errors.h" +#include "network.h" DEFINE_MTYPE_STATIC(LIB, SKIP_LIST, "Skip List") DEFINE_MTYPE_STATIC(LIB, SKIP_LIST_NODE, "Skip Node") @@ -95,7 +96,7 @@ static int randomLevel(void) do { if (randomsLeft <= 0) { - randomBits = random(); + randomBits = frr_weak_random(); randomsLeft = BitsInRandom / 2; } b = randomBits & 3; diff --git a/lib/srv6.c b/lib/srv6.c index be340f13f5..287bf56089 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "zebra.h" + #include "srv6.h" #include "log.h" diff --git a/lib/subdir.am b/lib/subdir.am index 4f62eb2264..2f8cbe5d52 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -45,6 +45,7 @@ lib_libfrr_la_SOURCES = \ lib/libfrr.c \ lib/linklist.c \ lib/log.c \ + lib/log_filter.c \ lib/log_vty.c \ lib/md5.c \ lib/memory.c \ @@ -100,6 +101,8 @@ lib_libfrr_la_SOURCES = \ lib/yang_translator.c \ lib/yang_wrappers.c \ lib/zclient.c \ + lib/zlog.c \ + lib/zlog_targets.c \ lib/printf/printf-pos.c \ lib/printf/vfprintf.c \ lib/printf/glue.c \ @@ -110,46 +113,48 @@ nodist_lib_libfrr_la_SOURCES = \ yang/frr-interface.yang.c \ yang/frr-route-map.yang.c \ yang/frr-route-types.yang.c \ + yang/frr-vrf.yang.c \ + yang/frr-routing.yang.c \ yang/ietf/ietf-routing-types.yang.c \ + yang/ietf/ietf-interfaces.yang.c \ yang/frr-module-translator.yang.c \ + yang/frr-nexthop.yang.c \ + yang/frr-igmp.yang.c \ + yang/frr-pim.yang.c \ + yang/frr-pim-rp.yang.c \ # end vtysh_scan += \ - $(top_srcdir)/lib/distribute.c \ - $(top_srcdir)/lib/filter.c \ - $(top_srcdir)/lib/if.c \ - $(top_srcdir)/lib/if_rmap.c \ - $(top_srcdir)/lib/keychain.c \ - $(top_srcdir)/lib/lib_vty.c \ - $(top_srcdir)/lib/nexthop_group.c \ - $(top_srcdir)/lib/plist.c \ - $(top_srcdir)/lib/routemap.c \ - $(top_srcdir)/lib/routemap_cli.c \ - $(top_srcdir)/lib/vrf.c \ - $(top_srcdir)/lib/vty.c \ + lib/distribute.c \ + lib/filter.c \ + lib/if.c \ + lib/if_rmap.c \ + lib/keychain.c \ + lib/lib_vty.c \ + lib/nexthop_group.c \ + lib/plist.c \ + lib/routemap.c \ + lib/routemap_cli.c \ + lib/vrf.c \ + lib/vty.c \ # end # can be loaded as DSO - always include for vtysh -vtysh_scan += $(top_srcdir)/lib/agentx.c +vtysh_scan += lib/agentx.c if SQLITE3 lib_libfrr_la_LIBADD += $(SQLITE3_LIBS) lib_libfrr_la_SOURCES += lib/db.c endif -lib/if_clippy.c: $(CLIPPY_DEPS) -lib/if.lo: lib/if_clippy.c -lib/plist_clippy.c: $(CLIPPY_DEPS) -lib/plist.lo: lib/plist_clippy.c -lib/nexthop_group_clippy.c: $(CLIPPY_DEPS) -lib/nexthop_group.lo: lib/nexthop_group_clippy.c -lib/northbound_cli_clippy.c: $(CLIPPY_DEPS) -lib/northbound_cli.lo: lib/northbound_cli_clippy.c -lib/routemap_cli_clippy.c: $(CLIPPY_DEPS) -lib/routemap_cli.lo: lib/routemap_cli_clippy.c -lib/vty_clippy.c: $(CLIPPY_DEPS) -lib/vty.lo: lib/vty_clippy.c -lib/log_vty_clippy.c: $(CLIPPY_DEPS) -lib/log_vty.lo: lib/log_vty_clippy.c +clippy_scan += \ + lib/if.c \ + lib/log_vty.c \ + lib/nexthop_group.c \ + lib/northbound_cli.c \ + lib/plist.c \ + lib/routemap_cli.c \ + lib/vty.c \ + # end pkginclude_HEADERS += \ lib/agg_table.h \ @@ -254,6 +259,8 @@ pkginclude_HEADERS += \ lib/zassert.h \ lib/zclient.h \ lib/zebra.h \ + lib/zlog.h \ + lib/zlog_targets.h \ lib/pbr.h \ # end @@ -265,7 +272,6 @@ nodist_pkginclude_HEADERS += \ noinst_HEADERS += \ lib/clippy.h \ - lib/log_int.h \ lib/plist_int.h \ lib/printf/printfcommon.h \ lib/printf/printflocal.h \ diff --git a/lib/thread.c b/lib/thread.c index dbf668a699..4d689a9f88 100644 --- a/lib/thread.c +++ b/lib/thread.c @@ -724,6 +724,7 @@ static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize, < 0) // effect a poll (return immediately) timeout = 0; + zlog_tls_buffer_flush(); rcu_read_unlock(); rcu_assert_read_unlocked(); diff --git a/lib/typesafe.c b/lib/typesafe.c index 6635cf7506..a52b55b734 100644 --- a/lib/typesafe.c +++ b/lib/typesafe.c @@ -23,6 +23,7 @@ #include "typesafe.h" #include "memory.h" +#include "network.h" DEFINE_MTYPE_STATIC(LIB, TYPEDHASH_BUCKET, "Typed-hash bucket") DEFINE_MTYPE_STATIC(LIB, SKIPLIST_OFLOW, "Skiplist overflow") @@ -196,7 +197,7 @@ struct sskip_item *typesafe_skiplist_add(struct sskip_head *head, int cmpval; /* level / newlevel are 1-counted here */ - newlevel = __builtin_ctz(random()) + 1; + newlevel = __builtin_ctz(frr_weak_random()) + 1; if (newlevel > SKIPLIST_MAXDEPTH) newlevel = SKIPLIST_MAXDEPTH; diff --git a/lib/version.h.in b/lib/version.h.in index 52c10f7d68..d535d131c8 100644 --- a/lib/version.h.in +++ b/lib/version.h.in @@ -28,6 +28,10 @@ #include "gitversion.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + #ifndef GIT_SUFFIX #define GIT_SUFFIX "" #endif @@ -54,4 +58,8 @@ pid_t pid_output (const char *); +#ifdef __cplusplus +} +#endif + #endif /* _ZEBRA_VERSION_H */ @@ -36,6 +36,8 @@ #include "privs.h" #include "nexthop_group.h" #include "lib_errors.h" +#include "northbound.h" +#include "northbound_cli.h" /* default VRF ID value used when VRF backend is not NETNS */ #define VRF_DEFAULT_INTERNAL 0 @@ -612,6 +614,8 @@ int vrf_handler_create(struct vty *vty, const char *vrfname, struct vrf **vrf) { struct vrf *vrfp; + char xpath_list[XPATH_MAXLEN]; + int ret; if (strlen(vrfname) > VRF_NAMSIZ) { if (vty) @@ -626,13 +630,24 @@ int vrf_handler_create(struct vty *vty, const char *vrfname, return CMD_WARNING_CONFIG_FAILED; } - vrfp = vrf_get(VRF_UNKNOWN, vrfname); - - if (vty) - VTY_PUSH_CONTEXT(VRF_NODE, vrfp); + if (vty) { + snprintf(xpath_list, sizeof(xpath_list), + "/frr-vrf:lib/vrf[name='%s']", vrfname); + + nb_cli_enqueue_change(vty, xpath_list, NB_OP_CREATE, NULL); + ret = nb_cli_apply_changes(vty, xpath_list); + if (ret == CMD_SUCCESS) { + VTY_PUSH_XPATH(VRF_NODE, xpath_list); + vrfp = vrf_lookup_by_name(vrfname); + if (vrfp) + VTY_PUSH_CONTEXT(VRF_NODE, vrfp); + } + } else { + vrfp = vrf_get(VRF_UNKNOWN, vrfname); - if (vrf) - *vrf = vrfp; + if (vrf) + *vrf = vrfp; + } return CMD_SUCCESS; } @@ -735,6 +750,7 @@ DEFUN (no_vrf, "VRF's name\n") { const char *vrfname = argv[2]->arg; + char xpath_list[XPATH_MAXLEN]; struct vrf *vrfp; @@ -750,15 +766,20 @@ DEFUN (no_vrf, return CMD_WARNING_CONFIG_FAILED; } - /* Clear configured flag and invoke delete. */ - UNSET_FLAG(vrfp->status, VRF_CONFIGURED); - vrf_delete(vrfp); + snprintf(xpath_list, sizeof(xpath_list), "/frr-vrf:lib/vrf[name='%s']", + vrfname); - return CMD_SUCCESS; + nb_cli_enqueue_change(vty, xpath_list, NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, xpath_list); } -static struct cmd_node vrf_node = {VRF_NODE, "%s(config-vrf)# ", 1}; +static struct cmd_node vrf_node = { + .name = "vrf", + .node = VRF_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-vrf)# ", +}; DEFUN_NOSH (vrf_netns, vrf_netns_cmd, @@ -848,11 +869,17 @@ static int vrf_write_host(struct vty *vty) return 1; } -static struct cmd_node vrf_debug_node = {VRF_DEBUG_NODE, "", 1}; +static int vrf_write_host(struct vty *vty); +static struct cmd_node vrf_debug_node = { + .name = "vrf debug", + .node = VRF_DEBUG_NODE, + .prompt = "", + .config_write = vrf_write_host, +}; void vrf_install_commands(void) { - install_node(&vrf_debug_node, vrf_write_host); + install_node(&vrf_debug_node); install_element(CONFIG_NODE, &vrf_debug_cmd); install_element(ENABLE_NODE, &vrf_debug_cmd); @@ -865,7 +892,8 @@ void vrf_cmd_init(int (*writefunc)(struct vty *vty), { install_element(CONFIG_NODE, &vrf_cmd); install_element(CONFIG_NODE, &no_vrf_cmd); - install_node(&vrf_node, writefunc); + vrf_node.config_write = writefunc; + install_node(&vrf_node); install_default(VRF_NODE); install_element(VRF_NODE, &vrf_exit_cmd); if (vrf_is_backend_netns() && ns_have_netns()) { @@ -1019,3 +1047,144 @@ vrf_id_t vrf_generate_id(void) return ++vrf_id_local; } + +/* ------- Northbound callbacks ------- */ + +/* + * XPath: /frr-vrf:lib/vrf + */ +static int lib_vrf_create(struct nb_cb_create_args *args) +{ + const char *vrfname; + struct vrf *vrfp; + + vrfname = yang_dnode_get_string(args->dnode, "./name"); + + if (args->event != NB_EV_APPLY) + return NB_OK; + + vrfp = vrf_get(VRF_UNKNOWN, vrfname); + + nb_running_set_entry(args->dnode, vrfp); + + return NB_OK; +} + +static int lib_vrf_destroy(struct nb_cb_destroy_args *args) +{ + struct vrf *vrfp; + + switch (args->event) { + case NB_EV_VALIDATE: + vrfp = nb_running_get_entry(args->dnode, NULL, true); + if (CHECK_FLAG(vrfp->status, VRF_ACTIVE)) { + zlog_debug("%s Only inactive VRFs can be deleted", + __func__); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + vrfp = nb_running_unset_entry(args->dnode); + + /* Clear configured flag and invoke delete. */ + UNSET_FLAG(vrfp->status, VRF_CONFIGURED); + vrf_delete(vrfp); + break; + } + + return NB_OK; +} + +static const void *lib_vrf_get_next(struct nb_cb_get_next_args *args) +{ + struct vrf *vrfp = (struct vrf *)args->list_entry; + + if (args->list_entry == NULL) { + vrfp = RB_MIN(vrf_name_head, &vrfs_by_name); + } else { + vrfp = RB_NEXT(vrf_name_head, vrfp); + } + + return vrfp; +} + +static int lib_vrf_get_keys(struct nb_cb_get_keys_args *args) +{ + struct vrf *vrfp = (struct vrf *)args->list_entry; + + args->keys->num = 1; + strlcpy(args->keys->key[0], vrfp->name, sizeof(args->keys->key[0])); + + return NB_OK; +} + +static const void *lib_vrf_lookup_entry(struct nb_cb_lookup_entry_args *args) +{ + const char *vrfname = args->keys->key[0]; + + struct vrf *vrf = vrf_lookup_by_name(vrfname); + + return vrf; +} + +/* + * XPath: /frr-vrf:lib/vrf/id + */ +static struct yang_data * +lib_vrf_state_id_get_elem(struct nb_cb_get_elem_args *args) +{ + struct vrf *vrfp = (struct vrf *)args->list_entry; + + return yang_data_new_uint32(args->xpath, vrfp->vrf_id); +} + +/* + * XPath: /frr-vrf:lib/vrf/active + */ +static struct yang_data * +lib_vrf_state_active_get_elem(struct nb_cb_get_elem_args *args) +{ + struct vrf *vrfp = (struct vrf *)args->list_entry; + + if (vrfp->status == VRF_ACTIVE) + return yang_data_new_bool( + args->xpath, vrfp->status == VRF_ACTIVE ? true : false); + + return NULL; +} + +/* clang-format off */ +const struct frr_yang_module_info frr_vrf_info = { + .name = "frr-vrf", + .nodes = { + { + .xpath = "/frr-vrf:lib/vrf", + .cbs = { + .create = lib_vrf_create, + .destroy = lib_vrf_destroy, + .get_next = lib_vrf_get_next, + .get_keys = lib_vrf_get_keys, + .lookup_entry = lib_vrf_lookup_entry, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/state/id", + .cbs = { + .get_elem = lib_vrf_state_id_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/state/active", + .cbs = { + .get_elem = lib_vrf_state_active_get_elem, + } + }, + { + .xpath = NULL, + }, + } +}; + @@ -325,6 +325,8 @@ extern int vrf_enable(struct vrf *vrf); extern void vrf_delete(struct vrf *vrf); extern vrf_id_t vrf_generate_id(void); +extern const struct frr_yang_module_info frr_vrf_info; + #ifdef __cplusplus } #endif @@ -1882,7 +1882,7 @@ static void vty_serv_sock_addrinfo(const char *hostname, unsigned short port) req.ai_flags = AI_PASSIVE; req.ai_family = AF_UNSPEC; req.ai_socktype = SOCK_STREAM; - sprintf(port_str, "%d", port); + snprintf(port_str, sizeof(port_str), "%d", port); port_str[sizeof(port_str) - 1] = '\0'; ret = getaddrinfo(hostname, port_str, &req, &ainfo); @@ -2199,6 +2199,9 @@ void vty_close(struct vty *vty) int i; bool was_stdio = false; + /* Drop out of configure / transaction if needed. */ + vty_config_exit(vty); + /* Cancel threads.*/ THREAD_OFF(vty->t_read); THREAD_OFF(vty->t_write); @@ -2242,9 +2245,6 @@ void vty_close(struct vty *vty) list_delete(&vty->error); } - /* Check configure. */ - vty_config_exit(vty); - /* OK free vty. */ XFREE(MTYPE_VTY, vty); @@ -2380,7 +2380,7 @@ static FILE *vty_use_backup_config(const char *fullpath) } fullpath_tmp = malloc(strlen(fullpath) + 8); - sprintf(fullpath_tmp, "%s.XXXXXX", fullpath); + snprintf(fullpath_tmp, strlen(fullpath) + 8, "%s.XXXXXX", fullpath); /* Open file to configuration write. */ tmp = mkstemp(fullpath_tmp); @@ -2605,6 +2605,28 @@ int vty_config_enter(struct vty *vty, bool private_config, bool exclusive) void vty_config_exit(struct vty *vty) { + enum node_type node = vty->node; + struct cmd_node *cnode; + + /* unlock and jump up to ENABLE_NODE if -and only if- we're + * somewhere below CONFIG_NODE */ + while (node && node != CONFIG_NODE) { + cnode = vector_lookup(cmdvec, node); + node = cnode->parent_node; + } + if (node != CONFIG_NODE) + /* called outside config, e.g. vty_close() in ENABLE_NODE */ + return; + + while (vty->node != ENABLE_NODE) + /* will call vty_config_node_exit() below */ + cmd_exit(vty); +} + +int vty_config_node_exit(struct vty *vty) +{ + vty->xpath_index = 0; + /* Check if there's a pending confirmed commit. */ if (vty->t_confirmed_commit_timeout) { vty_out(vty, @@ -2626,6 +2648,7 @@ void vty_config_exit(struct vty *vty) } vty->config = false; + return 1; } /* Master of the threads. */ @@ -2989,8 +3012,13 @@ static int vty_config_write(struct vty *vty) return CMD_SUCCESS; } +static int vty_config_write(struct vty *vty); struct cmd_node vty_node = { - VTY_NODE, "%s(config-line)# ", 1, + .name = "vty", + .node = VTY_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-line)# ", + .config_write = vty_config_write, }; /* Reset all VTY status. */ @@ -3084,7 +3112,7 @@ void vty_init(struct thread_master *master_thread, bool do_command_logging) Vvty_serv_thread = vector_init(VECTOR_MIN_SIZE); /* Install bgp top node. */ - install_node(&vty_node, vty_config_write); + install_node(&vty_node); install_element(VIEW_NODE, &config_who_cmd); install_element(VIEW_NODE, &show_history_cmd); @@ -323,6 +323,7 @@ extern void vty_log(const char *level, const char *proto, const char *msg, extern int vty_config_enter(struct vty *vty, bool private_config, bool exclusive); extern void vty_config_exit(struct vty *); +extern int vty_config_node_exit(struct vty *); extern int vty_shell(struct vty *); extern int vty_shell_serv(struct vty *); extern void vty_hello(struct vty *); diff --git a/lib/yang.c b/lib/yang.c index 0502d4952d..c80bf20306 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -72,13 +72,17 @@ static const char *yang_module_imp_clb(const char *mod_name, return NULL; } +/* clang-format off */ static const char *const frr_native_modules[] = { "frr-interface", + "frr-vrf", "frr-ripd", "frr-ripngd", "frr-isisd", "frr-vrrpd", + "frr-zebra", }; +/* clang-format on */ /* Generate the yang_modules tree. */ static inline int yang_module_compare(const struct yang_module *a, diff --git a/lib/yang.h b/lib/yang.h index 8af440d3ed..126521707b 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -34,7 +34,7 @@ extern "C" { #endif /* Maximum XPath length. */ -#define XPATH_MAXLEN 256 +#define XPATH_MAXLEN 512 /* Maximum list key length. */ #define LIST_MAXKEYS 8 diff --git a/lib/yang_wrappers.c b/lib/yang_wrappers.c index 2b502d635b..c31ba3fcc0 100644 --- a/lib/yang_wrappers.c +++ b/lib/yang_wrappers.c @@ -23,6 +23,8 @@ #include "lib_errors.h" #include "northbound.h" #include "printfrr.h" +#include "nexthop.h" +#include "printfrr.h" static const char *yang_get_default_value(const char *xpath) { @@ -783,6 +785,14 @@ void yang_get_default_string_buf(char *buf, size_t size, const char *xpath_fmt, } /* + * Primitive type: empty. + */ +struct yang_data *yang_data_new_empty(const char *xpath) +{ + return yang_data_new(xpath, NULL); +} + +/* * Derived type: IP prefix. */ void yang_str2prefix(const char *value, union prefixptr prefix) @@ -1114,3 +1124,70 @@ void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...) value = yang_get_default_value(xpath); yang_str2ip(value, var); } + +struct yang_data *yang_data_new_mac(const char *xpath, + const struct ethaddr *mac) +{ + char value_str[ETHER_ADDR_STRLEN]; + + prefix_mac2str(mac, value_str, sizeof(value_str)); + return yang_data_new(xpath, value_str); +} + +void yang_str2mac(const char *value, struct ethaddr *mac) +{ + (void)prefix_str2mac(value, mac); +} + +struct yang_data *yang_data_new_date_and_time(const char *xpath, time_t time) +{ + struct tm tm; + char timebuf[MONOTIME_STRLEN]; + struct timeval _time, time_real; + char *ts_dot; + uint16_t buflen; + + _time.tv_sec = time; + _time.tv_usec = 0; + monotime_to_realtime(&_time, &time_real); + + gmtime_r(&time_real.tv_sec, &tm); + + /* rfc-3339 format */ + strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%S", &tm); + buflen = strlen(timebuf); + ts_dot = timebuf + buflen; + + /* microseconds and appends Z */ + snprintfrr(ts_dot, sizeof(timebuf) - buflen, ".%06luZ", + (unsigned long)time_real.tv_usec); + + return yang_data_new(xpath, timebuf); +} + +const char *yang_nexthop_type2str(uint32_t ntype) +{ + switch (ntype) { + case NEXTHOP_TYPE_IFINDEX: + return "ifindex"; + break; + case NEXTHOP_TYPE_IPV4: + return "ip4"; + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + return "ip4-ifindex"; + break; + case NEXTHOP_TYPE_IPV6: + return "ip6"; + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + return "ip6-ifindex"; + break; + case NEXTHOP_TYPE_BLACKHOLE: + return "blackhole"; + break; + default: + return "unknown"; + break; + } +} diff --git a/lib/yang_wrappers.h b/lib/yang_wrappers.h index 10d1ea314f..ba2cf5139c 100644 --- a/lib/yang_wrappers.h +++ b/lib/yang_wrappers.h @@ -22,6 +22,10 @@ #include "prefix.h" +#ifdef __cplusplus +extern "C" { +#endif + /* bool */ extern bool yang_str2bool(const char *value); extern struct yang_data *yang_data_new_bool(const char *xpath, bool value); @@ -114,6 +118,9 @@ extern const char *yang_get_default_string(const char *xpath_fmt, ...); extern void yang_get_default_string_buf(char *buf, size_t size, const char *xpath_fmt, ...); +/* empty */ +extern struct yang_data *yang_data_new_empty(const char *xpath); + /* ip prefix */ extern void yang_str2prefix(const char *value, union prefixptr prefix); extern struct yang_data *yang_data_new_prefix(const char *xpath, @@ -172,4 +179,20 @@ extern void yang_dnode_get_ip(struct ipaddr *addr, const struct lyd_node *dnode, const char *xpath_fmt, ...); extern void yang_get_default_ip(struct ipaddr *var, const char *xpath_fmt, ...); +/* mac */ +extern struct yang_data *yang_data_new_mac(const char *xpath, + const struct ethaddr *mac); +extern void yang_str2mac(const char *value, struct ethaddr *mac); + +/*data-and-time */ +extern struct yang_data *yang_data_new_date_and_time(const char *xpath, + time_t time); + +/* nexthop enum2str */ +extern const char *yang_nexthop_type2str(uint32_t ntype); + +#ifdef __cplusplus +} +#endif + #endif /* _FRR_NORTHBOUND_WRAPPERS_H_ */ diff --git a/lib/zassert.h b/lib/zassert.h index d45e1be5f8..e50a88f407 100644 --- a/lib/zassert.h +++ b/lib/zassert.h @@ -19,6 +19,10 @@ #ifndef _QUAGGA_ASSERT_H #define _QUAGGA_ASSERT_H +#ifdef __cplusplus +extern "C" { +#endif + extern void _zlog_assert_failed(const char *assertion, const char *file, unsigned int line, const char *function) __attribute__((noreturn)); @@ -39,4 +43,8 @@ extern void _zlog_assert_failed(const char *assertion, const char *file, #undef assert #define assert(EX) zassert(EX) +#ifdef __cplusplus +} +#endif + #endif /* _QUAGGA_ASSERT_H */ diff --git a/lib/zclient.c b/lib/zclient.c index 5402e9c3c5..be2c4e54a0 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -388,6 +388,7 @@ int zclient_send_hello(struct zclient *zclient) zclient_create_header(s, ZEBRA_HELLO, VRF_DEFAULT); stream_putc(s, zclient->redist_default); stream_putw(s, zclient->instance); + stream_putl(s, zclient->session_id); if (zclient->receive_notify) stream_putc(s, 1); else diff --git a/lib/zclient.h b/lib/zclient.h index 214226cf5f..4ada064623 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -38,6 +38,10 @@ #include "mlag.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Zebra types. Used in Zserv message header. */ typedef uint16_t zebra_size_t; @@ -258,6 +262,9 @@ struct zclient { /* Is this a synchronous client? */ bool synchronous; + /* Session id (optional) to support clients with multiple sessions */ + uint32_t session_id; + /* Socket to zebra daemon. */ int sock; @@ -823,4 +830,8 @@ extern void zclient_send_mlag_data(struct zclient *client, */ extern int zclient_send_hello(struct zclient *client); +#ifdef __cplusplus +} +#endif + #endif /* _ZEBRA_ZCLIENT_H */ diff --git a/lib/zlog.c b/lib/zlog.c new file mode 100644 index 0000000000..45726755f8 --- /dev/null +++ b/lib/zlog.c @@ -0,0 +1,701 @@ +/* + * Copyright (c) 2015-19 David Lamparter, for NetDEF, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "zebra.h" + +#include <unistd.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <pthread.h> + +/* gettid() & co. */ +#ifdef HAVE_PTHREAD_NP_H +#include <pthread_np.h> +#endif +#ifdef linux +#include <sys/syscall.h> +#endif +#ifdef __FreeBSD__ +#include <sys/thr.h> +#endif +#ifdef __NetBSD__ +#include <lwp.h> +#endif +#ifdef __DragonFly__ +#include <sys/lwp.h> +#endif +#ifdef __APPLE__ +#include <mach/mach_traps.h> +#endif + +#include "memory.h" +#include "atomlist.h" +#include "printfrr.h" +#include "frrcu.h" +#include "zlog.h" + +DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE, "log message") +DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF, "log thread-local buffer") + +DEFINE_HOOK(zlog_init, (const char *progname, const char *protoname, + unsigned short instance, uid_t uid, gid_t gid), + (progname, protoname, instance, uid, gid)) +DEFINE_KOOH(zlog_fini, (), ()) +DEFINE_HOOK(zlog_aux_init, (const char *prefix, int prio_min), + (prefix, prio_min)) + +char zlog_prefix[128]; +size_t zlog_prefixsz; +int zlog_tmpdirfd = -1; + +/* these are kept around because logging is initialized (and directories + * & files created) before zprivs code switches to the FRR user; therefore + * we need to chown() things so we don't get permission errors later when + * trying to delete things on shutdown + */ +static uid_t zlog_uid = -1; +static gid_t zlog_gid = -1; + +DECLARE_ATOMLIST(zlog_targets, struct zlog_target, head); +static struct zlog_targets_head zlog_targets; + +/* cf. zlog.h for additional comments on this struct. + * + * Note: you MUST NOT pass the format string + va_list to non-FRR format + * string functions (e.g. vsyslog, sd_journal_printv, ...) since FRR uses an + * extended prinf() with additional formats (%pI4 and the like). + * + * Also remember to use va_copy() on args. + */ + +struct zlog_msg { + struct timespec ts; + int prio; + + const char *fmt; + va_list args; + + char *stackbuf; + size_t stackbufsz; + char *text; + size_t textlen; + + /* This is always ISO8601 with sub-second precision 9 here, it's + * converted for callers as needed. ts_dot points to the "." + * separating sub-seconds. ts_zonetail is "Z" or "+00:00" for the + * local time offset. + * + * Valid if ZLOG_TS_ISO8601 is set. + * (0 if timestamp has not been formatted yet) + */ + uint32_t ts_flags; + char ts_str[32], *ts_dot, ts_zonetail[8]; +}; + +/* thread-local log message buffering + * + * This is strictly optional and set up by calling zlog_tls_buffer_init() + * on a particular thread. + * + * If in use, this will create a temporary file in /var/tmp which is used as + * memory-mapped MAP_SHARED log message buffer. The idea there is that buffer + * access doesn't require any syscalls, but in case of a crash the kernel + * knows to sync the memory back to disk. This way the user can still get the + * last log messages if there were any left unwritten in the buffer. + * + * Sizing this dynamically isn't particularly useful, so here's an 8k buffer + * with a message limit of 64 messages. Message metadata (e.g. priority, + * timestamp) aren't in the mmap region, so they're lost on crash, but we can + * live with that. + */ + +#if defined(HAVE_OPENAT) && defined(HAVE_UNLINKAT) +#define CAN_DO_TLS 1 +#endif + +#define TLS_LOG_BUF_SIZE 8192 +#define TLS_LOG_MAXMSG 64 + +struct zlog_tls { + char *mmbuf; + size_t bufpos; + + size_t nmsgs; + struct zlog_msg msgs[TLS_LOG_MAXMSG]; + struct zlog_msg *msgp[TLS_LOG_MAXMSG]; +}; + +static inline void zlog_tls_free(void *arg); + +/* proper ELF TLS is a bit faster than pthread_[gs]etspecific, so if it's + * available we'll use it here + */ + +#ifdef __OpenBSD__ +static pthread_key_t zlog_tls_key; + +static void zlog_tls_key_init(void) __attribute__((_CONSTRUCTOR(500))); +static void zlog_tls_key_init(void) +{ + pthread_key_create(&zlog_tls_key, zlog_tls_free); +} + +static void zlog_tls_key_fini(void) __attribute__((_DESTRUCTOR(500))); +static void zlog_tls_key_fini(void) +{ + pthread_key_delete(zlog_tls_key); +} + +static inline struct zlog_tls *zlog_tls_get(void) +{ + return pthread_getspecific(zlog_tls_key); +} + +static inline void zlog_tls_set(struct zlog_tls *val) +{ + pthread_setspecific(zlog_tls_key, val); +} +#else +# ifndef thread_local +# define thread_local __thread +# endif + +static thread_local struct zlog_tls *zlog_tls_var + __attribute__((tls_model("initial-exec"))); + +static inline struct zlog_tls *zlog_tls_get(void) +{ + return zlog_tls_var; +} + +static inline void zlog_tls_set(struct zlog_tls *val) +{ + zlog_tls_var = val; +} +#endif + +#ifdef CAN_DO_TLS +static long zlog_gettid(void) +{ + long rv = -1; +#ifdef HAVE_PTHREAD_GETTHREADID_NP + rv = pthread_getthreadid_np(); +#elif defined(linux) + rv = syscall(__NR_gettid); +#elif defined(__NetBSD__) + rv = _lwp_self(); +#elif defined(__FreeBSD__) + thr_self(&rv); +#elif defined(__DragonFly__) + rv = lwp_gettid(); +#elif defined(__OpenBSD__) + rv = getthrid(); +#elif defined(__sun) + rv = pthread_self(); +#elif defined(__APPLE__) + rv = mach_thread_self(); + mach_port_deallocate(mach_task_self(), rv); +#endif + return rv; +} + +void zlog_tls_buffer_init(void) +{ + struct zlog_tls *zlog_tls; + char mmpath[MAXPATHLEN]; + int mmfd; + size_t i; + + zlog_tls = zlog_tls_get(); + + if (zlog_tls || zlog_tmpdirfd < 0) + return; + + zlog_tls = XCALLOC(MTYPE_LOG_TLSBUF, sizeof(*zlog_tls)); + for (i = 0; i < array_size(zlog_tls->msgp); i++) + zlog_tls->msgp[i] = &zlog_tls->msgs[i]; + + snprintfrr(mmpath, sizeof(mmpath), "logbuf.%ld", zlog_gettid()); + + mmfd = openat(zlog_tmpdirfd, mmpath, + O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0600); + if (mmfd < 0) { + zlog_err("failed to open thread log buffer \"%s\": %s", + mmpath, strerror(errno)); + goto out_anon; + } + fchown(mmfd, zlog_uid, zlog_gid); + +#ifdef HAVE_POSIX_FALLOCATE + if (posix_fallocate(mmfd, 0, TLS_LOG_BUF_SIZE) < 0) { +#else + if (ftruncate(mmfd, TLS_LOG_BUF_SIZE) < 0) { +#endif + zlog_err("failed to allocate thread log buffer \"%s\": %s", + mmpath, strerror(errno)); + goto out_anon_unlink; + } + + zlog_tls->mmbuf = mmap(NULL, TLS_LOG_BUF_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, mmfd, 0); + if (zlog_tls->mmbuf == MAP_FAILED) { + zlog_err("failed to mmap thread log buffer \"%s\": %s", + mmpath, strerror(errno)); + goto out_anon_unlink; + } + + close(mmfd); + zlog_tls_set(zlog_tls); + return; + +out_anon_unlink: + unlink(mmpath); + close(mmfd); +out_anon: + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + zlog_tls->mmbuf = mmap(NULL, TLS_LOG_BUF_SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + + if (!zlog_tls->mmbuf) { + zlog_err("failed to anonymous-mmap thread log buffer: %s", + strerror(errno)); + XFREE(MTYPE_LOG_TLSBUF, zlog_tls); + zlog_tls_set(NULL); + return; + } + + zlog_tls_set(zlog_tls); +} + +void zlog_tls_buffer_fini(void) +{ + char mmpath[MAXPATHLEN]; + + zlog_tls_buffer_flush(); + + zlog_tls_free(zlog_tls_get()); + zlog_tls_set(NULL); + + snprintfrr(mmpath, sizeof(mmpath), "logbuf.%ld", zlog_gettid()); + if (unlinkat(zlog_tmpdirfd, mmpath, 0)) + zlog_err("unlink logbuf: %s (%d)", strerror(errno), errno); +} + +#else /* !CAN_DO_TLS */ +void zlog_tls_buffer_init(void) +{ +} + +void zlog_tls_buffer_fini(void) +{ +} +#endif + +static inline void zlog_tls_free(void *arg) +{ + struct zlog_tls *zlog_tls = arg; + + if (!zlog_tls) + return; + + munmap(zlog_tls->mmbuf, TLS_LOG_BUF_SIZE); + XFREE(MTYPE_LOG_TLSBUF, zlog_tls); +} + +void zlog_tls_buffer_flush(void) +{ + struct zlog_target *zt; + struct zlog_tls *zlog_tls = zlog_tls_get(); + + if (!zlog_tls) + return; + if (!zlog_tls->nmsgs) + return; + + rcu_read_lock(); + frr_each (zlog_targets, &zlog_targets, zt) { + if (!zt->logfn) + continue; + + zt->logfn(zt, zlog_tls->msgp, zlog_tls->nmsgs); + } + rcu_read_unlock(); + + zlog_tls->bufpos = 0; + zlog_tls->nmsgs = 0; +} + + +static void vzlog_notls(int prio, const char *fmt, va_list ap) +{ + struct zlog_target *zt; + struct zlog_msg stackmsg = { + .prio = prio & LOG_PRIMASK, + .fmt = fmt, + }, *msg = &stackmsg; + char stackbuf[512]; + + clock_gettime(CLOCK_REALTIME, &msg->ts); + va_copy(msg->args, ap); + msg->stackbuf = stackbuf; + msg->stackbufsz = sizeof(stackbuf); + + rcu_read_lock(); + frr_each (zlog_targets, &zlog_targets, zt) { + if (prio > zt->prio_min) + continue; + if (!zt->logfn) + continue; + + zt->logfn(zt, &msg, 1); + } + rcu_read_unlock(); + + va_end(msg->args); + if (msg->text && msg->text != stackbuf) + XFREE(MTYPE_LOG_MESSAGE, msg->text); +} + +static void vzlog_tls(struct zlog_tls *zlog_tls, int prio, + const char *fmt, va_list ap) +{ + struct zlog_target *zt; + struct zlog_msg *msg; + char *buf; + bool ignoremsg = true; + bool immediate = false; + + /* avoid further processing cost if no target wants this message */ + rcu_read_lock(); + frr_each (zlog_targets, &zlog_targets, zt) { + if (prio > zt->prio_min) + continue; + ignoremsg = false; + break; + } + rcu_read_unlock(); + + if (ignoremsg) + return; + + msg = &zlog_tls->msgs[zlog_tls->nmsgs]; + zlog_tls->nmsgs++; + if (zlog_tls->nmsgs == array_size(zlog_tls->msgs)) + immediate = true; + + memset(msg, 0, sizeof(*msg)); + clock_gettime(CLOCK_REALTIME, &msg->ts); + va_copy(msg->args, ap); + msg->stackbuf = buf = zlog_tls->mmbuf + zlog_tls->bufpos; + msg->stackbufsz = TLS_LOG_BUF_SIZE - zlog_tls->bufpos - 1; + msg->fmt = fmt; + msg->prio = prio & LOG_PRIMASK; + if (msg->prio < LOG_INFO) + immediate = true; + + if (!immediate) { + /* messages written later need to take the formatting cost + * immediately since we can't hold a reference on varargs + */ + zlog_msg_text(msg, NULL); + + if (msg->text != buf) + /* zlog_msg_text called malloc() on us :( */ + immediate = true; + else { + zlog_tls->bufpos += msg->textlen + 1; + /* write a second \0 to mark current end position + * (in case of crash this signals end of unwritten log + * messages in mmap'd logbuf file) + */ + zlog_tls->mmbuf[zlog_tls->bufpos] = '\0'; + + /* avoid malloc() for next message */ + if (TLS_LOG_BUF_SIZE - zlog_tls->bufpos < 256) + immediate = true; + } + } + + if (immediate) + zlog_tls_buffer_flush(); + + va_end(msg->args); + if (msg->text && msg->text != buf) + XFREE(MTYPE_LOG_MESSAGE, msg->text); +} + +void vzlog(int prio, const char *fmt, va_list ap) +{ + struct zlog_tls *zlog_tls = zlog_tls_get(); + + if (zlog_tls) + vzlog_tls(zlog_tls, prio, fmt, ap); + else + vzlog_notls(prio, fmt, ap); +} + +void zlog_sigsafe(const char *text, size_t len) +{ + struct zlog_target *zt; + const char *end = text + len, *nlpos; + + while (text < end) { + nlpos = memchr(text, '\n', end - text); + if (!nlpos) + nlpos = end; + + frr_each (zlog_targets, &zlog_targets, zt) { + if (LOG_CRIT > zt->prio_min) + continue; + if (!zt->logfn_sigsafe) + continue; + + zt->logfn_sigsafe(zt, text, nlpos - text); + } + + if (nlpos == end) + break; + text = nlpos + 1; + } +} + + +int zlog_msg_prio(struct zlog_msg *msg) +{ + return msg->prio; +} + +const char *zlog_msg_text(struct zlog_msg *msg, size_t *textlen) +{ + if (!msg->text) { + va_list args; + + va_copy(args, msg->args); + msg->text = vasnprintfrr(MTYPE_LOG_MESSAGE, msg->stackbuf, + msg->stackbufsz, msg->fmt, args); + msg->textlen = strlen(msg->text); + va_end(args); + } + if (textlen) + *textlen = msg->textlen; + return msg->text; +} + +#define ZLOG_TS_FORMAT (ZLOG_TS_ISO8601 | ZLOG_TS_LEGACY) +#define ZLOG_TS_FLAGS ~ZLOG_TS_PREC + +size_t zlog_msg_ts(struct zlog_msg *msg, char *out, size_t outsz, + uint32_t flags) +{ + size_t len1; + + if (!(flags & ZLOG_TS_FORMAT)) + return 0; + + if (!(msg->ts_flags & ZLOG_TS_FORMAT) || + ((msg->ts_flags ^ flags) & ZLOG_TS_UTC)) { + struct tm tm; + + if (flags & ZLOG_TS_UTC) + gmtime_r(&msg->ts.tv_sec, &tm); + else + localtime_r(&msg->ts.tv_sec, &tm); + + strftime(msg->ts_str, sizeof(msg->ts_str), + "%Y-%m-%dT%H:%M:%S", &tm); + + if (flags & ZLOG_TS_UTC) { + msg->ts_zonetail[0] = 'Z'; + msg->ts_zonetail[1] = '\0'; + } else + snprintfrr(msg->ts_zonetail, sizeof(msg->ts_zonetail), + "%+03d:%02d", + (int)(tm.tm_gmtoff / 3600), + (int)(labs(tm.tm_gmtoff) / 60) % 60); + + msg->ts_dot = msg->ts_str + strlen(msg->ts_str); + snprintfrr(msg->ts_dot, + msg->ts_str + sizeof(msg->ts_str) - msg->ts_dot, + ".%09lu", (unsigned long)msg->ts.tv_nsec); + + msg->ts_flags = ZLOG_TS_ISO8601 | (flags & ZLOG_TS_UTC); + } + + len1 = flags & ZLOG_TS_PREC; + len1 = (msg->ts_dot - msg->ts_str) + (len1 ? len1 + 1 : 0); + + if (len1 > strlen(msg->ts_str)) + len1 = strlen(msg->ts_str); + + if (flags & ZLOG_TS_LEGACY) { + if (len1 + 1 > outsz) + return 0; + + /* just swap out the formatting, faster than redoing it */ + for (char *p = msg->ts_str; p < msg->ts_str + len1; p++) { + switch (*p) { + case '-': + *out++ = '/'; + break; + case 'T': + *out++ = ' '; + break; + default: + *out++ = *p; + } + } + *out = '\0'; + return len1; + } else { + size_t len2 = strlen(msg->ts_zonetail); + + if (len1 + len2 + 1 > outsz) + return 0; + memcpy(out, msg->ts_str, len1); + memcpy(out + len1, msg->ts_zonetail, len2); + out[len1 + len2] = '\0'; + return len1 + len2; + } +} + +/* setup functions */ + +struct zlog_target *zlog_target_clone(struct memtype *mt, + struct zlog_target *oldzt, size_t size) +{ + struct zlog_target *newzt; + + newzt = XCALLOC(mt, size); + if (oldzt) { + newzt->prio_min = oldzt->prio_min; + newzt->logfn = oldzt->logfn; + newzt->logfn_sigsafe = oldzt->logfn_sigsafe; + } + + return newzt; +} + +struct zlog_target *zlog_target_replace(struct zlog_target *oldzt, + struct zlog_target *newzt) +{ + if (newzt) + zlog_targets_add_tail(&zlog_targets, newzt); + if (oldzt) + zlog_targets_del(&zlog_targets, oldzt); + return oldzt; +} + + +/* common init */ + +#define TMPBASEDIR "/var/tmp/frr" + +static char zlog_tmpdir[MAXPATHLEN]; + +void zlog_aux_init(const char *prefix, int prio_min) +{ + if (prefix) + strlcpy(zlog_prefix, prefix, sizeof(zlog_prefix)); + + hook_call(zlog_aux_init, prefix, prio_min); +} + +void zlog_init(const char *progname, const char *protoname, + unsigned short instance, uid_t uid, gid_t gid) +{ + zlog_uid = uid; + zlog_gid = gid; + + if (instance) { + snprintfrr(zlog_tmpdir, sizeof(zlog_tmpdir), + "/var/tmp/frr/%s-%d.%ld", + progname, instance, (long)getpid()); + + zlog_prefixsz = snprintfrr(zlog_prefix, sizeof(zlog_prefix), + "%s[%d]: ", protoname, instance); + } else { + snprintfrr(zlog_tmpdir, sizeof(zlog_tmpdir), + "/var/tmp/frr/%s.%ld", + progname, (long)getpid()); + + zlog_prefixsz = snprintfrr(zlog_prefix, sizeof(zlog_prefix), + "%s: ", protoname); + } + + if (mkdir(TMPBASEDIR, 0700) != 0) { + if (errno != EEXIST) { + zlog_err("failed to mkdir \"%s\": %s", + TMPBASEDIR, strerror(errno)); + goto out_warn; + } + } + chown(TMPBASEDIR, zlog_uid, zlog_gid); + + if (mkdir(zlog_tmpdir, 0700) != 0) { + zlog_err("failed to mkdir \"%s\": %s", + zlog_tmpdir, strerror(errno)); + goto out_warn; + } + +#ifdef O_PATH + zlog_tmpdirfd = open(zlog_tmpdir, + O_PATH | O_RDONLY | O_CLOEXEC); +#else + zlog_tmpdirfd = open(zlog_tmpdir, + O_DIRECTORY | O_RDONLY | O_CLOEXEC); +#endif + if (zlog_tmpdirfd < 0) { + zlog_err("failed to open \"%s\": %s", + zlog_tmpdir, strerror(errno)); + goto out_warn; + } + +#ifdef AT_EMPTY_PATH + fchownat(zlog_tmpdirfd, "", zlog_uid, zlog_gid, AT_EMPTY_PATH); +#else + chown(zlog_tmpdir, zlog_uid, zlog_gid); +#endif + + hook_call(zlog_init, progname, protoname, instance, uid, gid); + return; + +out_warn: + zlog_err("crashlog and per-thread log buffering unavailable!"); + hook_call(zlog_init, progname, protoname, instance, uid, gid); +} + +void zlog_fini(void) +{ + hook_call(zlog_fini); + + if (zlog_tmpdirfd >= 0) { + close(zlog_tmpdirfd); + zlog_tmpdirfd = -1; + + if (rmdir(zlog_tmpdir)) + zlog_err("failed to rmdir \"%s\": %s", + zlog_tmpdir, strerror(errno)); + } +} diff --git a/lib/zlog.h b/lib/zlog.h new file mode 100644 index 0000000000..1c5013746b --- /dev/null +++ b/lib/zlog.h @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2015-19 David Lamparter, for NetDEF, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FRR_ZLOG_H +#define _FRR_ZLOG_H + +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> +#include <sys/uio.h> + +#include "atomlist.h" +#include "frrcu.h" +#include "memory.h" +#include "hook.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern char zlog_prefix[]; +extern size_t zlog_prefixsz; +extern int zlog_tmpdirfd; + +/* These functions are set up to write to stdout/stderr without explicit + * initialization and/or before config load. There is no need to call e.g. + * fprintf(stderr, ...) just because it's "too early" at startup. Depending + * on context, it may still be the right thing to use fprintf though -- try to + * determine wether something is a log message or something else. + */ + +extern void vzlog(int prio, const char *fmt, va_list ap); + +PRINTFRR(2, 3) +static inline void zlog(int prio, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vzlog(prio, fmt, ap); + va_end(ap); +} + +#define zlog_err(...) zlog(LOG_ERR, __VA_ARGS__) +#define zlog_warn(...) zlog(LOG_WARNING, __VA_ARGS__) +#define zlog_info(...) zlog(LOG_INFO, __VA_ARGS__) +#define zlog_notice(...) zlog(LOG_NOTICE, __VA_ARGS__) +#define zlog_debug(...) zlog(LOG_DEBUG, __VA_ARGS__) + +extern void zlog_sigsafe(const char *text, size_t len); + +/* extra priority value to disable a target without deleting it */ +#define ZLOG_DISABLED (LOG_EMERG-1) + +/* zlog_msg encapsulates a particular logging call from somewhere in the code. + * The same struct is passed around to all zlog_targets. + * + * This is used to defer formatting the log message until it is actually + * requested by one of the targets. If none of the targets needs the message + * formatted, the formatting call is avoided entirely. + * + * This struct is opaque / private to the core zlog code. Logging targets + * should use zlog_msg_* functions to get text / timestamps / ... for a + * message. + */ + +struct zlog_msg; + +extern int zlog_msg_prio(struct zlog_msg *msg); + +/* pass NULL as textlen if you don't need it. */ +extern const char *zlog_msg_text(struct zlog_msg *msg, size_t *textlen); + +/* timestamp formatting control flags */ + +/* sub-second digit count */ +#define ZLOG_TS_PREC 0xfU + +/* 8601: 0000-00-00T00:00:00Z (if used with ZLOG_TS_UTC) + * 0000-00-00T00:00:00+00:00 (otherwise) + * Legacy: 0000/00/00 00:00:00 (no TZ indicated!) + */ +#define ZLOG_TS_ISO8601 (1 << 8) +#define ZLOG_TS_LEGACY (1 << 9) + +/* default is local time zone */ +#define ZLOG_TS_UTC (1 << 10) + +extern size_t zlog_msg_ts(struct zlog_msg *msg, char *out, size_t outsz, + uint32_t flags); + +/* This list & struct implements the actual logging targets. It is accessed + * lock-free from all threads, and thus MUST only be changed atomically, i.e. + * RCU. + * + * Since there's no atomic replace, the replacement action is an add followed + * by a delete. This means that during logging config changes, log messages + * may be duplicated in the log target that is being changed. The old entry + * being changed MUST also at the very least not crash or do other stupid + * things. + * + * This list and struct are NOT related to config. Logging config is kept + * separately, and results in creating appropriate zlog_target(s) to realize + * the config. Log targets may also be created from varying sources, e.g. + * command line options, or VTY commands ("log monitor"). + * + * struct zlog_target is intended to be embedded into a larger structure that + * contains additional field for the specific logging target, e.g. an fd or + * additional options. It MUST be the first field in that larger struct. + */ + +PREDECL_ATOMLIST(zlog_targets) +struct zlog_target { + struct zlog_targets_item head; + + int prio_min; + + void (*logfn)(struct zlog_target *zt, struct zlog_msg *msg[], + size_t nmsgs); + + /* for crash handlers, set to NULL if log target can't write crash logs + * without possibly deadlocking (AS-Safe) + * + * text is not \0 terminated & split up into lines (e.g. no \n) + */ + void (*logfn_sigsafe)(struct zlog_target *zt, const char *text, + size_t len); + + struct rcu_head rcu_head; +}; + +/* make a copy for RCUpdating. oldzt may be NULL to allocate a fresh one. */ +extern struct zlog_target *zlog_target_clone(struct memtype *mt, + struct zlog_target *oldzt, + size_t size); + +/* update the zlog_targets list; both oldzt and newzt may be NULL. You + * still need to zlog_target_free() the old target afterwards if it wasn't + * NULL. + * + * Returns oldzt so you can zlog_target_free(zlog_target_replace(old, new)); + * (Some log targets may need extra cleanup inbetween, but remember the old + * target MUST remain functional until the end of the current RCU cycle.) + */ +extern struct zlog_target *zlog_target_replace(struct zlog_target *oldzt, + struct zlog_target *newzt); + +/* Mostly for symmetry for zlog_target_clone(), just rcu_free() internally. */ +#define zlog_target_free(mt, zt) \ + rcu_free(mt, zt, rcu_head) + +extern void zlog_init(const char *progname, const char *protoname, + unsigned short instance, uid_t uid, gid_t gid); +DECLARE_HOOK(zlog_init, (const char *progname, const char *protoname, + unsigned short instance, uid_t uid, gid_t gid), + (progname, protoname, instance, uid, gid)) + +extern void zlog_fini(void); +DECLARE_KOOH(zlog_fini, (), ()) + +/* for tools & test programs, i.e. anything not a daemon. + * (no cleanup needed at exit) + */ +extern void zlog_aux_init(const char *prefix, int prio_min); +DECLARE_HOOK(zlog_aux_init, (const char *prefix, int prio_min), + (prefix, prio_min)) + +extern void zlog_startup_end(void); + +extern void zlog_tls_buffer_init(void); +extern void zlog_tls_buffer_flush(void); +extern void zlog_tls_buffer_fini(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _FRR_ZLOG_H */ diff --git a/lib/zlog_targets.c b/lib/zlog_targets.c new file mode 100644 index 0000000000..b23ab073b4 --- /dev/null +++ b/lib/zlog_targets.c @@ -0,0 +1,574 @@ +/* + * Copyright (c) 2015-19 David Lamparter, for NetDEF, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "zebra.h" + +#include <sys/un.h> +#include <syslog.h> + +#include "memory.h" +#include "frrcu.h" +#include "frr_pthread.h" +#include "printfrr.h" +#include "zlog.h" +#include "zlog_targets.h" + +/* these allocations are intentionally left active even when doing full exit + * cleanup, in order to keep the logging subsystem fully functional until the + * absolute end. + */ + +DECLARE_MGROUP(LOG) +DEFINE_MGROUP_ACTIVEATEXIT(LOG, "logging subsystem") + +DEFINE_MTYPE_STATIC(LOG, LOG_FD, "log file target") +DEFINE_MTYPE_STATIC(LOG, LOG_FD_NAME, "log file name") +DEFINE_MTYPE_STATIC(LOG, LOG_FD_ROTATE, "log file rotate helper") +DEFINE_MTYPE_STATIC(LOG, LOG_SYSL, "syslog target") + +struct zlt_fd { + struct zlog_target zt; + + atomic_uint_fast32_t fd; + + char ts_subsec; + bool record_priority; + + struct rcu_head_close head_close; +}; + +static const char * const prionames[] = { + [LOG_EMERG] = "emergencies: ", + [LOG_ALERT] = "alerts: ", + [LOG_CRIT] = "critical: ", + [LOG_ERR] = "errors: ", + [LOG_WARNING] = "warnings: ", + [LOG_NOTICE] = "notifications: ", + [LOG_INFO] = "informational: ", + [LOG_DEBUG] = "debugging: ", +}; + +void zlog_fd(struct zlog_target *zt, struct zlog_msg *msgs[], size_t nmsgs) +{ + struct zlt_fd *zte = container_of(zt, struct zlt_fd, zt); + int fd; + size_t i, textlen, iovpos = 0; + size_t niov = MIN(4 * nmsgs + 1, IOV_MAX); + struct iovec iov[niov]; + /* "\nYYYY-MM-DD HH:MM:SS.NNNNNNNNN+ZZ:ZZ " = 37 chars */ +#define TS_LEN 40 + char ts_buf[TS_LEN * nmsgs], *ts_pos = ts_buf; + + fd = atomic_load_explicit(&zte->fd, memory_order_relaxed); + + for (i = 0; i < nmsgs; i++) { + struct zlog_msg *msg = msgs[i]; + int prio = zlog_msg_prio(msg); + + if (prio > zt->prio_min) + continue; + + iov[iovpos].iov_base = ts_pos; + if (iovpos > 0) + *ts_pos++ = '\n'; + ts_pos += zlog_msg_ts(msg, ts_pos, sizeof(ts_buf) - 1 + - (ts_pos - ts_buf), + ZLOG_TS_LEGACY | zte->ts_subsec); + *ts_pos++ = ' '; + iov[iovpos].iov_len = ts_pos - (char *)iov[iovpos].iov_base; + + iovpos++; + + if (zte->record_priority) { + iov[iovpos].iov_base = (char *)prionames[prio]; + iov[iovpos].iov_len = strlen(iov[iovpos].iov_base); + + iovpos++; + } + + iov[iovpos].iov_base = zlog_prefix; + iov[iovpos].iov_len = zlog_prefixsz; + + iovpos++; + + iov[iovpos].iov_base = (char *)zlog_msg_text(msg, &textlen); + iov[iovpos].iov_len = textlen; + + iovpos++; + + if (ts_buf + sizeof(ts_buf) - ts_pos < TS_LEN + || i + 1 == nmsgs + || array_size(iov) - iovpos < 5) { + iov[iovpos].iov_base = (char *)"\n"; + iov[iovpos].iov_len = 1; + + iovpos++; + + writev(fd, iov, iovpos); + + iovpos = 0; + ts_pos = ts_buf; + } + } + + assert(iovpos == 0); +} + +static void zlog_fd_sigsafe(struct zlog_target *zt, const char *text, + size_t len) +{ + struct zlt_fd *zte = container_of(zt, struct zlt_fd, zt); + struct iovec iov[4]; + int fd; + + iov[0].iov_base = (char *)prionames[LOG_CRIT]; + iov[0].iov_len = zte->record_priority ? strlen(iov[0].iov_base) : 0; + + iov[1].iov_base = zlog_prefix; + iov[1].iov_len = zlog_prefixsz; + + iov[2].iov_base = (char *)text; + iov[2].iov_len = len; + + iov[3].iov_base = (char *)"\n"; + iov[3].iov_len = 1; + + fd = atomic_load_explicit(&zte->fd, memory_order_relaxed); + + writev(fd, iov, array_size(iov)); +} + +/* + * (re-)configuration + */ + +void zlog_file_init(struct zlog_cfg_file *zcf) +{ + memset(zcf, 0, sizeof(*zcf)); + zcf->prio_min = ZLOG_DISABLED; + zcf->fd = -1; + pthread_mutex_init(&zcf->cfg_mtx, NULL); +} + +static void zlog_file_target_free(struct zlt_fd *zlt) +{ + if (!zlt) + return; + + rcu_close(&zlt->head_close, zlt->fd); + rcu_free(MTYPE_LOG_FD, zlt, zt.rcu_head); +} + +void zlog_file_fini(struct zlog_cfg_file *zcf) +{ + if (zcf->active) { + struct zlt_fd *ztf; + struct zlog_target *zt; + + zt = zlog_target_replace(&zcf->active->zt, NULL); + ztf = container_of(zt, struct zlt_fd, zt); + zlog_file_target_free(ztf); + } + XFREE(MTYPE_LOG_FD_NAME, zcf->filename); + pthread_mutex_destroy(&zcf->cfg_mtx); +} + +static bool zlog_file_cycle(struct zlog_cfg_file *zcf) +{ + struct zlog_target *zt, *old; + struct zlt_fd *zlt = NULL; + int fd; + bool rv = true; + + do { + if (zcf->prio_min == ZLOG_DISABLED) + break; + + if (zcf->fd != -1) + fd = dup(zcf->fd); + else if (zcf->filename) + fd = open(zcf->filename, + O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC + | O_NOCTTY, + LOGFILE_MASK); + else + fd = -1; + + if (fd < 0) { + rv = false; + break; + } + + zt = zlog_target_clone(MTYPE_LOG_FD, &zcf->active->zt, + sizeof(*zlt)); + zlt = container_of(zt, struct zlt_fd, zt); + + zlt->fd = fd; + zlt->record_priority = zcf->record_priority; + zlt->ts_subsec = zcf->ts_subsec; + + zlt->zt.prio_min = zcf->prio_min; + zlt->zt.logfn = zcf->zlog_wrap ? zcf->zlog_wrap : zlog_fd; + zlt->zt.logfn_sigsafe = zlog_fd_sigsafe; + } while (0); + + old = zlog_target_replace(&zcf->active->zt, &zlt->zt); + zcf->active = zlt; + + zlog_file_target_free(container_of(old, struct zlt_fd, zt)); + + return rv; +} + +void zlog_file_set_other(struct zlog_cfg_file *zcf) +{ + frr_with_mutex(&zcf->cfg_mtx) { + zlog_file_cycle(zcf); + } +} + +bool zlog_file_set_filename(struct zlog_cfg_file *zcf, const char *filename) +{ + frr_with_mutex(&zcf->cfg_mtx) { + XFREE(MTYPE_LOG_FD_NAME, zcf->filename); + zcf->filename = XSTRDUP(MTYPE_LOG_FD_NAME, filename); + zcf->fd = -1; + + return zlog_file_cycle(zcf); + } + assert(0); +} + +bool zlog_file_set_fd(struct zlog_cfg_file *zcf, int fd) +{ + frr_with_mutex(&zcf->cfg_mtx) { + if (zcf->fd == fd) + return true; + + XFREE(MTYPE_LOG_FD_NAME, zcf->filename); + zcf->fd = fd; + + return zlog_file_cycle(zcf); + } + assert(0); +} + +struct rcu_close_rotate { + struct rcu_head_close head_close; + struct rcu_head head_self; +}; + +bool zlog_file_rotate(struct zlog_cfg_file *zcf) +{ + struct rcu_close_rotate *rcr; + int fd; + + frr_with_mutex(&zcf->cfg_mtx) { + if (!zcf->active || !zcf->filename) + return true; + + fd = open(zcf->filename, + O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC | O_NOCTTY, + LOGFILE_MASK); + if (fd < 0) + return false; + + fd = atomic_exchange_explicit(&zcf->active->fd, + (uint_fast32_t)fd, + memory_order_relaxed); + } + + rcr = XCALLOC(MTYPE_LOG_FD_ROTATE, sizeof(*rcr)); + rcu_close(&rcr->head_close, fd); + rcu_free(MTYPE_LOG_FD_ROTATE, rcr, head_self); + + return true; +} + +/* fixed crash logging */ + +static struct zlt_fd zlog_crashlog; + +static void zlog_crashlog_sigsafe(struct zlog_target *zt, const char *text, + size_t len) +{ + static int crashlog_fd = -1; + + if (crashlog_fd == -1) { +#ifdef HAVE_OPENAT + crashlog_fd = openat(zlog_tmpdirfd, "crashlog", + O_WRONLY | O_APPEND | O_CREAT, + LOGFILE_MASK); +#endif + if (crashlog_fd < 0) + crashlog_fd = -2; + } + + if (crashlog_fd == -2) + return; + + zlog_crashlog.fd = crashlog_fd; + zlog_fd_sigsafe(&zlog_crashlog.zt, text, len); +} + +/* this is used for assert failures (they don't need AS-Safe logging) */ +static void zlog_crashlog_plain(struct zlog_target *zt, struct zlog_msg *msgs[], + size_t nmsgs) +{ + size_t i, len; + const char *text; + + for (i = 0; i < nmsgs; i++) { + if (zlog_msg_prio(msgs[i]) > zt->prio_min) + continue; + + text = zlog_msg_text(msgs[i], &len); + zlog_crashlog_sigsafe(zt, text, len); + } +} + +static void zlog_crashlog_init(void) +{ + zlog_crashlog.zt.prio_min = LOG_CRIT; + zlog_crashlog.zt.logfn = zlog_crashlog_plain; + zlog_crashlog.zt.logfn_sigsafe = zlog_crashlog_sigsafe; + zlog_crashlog.fd = -1; + + zlog_target_replace(NULL, &zlog_crashlog.zt); +} + +/* fixed logging for test/auxiliary programs */ + +static struct zlt_fd zlog_aux_stdout; +static bool zlog_is_aux; + +static int zlt_aux_init(const char *prefix, int prio_min) +{ + zlog_is_aux = true; + + zlog_aux_stdout.zt.prio_min = prio_min; + zlog_aux_stdout.zt.logfn = zlog_fd; + zlog_aux_stdout.zt.logfn_sigsafe = zlog_fd_sigsafe; + zlog_aux_stdout.fd = STDOUT_FILENO; + + zlog_target_replace(NULL, &zlog_aux_stdout.zt); + zlog_startup_end(); + return 0; +} + +static int zlt_init(const char *progname, const char *protoname, + unsigned short instance, uid_t uid, gid_t gid) +{ + openlog(progname, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); + return 0; +} + +static int zlt_fini(void) +{ + closelog(); + return 0; +} + +/* fixed startup logging to stderr */ + +static struct zlt_fd zlog_startup_stderr; + +__attribute__((_CONSTRUCTOR(450))) static void zlog_startup_init(void) +{ + zlog_startup_stderr.zt.prio_min = LOG_WARNING; + zlog_startup_stderr.zt.logfn = zlog_fd; + zlog_startup_stderr.zt.logfn_sigsafe = zlog_fd_sigsafe; + zlog_startup_stderr.fd = STDERR_FILENO; + + zlog_target_replace(NULL, &zlog_startup_stderr.zt); + + hook_register(zlog_aux_init, zlt_aux_init); + hook_register(zlog_init, zlt_init); + hook_register(zlog_fini, zlt_fini); +} + +void zlog_startup_end(void) +{ + static bool startup_ended = false; + + if (startup_ended) + return; + startup_ended = true; + + zlog_target_replace(&zlog_startup_stderr.zt, NULL); + + if (zlog_is_aux) + return; + + /* until here, crashlogs go to stderr */ + zlog_crashlog_init(); +} + +/* syslog */ + +struct zlt_syslog { + struct zlog_target zt; + + int syslog_facility; +}; + +static void zlog_syslog(struct zlog_target *zt, struct zlog_msg *msgs[], + size_t nmsgs) +{ + size_t i; + struct zlt_syslog *zte = container_of(zt, struct zlt_syslog, zt); + + for (i = 0; i < nmsgs; i++) { + if (zlog_msg_prio(msgs[i]) > zt->prio_min) + continue; + + syslog(zlog_msg_prio(msgs[i]) | zte->syslog_facility, "%s", + zlog_msg_text(msgs[i], NULL)); + } +} + +#ifndef _PATH_LOG +#define _PATH_LOG "/dev/log" +#endif + +static void zlog_syslog_sigsafe(struct zlog_target *zt, const char *text, + size_t len) +{ + static int syslog_fd = -1; + + char hdr[192]; + size_t hdrlen; + struct iovec iov[2]; + + if (syslog_fd == -1) { + syslog_fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (syslog_fd >= 0) { + struct sockaddr_un sa; + socklen_t salen = sizeof(sa); + + sa.sun_family = AF_UNIX; + strlcpy(sa.sun_path, _PATH_LOG, sizeof(sa.sun_path)); +#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN + salen = sa.sun_len = SUN_LEN(&sa); +#endif + if (connect(syslog_fd, (struct sockaddr *)&sa, salen)) { + close(syslog_fd); + syslog_fd = -1; + } + } + + /* /dev/log could be a fifo instead of a socket */ + if (syslog_fd == -1) { + syslog_fd = open(_PATH_LOG, O_WRONLY | O_NOCTTY); + if (syslog_fd < 0) + /* give up ... */ + syslog_fd = -2; + } + } + + if (syslog_fd == -2) + return; + + /* note zlog_prefix includes trailing ": ", need to cut off 2 chars */ + hdrlen = snprintfrr(hdr, sizeof(hdr), "<%d>%.*s[%ld]: ", LOG_CRIT, + zlog_prefixsz > 2 ? (int)(zlog_prefixsz - 2) : 0, + zlog_prefix, (long)getpid()); + + iov[0].iov_base = hdr; + iov[0].iov_len = hdrlen; + + iov[1].iov_base = (char *)text; + iov[1].iov_len = len; + + writev(syslog_fd, iov, array_size(iov)); +} + + +static pthread_mutex_t syslog_cfg_mutex = PTHREAD_MUTEX_INITIALIZER; +static struct zlt_syslog *zlt_syslog; +static int syslog_facility = LOG_DAEMON; +static int syslog_prio_min = ZLOG_DISABLED; + +void zlog_syslog_set_facility(int facility) +{ + struct zlog_target *newztc; + struct zlt_syslog *newzt; + + frr_with_mutex(&syslog_cfg_mutex) { + if (facility == syslog_facility) + return; + syslog_facility = facility; + + if (syslog_prio_min == ZLOG_DISABLED) + return; + + newztc = zlog_target_clone(MTYPE_LOG_SYSL, &zlt_syslog->zt, + sizeof(*newzt)); + newzt = container_of(newztc, struct zlt_syslog, zt); + newzt->syslog_facility = syslog_facility; + + zlog_target_free(MTYPE_LOG_SYSL, + zlog_target_replace(&zlt_syslog->zt, + &newzt->zt)); + + zlt_syslog = newzt; + } +} + +int zlog_syslog_get_facility(void) +{ + frr_with_mutex(&syslog_cfg_mutex) { + return syslog_facility; + } + assert(0); +} + +void zlog_syslog_set_prio_min(int prio_min) +{ + struct zlog_target *newztc; + struct zlt_syslog *newzt = NULL; + + frr_with_mutex(&syslog_cfg_mutex) { + if (prio_min == syslog_prio_min) + return; + syslog_prio_min = prio_min; + + if (syslog_prio_min != ZLOG_DISABLED) { + newztc = zlog_target_clone(MTYPE_LOG_SYSL, + &zlt_syslog->zt, + sizeof(*newzt)); + newzt = container_of(newztc, struct zlt_syslog, zt); + newzt->zt.prio_min = prio_min; + newzt->zt.logfn = zlog_syslog; + newzt->zt.logfn_sigsafe = zlog_syslog_sigsafe; + newzt->syslog_facility = syslog_facility; + } + + zlog_target_free(MTYPE_LOG_SYSL, + zlog_target_replace(&zlt_syslog->zt, + &newzt->zt)); + + zlt_syslog = newzt; + } +} + +int zlog_syslog_get_prio_min(void) +{ + frr_with_mutex(&syslog_cfg_mutex) { + return syslog_prio_min; + } + assert(0); +} diff --git a/lib/zlog_targets.h b/lib/zlog_targets.h new file mode 100644 index 0000000000..6faf722ffd --- /dev/null +++ b/lib/zlog_targets.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015-19 David Lamparter, for NetDEF, Inc. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _FRR_ZLOG_TARGETS_H +#define _FRR_ZLOG_TARGETS_H + +#include <pthread.h> + +#include "zlog.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* multiple file log targets can be active */ + +struct zlt_fd; + +struct zlog_cfg_file { + struct zlt_fd *active; + + pthread_mutex_t cfg_mtx; + + /* call zlog_file_set_other() to apply these */ + int prio_min; + char ts_subsec; + bool record_priority; + + /* call zlog_file_set_filename/fd() to change this */ + char *filename; + int fd; + + void (*zlog_wrap)(struct zlog_target *zt, struct zlog_msg *msgs[], + size_t nmsgs); +}; + +extern void zlog_file_init(struct zlog_cfg_file *zcf); +extern void zlog_file_fini(struct zlog_cfg_file *zcf); + +extern void zlog_file_set_other(struct zlog_cfg_file *zcf); +extern bool zlog_file_set_filename(struct zlog_cfg_file *zcf, const char *name); +extern bool zlog_file_set_fd(struct zlog_cfg_file *zcf, int fd); +extern bool zlog_file_rotate(struct zlog_cfg_file *zcf); + +extern void zlog_fd(struct zlog_target *zt, struct zlog_msg *msgs[], + size_t nmsgs); + +/* syslog is always limited to one target */ + +extern void zlog_syslog_set_facility(int facility); +extern int zlog_syslog_get_facility(void); + +/* use ZLOG_DISABLED to disable */ +extern void zlog_syslog_set_prio_min(int prio_min); +extern int zlog_syslog_get_prio_min(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _FRR_ZLOG_TARGETS_H */ diff --git a/m4/ax_python.m4 b/m4/ax_python.m4 index d293da5257..9f43ea0ab1 100644 --- a/m4/ax_python.m4 +++ b/m4/ax_python.m4 @@ -3,7 +3,7 @@ dnl 2019 David Lamparter for NetDEF, Inc. dnl SPDX-License-Identifier: GPL-2.0-or-later dnl the _ at the beginning will be cut off (to support the empty version string) -m4_define_default([_FRR_PY_VERS], [_3 _ _2 _3.8 _3.7 _3.6 _3.5 _3.4 _3.3 _3.2 _2.7]) +m4_define_default([_FRR_PY_VERS], [_3 _3.10 _3.9 _3.8 _3.7 _3.6 _3.5 _3.4 _3.3 _3.2 _ _2 _2.7]) dnl check basic interpreter properties (py2/py3) dnl doubles as simple check whether the interpreter actually works diff --git a/nhrpd/linux.c b/nhrpd/linux.c index 85e941e7ba..59c82b1c55 100644 --- a/nhrpd/linux.c +++ b/nhrpd/linux.c @@ -25,6 +25,7 @@ #include <linux/ip.h> #include <linux/if_arp.h> #include <linux/if_tunnel.h> +#include <linux/limits.h> #include "nhrp_protocol.h" #include "os.h" @@ -127,10 +128,11 @@ static int linux_configure_arp(const char *iface, int on) static int linux_icmp_redirect_off(const char *iface) { - char fname[256]; + char fname[PATH_MAX]; int fd, ret = -1; - sprintf(fname, "/proc/sys/net/ipv4/conf/%s/send_redirects", iface); + snprintf(fname, sizeof(fname), + "/proc/sys/net/ipv4/conf/%s/send_redirects", iface); fd = open(fname, O_WRONLY); if (fd < 0) return -1; diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index cc35f09aae..fe681b4052 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -17,16 +17,22 @@ #include "nhrpd.h" #include "netlink.h" +static int nhrp_config_write(struct vty *vty); static struct cmd_node zebra_node = { + .name = "zebra", .node = ZEBRA_NODE, + .parent_node = CONFIG_NODE, .prompt = "%s(config-router)# ", - .vtysh = 1, + .config_write = nhrp_config_write, }; +static int interface_config_write(struct vty *vty); static struct cmd_node nhrp_interface_node = { + .name = "interface", .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, .prompt = "%s(config-if)# ", - .vtysh = 1, + .config_write = interface_config_write, }; #define NHRP_DEBUG_FLAGS_CMD "<all|common|event|interface|kernel|route|vici>" @@ -1096,7 +1102,7 @@ static int interface_config_write(struct vty *vty) void nhrp_config_init(void) { - install_node(&zebra_node, nhrp_config_write); + install_node(&zebra_node); install_default(ZEBRA_NODE); /* access-list commands */ @@ -1120,7 +1126,7 @@ void nhrp_config_init(void) install_element(CONFIG_NODE, &no_nhrp_nflog_group_cmd); /* interface specific commands */ - install_node(&nhrp_interface_node, interface_config_write); + install_node(&nhrp_interface_node); if_cmd_init(); install_element(INTERFACE_NODE, &tunnel_protection_cmd); diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am index 42a6380b17..8cfc25b7bd 100644 --- a/nhrpd/subdir.am +++ b/nhrpd/subdir.am @@ -4,7 +4,7 @@ if NHRPD sbin_PROGRAMS += nhrpd/nhrpd -vtysh_scan += $(top_srcdir)/nhrpd/nhrp_vty.c +vtysh_scan += nhrpd/nhrp_vty.c man8 += $(MANBUILD)/frr-nhrpd.8 endif diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 85d02c186b..b144c6804e 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -332,11 +332,12 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, if (req == on->last_ls_req) { /* sanity check refcount */ assert(req->lock >= 2); - ospf6_lsa_unlock(req); + req = ospf6_lsa_unlock(req); on->last_ls_req = NULL; } - ospf6_lsdb_remove(req, - on->request_list); + if (req) + ospf6_lsdb_remove( + req, on->request_list); ospf6_check_nbr_loading(on); continue; } @@ -348,7 +349,7 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa, zlog_debug( "Received is newer, remove requesting"); if (req == on->last_ls_req) { - ospf6_lsa_unlock(req); + req = ospf6_lsa_unlock(req); on->last_ls_req = NULL; } if (req) diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 93265afc43..1209997514 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -1943,8 +1943,13 @@ static int config_write_ospf6_interface(struct vty *vty) return 0; } +static int config_write_ospf6_interface(struct vty *vty); static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */ + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = config_write_ospf6_interface, }; static int ospf6_ifp_create(struct interface *ifp) @@ -2001,7 +2006,7 @@ static int ospf6_ifp_destroy(struct interface *ifp) void ospf6_interface_init(void) { /* Install interface node. */ - install_node(&interface_node, config_write_ospf6_interface); + install_node(&interface_node); if_cmd_init(); if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up, ospf6_ifp_down, ospf6_ifp_destroy); diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index bcfd975879..9e7479c797 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -397,10 +397,10 @@ void ospf6_lsa_show_summary(struct vty *vty, struct ospf6_lsa *lsa) (unsigned long)ntohl(lsa->header->seqnum), handler->lh_get_prefix_str(lsa, buf, sizeof(buf), 0)); } else if (type != OSPF6_LSTYPE_UNKNOWN) { - sprintf(tmpbuf, "%-4s %-15s%-15s%4hu %8lx", - ospf6_lstype_short_name(lsa->header->type), id, - adv_router, ospf6_lsa_age_current(lsa), - (unsigned long)ntohl(lsa->header->seqnum)); + snprintf(tmpbuf, sizeof(tmpbuf), "%-4s %-15s%-15s%4hu %8lx", + ospf6_lstype_short_name(lsa->header->type), id, + adv_router, ospf6_lsa_age_current(lsa), + (unsigned long)ntohl(lsa->header->seqnum)); while (handler->lh_get_prefix_str(lsa, buf, sizeof(buf), cnt) != NULL) { @@ -608,16 +608,17 @@ void ospf6_lsa_lock(struct ospf6_lsa *lsa) } /* decrement reference counter of struct ospf6_lsa */ -void ospf6_lsa_unlock(struct ospf6_lsa *lsa) +struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *lsa) { /* decrement reference counter */ assert(lsa->lock > 0); lsa->lock--; if (lsa->lock != 0) - return; + return lsa; ospf6_lsa_delete(lsa); + return NULL; } diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 02f9f9d26c..5519dd1b80 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -227,7 +227,7 @@ extern void ospf6_lsa_delete(struct ospf6_lsa *lsa); extern struct ospf6_lsa *ospf6_lsa_copy(struct ospf6_lsa *); extern void ospf6_lsa_lock(struct ospf6_lsa *); -extern void ospf6_lsa_unlock(struct ospf6_lsa *); +extern struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *); extern int ospf6_lsa_expire(struct thread *); extern int ospf6_lsa_refresh(struct thread *); diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index e4bed7a79d..4dbe5ca321 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -168,6 +168,7 @@ struct quagga_signal_t ospf6_signals[] = { static const struct frr_yang_module_info *const ospf6d_yang_modules[] = { &frr_interface_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(ospf6d, OSPF6, .vty_port = OSPF6_VTY_PORT, diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index 21f9b0722c..31862a2298 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1948,9 +1948,9 @@ int ospf6_lsreq_send(struct thread *thread) } if (last_req != NULL) { - if (on->last_ls_req != NULL) { - ospf6_lsa_unlock(on->last_ls_req); - } + if (on->last_ls_req != NULL) + on->last_ls_req = ospf6_lsa_unlock(on->last_ls_req); + ospf6_lsa_lock(last_req); on->last_ls_req = last_req; } diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index dc10fa52cb..dd672dd1c5 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -1112,16 +1112,21 @@ static int config_write_ospf6(struct vty *vty) return 0; } +static int config_write_ospf6(struct vty *vty); /* OSPF6 node structure. */ static struct cmd_node ospf6_node = { - OSPF6_NODE, "%s(config-ospf6)# ", 1 /* VTYSH */ + .name = "ospf6", + .node = OSPF6_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-ospf6)# ", + .config_write = config_write_ospf6, }; /* Install ospf related commands. */ void ospf6_top_init(void) { /* Install ospf6 top node. */ - install_node(&ospf6_node, config_write_ospf6); + install_node(&ospf6_node); install_element(VIEW_NODE, &show_ipv6_ospf6_cmd); install_element(CONFIG_NODE, &router_ospf6_cmd); diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index db61fe087b..17e33902d9 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -69,8 +69,12 @@ struct route_node *route_prev(struct route_node *node) return prev; } +static int config_write_ospf6_debug(struct vty *vty); static struct cmd_node debug_node = { - DEBUG_NODE, "", 1 /* VTYSH */ + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = config_write_ospf6_debug, }; static int config_write_ospf6_debug(struct vty *vty) @@ -1216,7 +1220,7 @@ void ospf6_init(void) prefix_list_delete_hook(ospf6_plist_del); ospf6_bfd_init(); - install_node(&debug_node, config_write_ospf6_debug); + install_node(&debug_node); install_element_ospf6_debug_message(); install_element_ospf6_debug_lsa(); diff --git a/ospf6d/subdir.am b/ospf6d/subdir.am index 570b077cb1..9bb6838310 100644 --- a/ospf6d/subdir.am +++ b/ospf6d/subdir.am @@ -7,21 +7,21 @@ noinst_LIBRARIES += ospf6d/libospf6.a sbin_PROGRAMS += ospf6d/ospf6d dist_examples_DATA += ospf6d/ospf6d.conf.sample vtysh_scan += \ - $(top_srcdir)/ospf6d/ospf6_abr.c \ - $(top_srcdir)/ospf6d/ospf6_asbr.c \ - $(top_srcdir)/ospf6d/ospf6_area.c \ - $(top_srcdir)/ospf6d/ospf6_bfd.c \ - $(top_srcdir)/ospf6d/ospf6_flood.c \ - $(top_srcdir)/ospf6d/ospf6_interface.c \ - $(top_srcdir)/ospf6d/ospf6_intra.c \ - $(top_srcdir)/ospf6d/ospf6_lsa.c \ - $(top_srcdir)/ospf6d/ospf6_message.c \ - $(top_srcdir)/ospf6d/ospf6_neighbor.c \ - $(top_srcdir)/ospf6d/ospf6_route.c \ - $(top_srcdir)/ospf6d/ospf6_spf.c \ - $(top_srcdir)/ospf6d/ospf6_top.c \ - $(top_srcdir)/ospf6d/ospf6_zebra.c \ - $(top_srcdir)/ospf6d/ospf6d.c \ + ospf6d/ospf6_abr.c \ + ospf6d/ospf6_asbr.c \ + ospf6d/ospf6_area.c \ + ospf6d/ospf6_bfd.c \ + ospf6d/ospf6_flood.c \ + ospf6d/ospf6_interface.c \ + ospf6d/ospf6_intra.c \ + ospf6d/ospf6_lsa.c \ + ospf6d/ospf6_message.c \ + ospf6d/ospf6_neighbor.c \ + ospf6d/ospf6_route.c \ + ospf6d/ospf6_spf.c \ + ospf6d/ospf6_top.c \ + ospf6d/ospf6_zebra.c \ + ospf6d/ospf6d.c \ # end if SNMP module_LTLIBRARIES += ospf6d/ospf6d_snmp.la diff --git a/ospfd/ospf_api.c b/ospfd/ospf_api.c index 1ace0977bc..7e7236a3b6 100644 --- a/ospfd/ospf_api.c +++ b/ospfd/ospf_api.c @@ -353,8 +353,8 @@ struct msg *msg_read(int fd) struct msg *msg; struct apimsghdr hdr; uint8_t buf[OSPF_API_MAX_MSG_SIZE]; - int bodylen; - int rlen; + ssize_t bodylen; + ssize_t rlen; /* Read message header */ rlen = readn(fd, (uint8_t *)&hdr, sizeof(struct apimsghdr)); @@ -378,8 +378,13 @@ struct msg *msg_read(int fd) /* Determine body length. */ bodylen = ntohs(hdr.msglen); - if (bodylen > 0) { + if (bodylen > (ssize_t)sizeof(buf)) { + zlog_warn("%s: Body Length of message greater than what we can read", + __func__); + return NULL; + } + if (bodylen > 0) { /* Read message body */ rlen = readn(fd, buf, bodylen); if (rlen < 0) { diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 30940cf010..8747dd1f53 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -306,7 +306,7 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa) } if (IS_DEBUG_OSPF(lsa, LSA)) { - snprintf(buf1, INET_ADDRSTRLEN, "%s", + snprintf(buf1, sizeof(buf1), "%s", inet_ntoa(al->header.adv_router)); zlog_debug( "Route[External]: Calculate AS-external-LSA to %s/%d adv_router %s", diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index a712ecde95..3dcb2b481d 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -82,9 +82,8 @@ const char *ospf_area_name_string(struct ospf_area *area) return "-"; area_id = ntohl(area->area_id.s_addr); - snprintf(buf, OSPF_AREA_STRING_MAXLEN, "%d.%d.%d.%d", - (area_id >> 24) & 0xff, (area_id >> 16) & 0xff, - (area_id >> 8) & 0xff, area_id & 0xff); + snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (area_id >> 24) & 0xff, + (area_id >> 16) & 0xff, (area_id >> 8) & 0xff, area_id & 0xff); return buf; } @@ -100,11 +99,11 @@ const char *ospf_area_desc_string(struct ospf_area *area) type = area->external_routing; switch (type) { case OSPF_AREA_NSSA: - snprintf(buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [NSSA]", + snprintf(buf, sizeof(buf), "%s [NSSA]", ospf_area_name_string(area)); break; case OSPF_AREA_STUB: - snprintf(buf, OSPF_AREA_DESC_STRING_MAXLEN, "%s [Stub]", + snprintf(buf, sizeof(buf), "%s [Stub]", ospf_area_name_string(area)); break; default: @@ -127,7 +126,7 @@ const char *ospf_if_name_string(struct ospf_interface *oi) return oi->ifp->name; ifaddr = ntohl(oi->address->u.prefix4.s_addr); - snprintf(buf, OSPF_IF_STRING_MAXLEN, "%s:%d.%d.%d.%d", oi->ifp->name, + snprintf(buf, sizeof(buf), "%s:%d.%d.%d.%d", oi->ifp->name, (ifaddr >> 24) & 0xff, (ifaddr >> 16) & 0xff, (ifaddr >> 8) & 0xff, ifaddr & 0xff); return buf; @@ -1640,9 +1639,13 @@ DEFUN_NOSH (show_debugging_ospf_instance, return show_debugging_ospf_common(vty, ospf); } +static int config_write_debug(struct vty *vty); /* Debug node. */ static struct cmd_node debug_node = { - DEBUG_NODE, "", 1 /* VTYSH */ + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = config_write_debug, }; static int config_write_debug(struct vty *vty) @@ -1665,7 +1668,7 @@ static int config_write_debug(struct vty *vty) return CMD_SUCCESS; if (ospf->instance) - sprintf(str, " %u", ospf->instance); + snprintf(str, sizeof(str), " %u", ospf->instance); /* debug ospf ism (status|events|timers). */ if (IS_CONF_DEBUG_OSPF(ism, ISM) == OSPF_DEBUG_ISM) @@ -1783,7 +1786,7 @@ static int config_write_debug(struct vty *vty) /* Initialize debug commands. */ void ospf_debug_init(void) { - install_node(&debug_node, config_write_debug); + install_node(&debug_node); install_element(ENABLE_NODE, &show_debugging_ospf_cmd); install_element(ENABLE_NODE, &debug_ospf_ism_cmd); diff --git a/ospfd/ospf_dump_api.c b/ospfd/ospf_dump_api.c index 1196339c34..e24936a473 100644 --- a/ospfd/ospf_dump_api.c +++ b/ospfd/ospf_dump_api.c @@ -105,7 +105,7 @@ char *ospf_options_dump(uint8_t options) { static char buf[OSPF_OPTION_STR_MAXLEN]; - snprintf(buf, OSPF_OPTION_STR_MAXLEN, "*|%s|%s|%s|%s|%s|%s|%s", + snprintf(buf, sizeof(buf), "*|%s|%s|%s|%s|%s|%s|%s", (options & OSPF_OPTION_O) ? "O" : "-", (options & OSPF_OPTION_DC) ? "DC" : "-", (options & OSPF_OPTION_EA) ? "EA" : "-", diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 088f7f31c7..d089ea76cd 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -33,6 +33,7 @@ #include "hash.h" #include "sockunion.h" /* for inet_aton() */ #include "checksum.h" +#include "network.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -298,7 +299,8 @@ const char *dump_lsa_key(struct ospf_lsa *lsa) strlcpy(id, inet_ntoa(lsah->id), sizeof(id)); strlcpy(ar, inet_ntoa(lsah->adv_router), sizeof(ar)); - sprintf(buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar); + snprintf(buf, sizeof(buf), "Type%d,id(%s),ar(%s)", lsah->type, + id, ar); } else strlcpy(buf, "NULL", sizeof(buf)); @@ -3523,7 +3525,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa) * 1680s * and 1740s. */ - delay = (random() % (max_delay - min_delay)) + min_delay; + delay = (frr_weak_random() % (max_delay - min_delay)) + + min_delay; current_index = ospf->lsa_refresh_queue.index + (monotime(NULL) - ospf->lsa_refresher_started) diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 4d6ebb40eb..6a3ba9902d 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -128,6 +128,7 @@ struct quagga_signal_t ospf_signals[] = { static const struct frr_yang_module_info *const ospfd_yang_modules[] = { &frr_interface_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(ospfd, OSPF, .vty_port = OSPF_VTY_PORT, diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 9cd83c245c..47688babbf 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -33,6 +33,7 @@ #include "table.h" #include "log.h" #include "command.h" +#include "network.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -723,7 +724,7 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) /* Start DD exchange protocol */ if (state == NSM_ExStart) { if (nbr->dd_seqnum == 0) - nbr->dd_seqnum = (uint32_t)random(); + nbr->dd_seqnum = (uint32_t)frr_weak_random(); else nbr->dd_seqnum++; diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 550e5ee9ee..63191d5cb5 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -784,7 +784,7 @@ static struct ospf_area *ospfStubAreaLookup(struct variable *v, oid name[], area = ospf_area_lookup_by_area_id(ospf, *addr); - if (area->external_routing == OSPF_AREA_STUB) + if (area && area->external_routing == OSPF_AREA_STUB) return area; else return NULL; diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index 7a786ba7ab..2a35bd2ef9 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -2094,7 +2094,7 @@ static void show_sr_node(struct vty *vty, struct json_object *json, json_obj = json_object_new_object(); char tmp[2]; - snprintf(tmp, 2, "%u", i); + snprintf(tmp, sizeof(tmp), "%u", i); json_object_string_add(json_obj, tmp, srn->algo[i] == SR_ALGORITHM_SPF ? "SPF" @@ -2129,13 +2129,15 @@ static void show_sr_node(struct vty *vty, struct json_object *json, "--------------------- --------- ---------------\n"); } for (ALL_LIST_ELEMENTS_RO(srn->ext_prefix, node, srp)) { - snprintf(pref, 19, "%s/%u", inet_ntoa(srp->nhlfe.prefv4.prefix), + snprintf(pref, sizeof(pref), "%s/%u", + inet_ntoa(srp->nhlfe.prefv4.prefix), srp->nhlfe.prefv4.prefixlen); - snprintf(sid, 22, "SR Pfx (idx %u)", srp->sid); + snprintf(sid, sizeof(sid), "SR Pfx (idx %u)", srp->sid); if (srp->nhlfe.label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srp->nhlfe.label_out); + snprintf(label, sizeof(label), "%u", + srp->nhlfe.label_out); itf = if_lookup_by_index(srp->nhlfe.ifindex, VRF_DEFAULT); if (json) { if (!json_prefix) { @@ -2164,14 +2166,15 @@ static void show_sr_node(struct vty *vty, struct json_object *json, } for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, srl)) { - snprintf(pref, 19, "%s/%u", + snprintf(pref, sizeof(pref), "%s/%u", inet_ntoa(srl->nhlfe[0].prefv4.prefix), srl->nhlfe[0].prefv4.prefixlen); - snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[0]); + snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)", srl->sid[0]); if (srl->nhlfe[0].label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srl->nhlfe[0].label_out); + snprintf(label, sizeof(label), "%u", + srl->nhlfe[0].label_out); itf = if_lookup_by_index(srl->nhlfe[0].ifindex, VRF_DEFAULT); if (json) { if (!json_link) { @@ -2194,11 +2197,13 @@ static void show_sr_node(struct vty *vty, struct json_object *json, json_object_array_add(json_link, json_obj); /* Backup Link */ json_obj = json_object_new_object(); - snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); + snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)", + srl->sid[1]); if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srl->nhlfe[0].label_out); + snprintf(label, sizeof(label), "%u", + srl->nhlfe[0].label_out); json_object_string_add(json_obj, "prefix", pref); json_object_int_add(json_obj, "sid", srl->sid[1]); json_object_int_add(json_obj, "inputLabel", @@ -2215,11 +2220,13 @@ static void show_sr_node(struct vty *vty, struct json_object *json, srl->nhlfe[0].label_in, label, sid, itf ? itf->name : "-", inet_ntoa(srl->nhlfe[0].nexthop)); - snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]); + snprintf(sid, sizeof(sid), "SR Adj. (lbl %u)", + srl->sid[1]); if (srl->nhlfe[1].label_out == MPLS_LABEL_IMPLICIT_NULL) - sprintf(label, "pop"); + snprintf(label, sizeof(label), "pop"); else - sprintf(label, "%u", srl->nhlfe[1].label_out); + snprintf(label, sizeof(label), "%u", + srl->nhlfe[1].label_out); vty_out(vty, "%18s %8u %9s %21s %9s %15s\n", pref, srl->nhlfe[1].label_in, label, sid, itf ? itf->name : "-", diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index ea73834a66..71275e49d2 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -83,7 +83,8 @@ static void area_id2str(char *buf, int length, struct in_addr *area_id, if (area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) inet_ntop(AF_INET, area_id, buf, length); else - sprintf(buf, "%lu", (unsigned long)ntohl(area_id->s_addr)); + snprintf(buf, length, "%lu", + (unsigned long)ntohl(area_id->s_addr)); } static int str2metric(const char *str, int *metric) @@ -9263,8 +9264,8 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf, char buf1[19]; - snprintf(buf1, 19, "%s/%d", inet_ntoa(rn->p.u.prefix4), - rn->p.prefixlen); + snprintf(buf1, sizeof(buf1), "%s/%d", + inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); json_route = json_object_new_object(); if (json) { json_object_object_add(json, buf1, json_route); @@ -9997,7 +9998,7 @@ static int config_write_interface(struct vty *vty) static int config_write_network_area(struct vty *vty, struct ospf *ospf) { struct route_node *rn; - uint8_t buf[INET_ADDRSTRLEN]; + char buf[INET_ADDRSTRLEN]; /* `network area' print. */ for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) @@ -10006,12 +10007,12 @@ static int config_write_network_area(struct vty *vty, struct ospf *ospf) /* Create Area ID string by specified Area ID format. */ if (n->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD) - inet_ntop(AF_INET, &n->area_id, (char *)buf, + inet_ntop(AF_INET, &n->area_id, buf, sizeof(buf)); else - sprintf((char *)buf, "%lu", - (unsigned long int)ntohl( - n->area_id.s_addr)); + snprintf(buf, sizeof(buf), "%lu", + (unsigned long int)ntohl( + n->area_id.s_addr)); /* Network print. */ vty_out(vty, " network %s/%d area %s\n", @@ -10026,13 +10027,13 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf) { struct listnode *node; struct ospf_area *area; - uint8_t buf[INET_ADDRSTRLEN]; + char buf[INET_ADDRSTRLEN]; /* Area configuration print. */ for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) { struct route_node *rn1; - area_id2str((char *)buf, sizeof(buf), &area->area_id, + area_id2str(buf, sizeof(buf), &area->area_id, area->area_id_fmt); if (area->auth_type != OSPF_AUTH_NULL) { @@ -10555,14 +10556,21 @@ void ospf_vty_show_init(void) } +static int config_write_interface(struct vty *vty); /* ospfd's interface node. */ -static struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1}; +static struct cmd_node interface_node = { + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = config_write_interface, +}; /* Initialization of OSPF interface. */ static void ospf_vty_if_init(void) { /* Install interface node. */ - install_node(&interface_node, config_write_interface); + install_node(&interface_node); if_cmd_init(); /* "ip ospf authentication" commands. */ @@ -10668,7 +10676,14 @@ static void ospf_vty_zebra_init(void) #endif /* 0 */ } -static struct cmd_node ospf_node = {OSPF_NODE, "%s(config-router)# ", 1}; +static int ospf_config_write(struct vty *vty); +static struct cmd_node ospf_node = { + .name = "ospf", + .node = OSPF_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", + .config_write = ospf_config_write, +}; static void ospf_interface_clear(struct interface *ifp) { @@ -10741,7 +10756,7 @@ void ospf_vty_clear_init(void) void ospf_vty_init(void) { /* Install ospf top node. */ - install_node(&ospf_node, ospf_config_write); + install_node(&ospf_node); /* "router ospf" commands. */ install_element(CONFIG_NODE, &router_ospf_cmd); diff --git a/ospfd/subdir.am b/ospfd/subdir.am index 6de4099c5b..447ddf9cbb 100644 --- a/ospfd/subdir.am +++ b/ospfd/subdir.am @@ -7,14 +7,14 @@ noinst_LIBRARIES += ospfd/libfrrospf.a sbin_PROGRAMS += ospfd/ospfd dist_examples_DATA += ospfd/ospfd.conf.sample vtysh_scan += \ - $(top_srcdir)/ospfd/ospf_bfd.c \ - $(top_srcdir)/ospfd/ospf_dump.c \ - $(top_srcdir)/ospfd/ospf_opaque.c \ - $(top_srcdir)/ospfd/ospf_ri.c \ - $(top_srcdir)/ospfd/ospf_routemap.c \ - $(top_srcdir)/ospfd/ospf_te.c \ - $(top_srcdir)/ospfd/ospf_sr.c \ - $(top_srcdir)/ospfd/ospf_vty.c \ + ospfd/ospf_bfd.c \ + ospfd/ospf_dump.c \ + ospfd/ospf_opaque.c \ + ospfd/ospf_ri.c \ + ospfd/ospf_routemap.c \ + ospfd/ospf_te.c \ + ospfd/ospf_sr.c \ + ospfd/ospf_vty.c \ # end if SNMP module_LTLIBRARIES += ospfd/ospfd_snmp.la @@ -72,8 +72,9 @@ ospfdheader_HEADERS = \ # end endif -ospfd/ospf_vty_clippy.c: $(CLIPPY_DEPS) -ospfd/ospf_vty.$(OBJEXT): ospfd/ospf_vty_clippy.c +clippy_scan += \ + ospfd/ospf_vty.c \ + # end noinst_HEADERS += \ ospfd/ospf_abr.h \ diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index 4a3a9ca382..a52c2d1e30 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -677,7 +677,12 @@ DEFPY (show_pbr_interface, /* PBR debugging CLI ------------------------------------------------------- */ -static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = pbr_debug_config_write, +}; DEFPY(debug_pbr, debug_pbr_cmd, @@ -725,8 +730,13 @@ DEFUN_NOSH(show_debugging_pbr, /* ------------------------------------------------------------------------- */ +static int pbr_interface_config_write(struct vty *vty); static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */ + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = pbr_interface_config_write, }; static int pbr_interface_config_write(struct vty *vty) @@ -754,8 +764,15 @@ static int pbr_interface_config_write(struct vty *vty) return 1; } +static int pbr_vty_map_config_write(struct vty *vty); /* PBR map node structure. */ -static struct cmd_node pbr_map_node = {PBRMAP_NODE, "%s(config-pbr-map)# ", 1}; +static struct cmd_node pbr_map_node = { + .name = "pbr-map", + .node = PBRMAP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pbr-map)# ", + .config_write = pbr_vty_map_config_write, +}; static int pbr_vty_map_config_write_sequence(struct vty *vty, struct pbr_map *pbrm, @@ -833,15 +850,13 @@ void pbr_vty_init(void) { cmd_variable_handler_register(pbr_map_name); - install_node(&interface_node, - pbr_interface_config_write); + install_node(&interface_node); if_cmd_init(); - install_node(&pbr_map_node, - pbr_vty_map_config_write); + install_node(&pbr_map_node); /* debug */ - install_node(&debug_node, pbr_debug_config_write); + install_node(&debug_node); install_element(VIEW_NODE, &debug_pbr_cmd); install_element(CONFIG_NODE, &debug_pbr_cmd); install_element(VIEW_NODE, &show_debugging_pbr_cmd); diff --git a/pbrd/subdir.am b/pbrd/subdir.am index c55f0b41cc..42f279988b 100644 --- a/pbrd/subdir.am +++ b/pbrd/subdir.am @@ -7,8 +7,8 @@ noinst_LIBRARIES += pbrd/libpbr.a sbin_PROGRAMS += pbrd/pbrd dist_examples_DATA += pbrd/pbrd.conf.sample vtysh_scan += \ - $(top_srcdir)/pbrd/pbr_vty.c \ - $(top_srcdir)/pbrd/pbr_debug.c \ + pbrd/pbr_vty.c \ + pbrd/pbr_debug.c \ # end man8 += $(MANBUILD)/frr-pbrd.8 endif @@ -33,11 +33,10 @@ noinst_HEADERS += \ pbrd/pbr_vrf.h \ # end -pbrd/pbr_vty_clippy.c: $(CLIPPY_DEPS) -pbrd/pbr_vty.$(OBJEXT): pbrd/pbr_vty_clippy.c - -pbrd/pbr_debug_clippy.c: $(CLIPPY_DEPS) -pbrd/pbr_debug.$(OBJEXT): pbrd/pbr_debug_clippy.c +clippy_scan += \ + pbrd/pbr_debug.c \ + pbrd/pbr_vty.c \ + # end pbrd_pbrd_SOURCES = pbrd/pbr_main.c pbrd_pbrd_LDADD = pbrd/libpbr.a lib/libfrr.la $(LIBCAP) diff --git a/pimd/mtracebis.c b/pimd/mtracebis.c index 2f10abccee..1b812de92c 100644 --- a/pimd/mtracebis.c +++ b/pimd/mtracebis.c @@ -108,7 +108,7 @@ static const char *rtg_proto_str(enum mtrace_rtg_proto proto) case MTRACE_RTG_PROTO_PIM_ASSERT: return "PIM assert"; default: - sprintf(buf, "unknown protocol (%d)", proto); + snprintf(buf, sizeof(buf), "unknown protocol (%d)", proto); return buf; } } @@ -161,7 +161,7 @@ static const char *fwd_code_str(enum mtrace_fwd_code code) case MTRACE_FWD_CODE_ADMIN_PROHIB: return "admin. prohib."; default: - sprintf(buf, "unknown fwd. code (%d)", code); + snprintf(buf, sizeof(buf), "unknown fwd. code (%d)", code); return buf; } } diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index d6c500cdb0..fe9b5e1beb 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -70,10 +70,19 @@ #endif static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */ + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = pim_interface_config_write, }; -static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = pim_debug_config_write, +}; static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[], const int argc, int *idx) @@ -2501,10 +2510,12 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty, pim_upstream_state2brief_str(up->join_state, state_str, sizeof(state_str)); if (up->reg_state != PIM_REG_NOINFO) { char tmp_str[PIM_REG_STATE_STR_LEN]; + char tmp[sizeof(state_str) + 1]; - sprintf(state_str + strlen(state_str), ",%s", - pim_reg_state2brief_str(up->reg_state, tmp_str, - sizeof(tmp_str))); + snprintf(tmp, sizeof(tmp), ",%s", + pim_reg_state2brief_str(up->reg_state, tmp_str, + sizeof(tmp_str))); + strlcat(state_str, tmp, sizeof(state_str)); } if (uj) { @@ -3410,15 +3421,24 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj) time_t now; json_object *json = NULL; json_object *json_iface = NULL; - json_object *json_row = NULL; + json_object *json_group = NULL; + json_object *json_groups = NULL; now = pim_time_monotonic_sec(); - if (uj) + if (uj) { json = json_object_new_object(); - else + json_object_int_add(json, "totalGroups", pim->igmp_group_count); + json_object_int_add(json, "watermarkLimit", + pim->igmp_watermark_limit); + } else { + vty_out(vty, "Total IGMP groups: %u\n", pim->igmp_group_count); + vty_out(vty, "Watermark warn limit(%s): %u\n", + pim->igmp_watermark_limit ? "Set" : "Not Set", + pim->igmp_watermark_limit); vty_out(vty, "Interface Address Group Mode Timer Srcs V Uptime \n"); + } /* scan interfaces */ FOR_ALL_INTERFACES (pim->vrf, ifp) { @@ -3465,37 +3485,44 @@ static void igmp_show_groups(struct pim_instance *pim, struct vty *vty, bool uj) json_object_object_add( json, ifp->name, json_iface); + json_groups = + json_object_new_array(); + json_object_object_add( + json_iface, + "groups", + json_groups); } - json_row = json_object_new_object(); - json_object_string_add( - json_row, "source", ifaddr_str); - json_object_string_add( - json_row, "group", group_str); + json_group = json_object_new_object(); + json_object_string_add(json_group, + "source", + ifaddr_str); + json_object_string_add(json_group, + "group", + group_str); if (grp->igmp_version == 3) json_object_string_add( - json_row, "mode", + json_group, "mode", grp->group_filtermode_isexcl ? "EXCLUDE" : "INCLUDE"); - json_object_string_add(json_row, + json_object_string_add(json_group, "timer", hhmmss); json_object_int_add( - json_row, "sourcesCount", + json_group, "sourcesCount", grp->group_source_list ? listcount( grp->group_source_list) : 0); - json_object_int_add(json_row, "version", - grp->igmp_version); + json_object_int_add( + json_group, "version", + grp->igmp_version); json_object_string_add( - json_row, "uptime", uptime); - json_object_object_add(json_iface, - group_str, - json_row); - + json_group, "uptime", uptime); + json_object_array_add(json_groups, + json_group); } else { vty_out(vty, "%-16s %-15s %-15s %4s %8s %4d %d %8s\n", @@ -6856,6 +6883,35 @@ DEFUN (no_ip_pim_packets, return CMD_SUCCESS; } +DEFPY (igmp_group_watermark, + igmp_group_watermark_cmd, + "ip igmp watermark-warn (10-60000)$limit", + IP_STR + IGMP_STR + "Configure group limit for watermark warning\n" + "Group count to generate watermark warning\n") +{ + PIM_DECLVAR_CONTEXT(vrf, pim); + pim->igmp_watermark_limit = limit; + + return CMD_SUCCESS; +} + +DEFPY (no_igmp_group_watermark, + no_igmp_group_watermark_cmd, + "no ip igmp watermark-warn [(10-60000)$limit]", + NO_STR + IP_STR + IGMP_STR + "Unconfigure group limit for watermark warning\n" + "Group count to generate watermark warning\n") +{ + PIM_DECLVAR_CONTEXT(vrf, pim); + pim->igmp_watermark_limit = 0; + + return CMD_SUCCESS; +} + DEFUN (ip_pim_v6_secondary, ip_pim_v6_secondary_cmd, "ip pim send-v6-secondary", @@ -10827,11 +10883,10 @@ DEFUN_HIDDEN (ip_pim_mlag, void pim_cmd_init(void) { - install_node(&interface_node, - pim_interface_config_write); /* INTERFACE_NODE */ + install_node(&interface_node); /* INTERFACE_NODE */ if_cmd_init(); - install_node(&debug_node, pim_debug_config_write); + install_node(&debug_node); install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd); @@ -10902,6 +10957,10 @@ void pim_cmd_init(void) install_element(VRF_NODE, &no_ip_pim_ecmp_rebalance_cmd); install_element(CONFIG_NODE, &ip_pim_mlag_cmd); install_element(CONFIG_NODE, &no_ip_pim_mlag_cmd); + install_element(CONFIG_NODE, &igmp_group_watermark_cmd); + install_element(VRF_NODE, &igmp_group_watermark_cmd); + install_element(CONFIG_NODE, &no_igmp_group_watermark_cmd); + install_element(VRF_NODE, &no_igmp_group_watermark_cmd); install_element(INTERFACE_NODE, &interface_ip_igmp_cmd); install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 95b81d5dcb..b25b6eaa8c 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -28,6 +28,7 @@ #include "plist.h" #include "hash.h" #include "ferr.h" +#include "network.h" #include "pimd.h" #include "pim_instance.h" @@ -1103,7 +1104,8 @@ int pim_if_t_override_msec(struct interface *ifp) effective_override_interval_msec = pim_if_effective_override_interval_msec(ifp); - t_override_msec = random() % (effective_override_interval_msec + 1); + t_override_msec = + frr_weak_random() % (effective_override_interval_msec + 1); return t_override_msec; } @@ -1181,7 +1183,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp) return 0; /* t_suppressed = t_periodic * rand(1.1, 1.4) */ - ramount = 1100 + (random() % (1400 - 1100 + 1)); + ramount = 1100 + (frr_weak_random() % (1400 - 1100 + 1)); t_suppressed_msec = router->t_periodic * ramount; return t_suppressed_msec; diff --git a/pimd/pim_igmp.c b/pimd/pim_igmp.c index 8d39d7e800..851b00b2ac 100644 --- a/pimd/pim_igmp.c +++ b/pimd/pim_igmp.c @@ -753,6 +753,39 @@ static void igmp_group_free(struct igmp_group *group) XFREE(MTYPE_PIM_IGMP_GROUP, group); } +static void igmp_group_count_incr(struct igmp_sock *igmp) +{ + struct pim_interface *pim_ifp = igmp->interface->info; + + if (!pim_ifp) + return; + + ++pim_ifp->pim->igmp_group_count; + if (pim_ifp->pim->igmp_group_count + == pim_ifp->pim->igmp_watermark_limit) { + zlog_warn( + "IGMP group count reached watermark limit: %u(vrf: %s)", + pim_ifp->pim->igmp_group_count, + VRF_LOGNAME(pim_ifp->pim->vrf)); + } +} + +static void igmp_group_count_decr(struct igmp_sock *igmp) +{ + struct pim_interface *pim_ifp = igmp->interface->info; + + if (!pim_ifp) + return; + + if (pim_ifp->pim->igmp_group_count == 0) { + zlog_warn("Cannot decrement igmp group count below 0(vrf: %s)", + VRF_LOGNAME(pim_ifp->pim->vrf)); + return; + } + + --pim_ifp->pim->igmp_group_count; +} + void igmp_group_delete(struct igmp_group *group) { struct listnode *src_node; @@ -778,6 +811,7 @@ void igmp_group_delete(struct igmp_group *group) } group_timer_off(group); + igmp_group_count_decr(group->group_igmp_sock); listnode_delete(group->group_igmp_sock->igmp_group_list, group); hash_release(group->group_igmp_sock->igmp_group_hash, group); @@ -879,7 +913,7 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr, igmp->igmp_group_list = list_new(); igmp->igmp_group_list->del = (void (*)(void *))igmp_group_free; - snprintf(hash_name, 64, "IGMP %s hash", ifp->name); + snprintf(hash_name, sizeof(hash_name), "IGMP %s hash", ifp->name); igmp->igmp_group_hash = hash_create(igmp_group_hash_key, igmp_group_hash_equal, hash_name); @@ -1158,6 +1192,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp, group_str, igmp->fd, igmp->interface->name); } + igmp_group_count_incr(igmp); + /* RFC 3376: 6.2.2. Definition of Group Timers diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index ffd872ce03..8eaca75821 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -1945,7 +1945,8 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from, if (!inet_ntop(AF_INET, src, src_str, sizeof(src_str))) - sprintf(src_str, "<source?>"); + snprintf(src_str, sizeof(src_str), + "<source?>"); zlog_debug( " Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s", diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index b4c2dd28cc..b7e49078ef 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -99,7 +99,7 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) pim_msdp_init(pim, router->master); pim_vxlan_init(pim); - snprintf(hash_name, 64, "PIM %s RPF Hash", vrf->name); + snprintf(hash_name, sizeof(hash_name), "PIM %s RPF Hash", vrf->name); pim->rpf_hash = hash_create_size(256, pim_rpf_hash_key, pim_rpf_equal, hash_name); diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index 71bd7c1089..2b76da21b2 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -178,6 +178,8 @@ struct pim_instance { struct list *ssmpingd_list; struct in_addr ssmpingd_group_addr; + unsigned int igmp_group_count; + unsigned int igmp_watermark_limit; unsigned int keep_alive_time; unsigned int rp_keep_alive_time; diff --git a/pimd/pim_main.c b/pimd/pim_main.c index 93b561ba0f..5c4c7151a5 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -75,6 +75,7 @@ struct zebra_privs_t pimd_privs = { static const struct frr_yang_module_info *const pimd_yang_modules[] = { &frr_interface_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT, diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c index 304e6ac6bc..78be914cee 100644 --- a/pimd/pim_mlag.c +++ b/pimd/pim_mlag.c @@ -583,7 +583,9 @@ static void pim_mlag_process_mlagd_state_change(struct mlag_status msg) router->mlag_role = msg.my_role; } - strcpy(router->peerlink_rif, msg.peerlink_rif); + strlcpy(router->peerlink_rif, msg.peerlink_rif, + sizeof(router->peerlink_rif)); + /* XXX - handle the case where we may rx the interface name from the * MLAG daemon before we get the interface from zebra. */ @@ -767,7 +769,7 @@ static void pim_mlag_process_mroute_del(struct mlag_mroute_del msg) int pim_zebra_mlag_handle_msg(struct stream *s, int len) { struct mlag_msg mlag_msg; - char buf[ZLOG_FILTER_LENGTH_MAX]; + char buf[80]; int rc = 0; size_t length; diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 52c989e644..b42092a464 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -1574,14 +1574,16 @@ void pim_msdp_init(struct pim_instance *pim, struct thread_master *master) pim->msdp.master = master; char hash_name[64]; - snprintf(hash_name, 64, "PIM %s MSDP Peer Hash", pim->vrf->name); + snprintf(hash_name, sizeof(hash_name), "PIM %s MSDP Peer Hash", + pim->vrf->name); pim->msdp.peer_hash = hash_create(pim_msdp_peer_hash_key_make, pim_msdp_peer_hash_eq, hash_name); pim->msdp.peer_list = list_new(); pim->msdp.peer_list->del = (void (*)(void *))pim_msdp_peer_free; pim->msdp.peer_list->cmp = (int (*)(void *, void *))pim_msdp_peer_comp; - snprintf(hash_name, 64, "PIM %s MSDP SA Hash", pim->vrf->name); + snprintf(hash_name, sizeof(hash_name), "PIM %s MSDP SA Hash", + pim->vrf->name); pim->msdp.sa_hash = hash_create(pim_msdp_sa_hash_key_make, pim_msdp_sa_hash_eq, hash_name); pim->msdp.sa_list = list_new(); diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 60b7c73d43..a888d68f09 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -103,7 +103,7 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim, pnc->rp_list = list_new(); pnc->rp_list->cmp = pim_rp_list_cmp; - snprintf(hash_name, 64, "PNC %s(%s) Upstream Hash", + snprintf(hash_name, sizeof(hash_name), "PNC %s(%s) Upstream Hash", prefix2str(&pnc->rpf.rpf_addr, buf1, 64), pim->vrf->name); pnc->upstream_hash = hash_create_size(8192, pim_upstream_hash_key, pim_upstream_equal, hash_name); @@ -788,7 +788,11 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS) case NEXTHOP_TYPE_IPV6_IFINDEX: ifp1 = if_lookup_by_index(nexthop->ifindex, pim->vrf_id); - nbr = pim_neighbor_find_if(ifp1); + + if (!ifp1) + nbr = NULL; + else + nbr = pim_neighbor_find_if(ifp1); /* Overwrite with Nbr address as NH addr */ if (nbr) nexthop->gate.ipv4 = nbr->source_addr; diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index f37c140bf2..3976b262e3 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -23,6 +23,7 @@ #include "thread.h" #include "memory.h" #include "if.h" +#include "network.h" #include "pimd.h" #include "pim_pim.h" @@ -878,7 +879,7 @@ int pim_sock_add(struct interface *ifp) old_genid = pim_ifp->pim_generation_id; while (old_genid == pim_ifp->pim_generation_id) - pim_ifp->pim_generation_id = random(); + pim_ifp->pim_generation_id = frr_weak_random(); zlog_info("PIM INTERFACE UP: on interface %s ifindex=%d", ifp->name, ifp->ifindex); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index a9f1d9335a..1611eac95d 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -728,7 +728,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, char rp_str[INET_ADDRSTRLEN]; if (!inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str))) - sprintf(rp_str, "<rp?>"); + snprintf(rp_str, sizeof(rp_str), "<rp?>"); prefix2str(&group, grp_str, sizeof(grp_str)); if (plist) @@ -763,7 +763,9 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, if (!inet_ntop(AF_INET, bsrp, bsrp_str, sizeof(bsrp_str))) - sprintf(bsrp_str, "<bsrp?>"); + snprintf(bsrp_str, + sizeof(bsrp_str), + "<bsrp?>"); zlog_debug( "%s: BSM RP %s found for the group %s", @@ -1261,11 +1263,11 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) char buf[48]; if (rp_info->rp_src == RP_SRC_STATIC) - strcpy(source, "Static"); + strlcpy(source, "Static", sizeof(source)); else if (rp_info->rp_src == RP_SRC_BSR) - strcpy(source, "BSR"); + strlcpy(source, "BSR", sizeof(source)); else - strcpy(source, "None"); + strlcpy(source, "None", sizeof(source)); if (uj) { /* * If we have moved on to a new RP then add the @@ -1289,6 +1291,10 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj) json_rp_rows = json_object_new_array(); json_row = json_object_new_object(); + json_object_string_add( + json_row, "rpAddress", + inet_ntoa(rp_info->rp.rpf_addr.u + .prefix4)); if (rp_info->rp.source_nexthop.interface) json_object_string_add( json_row, "outboundInterface", diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c index f0a71c96ce..504519c8a4 100644 --- a/pimd/pim_sock.c +++ b/pimd/pim_sock.c @@ -288,10 +288,10 @@ int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr, char group_str[INET_ADDRSTRLEN]; char ifaddr_str[INET_ADDRSTRLEN]; if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str))) - sprintf(group_str, "<group?>"); + snprintf(group_str, sizeof(group_str), "<group?>"); if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str, sizeof(ifaddr_str))) - sprintf(ifaddr_str, "<ifaddr?>"); + snprintf(ifaddr_str, sizeof(ifaddr_str), "<ifaddr?>"); flog_err( EC_LIB_SOCKET, @@ -304,10 +304,10 @@ int pim_socket_join(int fd, struct in_addr group, struct in_addr ifaddr, char group_str[INET_ADDRSTRLEN]; char ifaddr_str[INET_ADDRSTRLEN]; if (!inet_ntop(AF_INET, &group, group_str, sizeof(group_str))) - sprintf(group_str, "<group?>"); + snprintf(group_str, sizeof(group_str), "<group?>"); if (!inet_ntop(AF_INET, &ifaddr, ifaddr_str, sizeof(ifaddr_str))) - sprintf(ifaddr_str, "<ifaddr?>"); + snprintf(ifaddr_str, sizeof(ifaddr_str), "<ifaddr?>"); zlog_debug( "Socket fd=%d joined group %s on interface address %s", diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 982fb7e5a5..cf5ea2fa53 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -29,6 +29,7 @@ #include "hash.h" #include "jhash.h" #include "wheel.h" +#include "network.h" #include "pimd.h" #include "pim_pim.h" @@ -1762,7 +1763,7 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up, if (!null_register) { uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD); uint32_t upper = (1.5 * PIM_REGISTER_SUPPRESSION_PERIOD); - time = lower + (random() % (upper - lower + 1)) + time = lower + (frr_weak_random() % (upper - lower + 1)) - PIM_REGISTER_PROBE_PERIOD; } else time = PIM_REGISTER_PROBE_PERIOD; @@ -2164,8 +2165,7 @@ void pim_upstream_init(struct pim_instance *pim) { char name[64]; - snprintf(name, 64, "PIM %s Timer Wheel", - pim->vrf->name); + snprintf(name, sizeof(name), "PIM %s Timer Wheel", pim->vrf->name); pim->upstream_sg_wheel = wheel_init(router->master, 31000, 100, pim_upstream_hash_key, pim_upstream_sg_running, name); diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 72540903be..1f2ca11db3 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -172,9 +172,9 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) char spaces[10]; if (pim->vrf_id == VRF_DEFAULT) - sprintf(spaces, "%s", ""); + snprintf(spaces, sizeof(spaces), "%s", ""); else - sprintf(spaces, "%s", " "); + snprintf(spaces, sizeof(spaces), "%s", " "); writes += pim_msdp_config_write(pim, vty, spaces); @@ -239,6 +239,13 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) vty_out(vty, "%sip pim ecmp\n", spaces); ++writes; } + + if (pim->igmp_watermark_limit != 0) { + vty_out(vty, "%sip igmp watermark-warn %u\n", spaces, + pim->igmp_watermark_limit); + ++writes; + } + if (pim->ssmpingd_list) { struct listnode *node; struct ssmpingd_sock *ss; diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index 84fac4f951..49c221f8ed 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -285,17 +285,17 @@ static int zclient_read_nexthop(struct pim_instance *pim, * If we are sending v6 secondary assume we receive v6 * secondary */ - if (pim->send_v6_secondary) - nbr = pim_neighbor_find_by_secondary( - if_lookup_by_index( - nexthop_tab[num_ifindex] - .ifindex, - nexthop_vrf_id), - &p); + struct interface *ifp = if_lookup_by_index( + nexthop_tab[num_ifindex].ifindex, + nexthop_vrf_id); + + if (!ifp) + nbr = NULL; + else if (pim->send_v6_secondary) + nbr = pim_neighbor_find_by_secondary(ifp, &p); else - nbr = pim_neighbor_find_if(if_lookup_by_index( - nexthop_tab[num_ifindex].ifindex, - nexthop_vrf_id)); + nbr = pim_neighbor_find_if(ifp); + if (nbr) { nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET; diff --git a/pimd/subdir.am b/pimd/subdir.am index 0e30590079..121abea598 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -8,7 +8,7 @@ sbin_PROGRAMS += pimd/pimd bin_PROGRAMS += pimd/mtracebis noinst_PROGRAMS += pimd/test_igmpv3_join dist_examples_DATA += pimd/pimd.conf.sample -vtysh_scan += $(top_srcdir)/pimd/pim_cmd.c +vtysh_scan += pimd/pim_cmd.c man8 += $(MANBUILD)/frr-pimd.8 man8 += $(MANBUILD)/mtracebis.8 endif @@ -123,8 +123,9 @@ noinst_HEADERS += \ pimd/mtracebis_routeget.h \ # end -pimd/pim_cmd_clippy.c: $(CLIPPY_DEPS) -pimd/pim_cmd.$(OBJEXT): pimd/pim_cmd_clippy.c +clippy_scan += \ + pimd/pim_cmd.c \ + # end pimd_pimd_LDADD = pimd/libpim.a lib/libfrr.la $(LIBCAP) pimd_pimd_SOURCES = pimd/pim_main.c diff --git a/python/firstheader.py b/python/firstheader.py new file mode 100644 index 0000000000..19a85b63e5 --- /dev/null +++ b/python/firstheader.py @@ -0,0 +1,30 @@ +# +# check that the first header included in C files is either +# zebra.h or config.h +# + +import sys, os, re, subprocess + +include_re = re.compile('^#\s*include\s+["<]([^ ">]+)[">]', re.M) + +errors = 0 + +files = subprocess.check_output(['git', 'ls-files']).decode('ASCII') +for fn in files.splitlines(): + if not fn.endswith('.c'): + continue + if fn.startswith('tools/'): + continue + with open(fn, 'r') as fd: + data = fd.read() + m = include_re.search(data) + if m is None: + #sys.stderr.write('no #include in %s?\n' % (fn)) + continue + if m.group(1) in ['config.h', 'zebra.h', 'lib/zebra.h']: + continue + sys.stderr.write('%s: %s\n' % (fn, m.group(0))) + errors += 1 + +if errors: + sys.exit(1) diff --git a/python/makefile.py b/python/makefile.py new file mode 100644 index 0000000000..9af397d373 --- /dev/null +++ b/python/makefile.py @@ -0,0 +1,100 @@ +#!/usr/bin/python3 +# +# FRR extended automake/Makefile functionality helper +# +# This script is executed on/after generating Makefile to add some pieces for +# clippy. + +import sys +import os +import subprocess +import re +import argparse +from string import Template + +argp = argparse.ArgumentParser(description = 'FRR Makefile extensions') +argp.add_argument('--dev-build', action = 'store_const', const = True, + help = 'run additional developer checks') +args = argp.parse_args() + +with open('Makefile', 'r') as fd: + before = fd.read() + +nolinecont = before.replace('\\\n', '') +m = re.search('^clippy_scan\s*=([^#]*)(?:#.*)?$', nolinecont, flags=re.MULTILINE) +if m is None: + sys.stderr.write('failed to parse Makefile.in\n') + sys.exit(2) + +clippy_scan = m.group(1).strip().split() +for clippy_file in clippy_scan: + assert clippy_file.endswith('.c') + +# check for files using clippy but not listed in clippy_scan +if args.dev_build: + basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + if os.path.exists(os.path.join(basepath, '.git')): + clippy_ref = subprocess.check_output([ + 'git', '-C', basepath, 'grep', '-l', '-P', '^#\s*include.*_clippy.c', '--', '**.c']).decode('US-ASCII') + + clippy_ref = set(clippy_ref.splitlines()) + missing = clippy_ref - set(clippy_scan) + + if len(missing) > 0: + sys.stderr.write('error: files seem to be using clippy, but not listed in "clippy_scan" in subdir.am:\n\t%s\n' % ('\n\t'.join(sorted(missing)))) + sys.exit(1) + +clippydep = Template(''' +${clippybase}.$$(OBJEXT): ${clippybase}_clippy.c +${clippybase}.lo: ${clippybase}_clippy.c +${clippybase}_clippy.c: $$(CLIPPY_DEPS)''') + +clippyauxdep = Template('''# clippy{ +# auxiliary clippy target +${target}: ${clippybase}_clippy.c +# }clippy''') + +lines = before.splitlines() +autoderp = '#AUTODERP# ' +out_lines = [] +make_rule_re = re.compile('^([^:\s]+):\s*([^:\s]+)\s*($|\n)') + +while lines: + line = lines.pop(0) + if line.startswith(autoderp): + line = line[len(autoderp):] + + if line == '# clippy{': + while lines: + line = lines.pop(0) + if line == '# }clippy': + break + continue + + if line.startswith('#'): + out_lines.append(line) + continue + + m = make_rule_re.match(line) + if m is None: + out_lines.append(line) + continue + + if m.group(2) in clippy_scan: + out_lines.append(clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2])) + + out_lines.append(line) + +out_lines.append('# clippy{\n# main clippy targets') +for clippy_file in clippy_scan: + out_lines.append(clippydep.substitute(clippybase = clippy_file[:-2])) +out_lines.append('# }clippy') +out_lines.append('') + +after = '\n'.join(out_lines) +if after == before: + sys.exit(0) + +with open('Makefile.pyout', 'w') as fd: + fd.write(after) +os.rename('Makefile.pyout', 'Makefile') diff --git a/python/makevars.py b/python/makevars.py new file mode 100644 index 0000000000..e0e2031a0d --- /dev/null +++ b/python/makevars.py @@ -0,0 +1,50 @@ +# +# helper class to grab variables from FRR's Makefile +# + +import os +import subprocess + +class MakeVars(object): + ''' + makevars['FOO_CFLAGS'] gets you "FOO_CFLAGS" from Makefile + ''' + def __init__(self): + self._data = dict() + + def getvars(self, varlist): + ''' + get a batch list of variables from make. faster than individual calls. + ''' + rdfd, wrfd = os.pipe() + + shvars = ['shvar-%s' % s for s in varlist] + make = subprocess.Popen(['make', '-s', 'VARFD=%d' % wrfd] + shvars, pass_fds = [wrfd]) + os.close(wrfd) + data = b'' + + rdf = os.fdopen(rdfd, 'rb') + while True: + rdata = rdf.read() + if len(rdata) == 0: + break + data += rdata + + del rdf + make.wait() + + data = data.decode('US-ASCII').strip().split('\n') + for row in data: + k, v = row.split('=', 1) + v = v[1:-1] + self._data[k] = v + + def __getitem__(self, k): + if k not in self._data: + self.getvars([k]) + return self._data[k] + + def get(self, k, defval = None): + if k not in self._data: + self.getvars([k]) + return self._data[k] or defval diff --git a/ripd/rip_debug.c b/ripd/rip_debug.c index 3356d99c2a..871ee8e87e 100644 --- a/ripd/rip_debug.c +++ b/ripd/rip_debug.c @@ -172,10 +172,14 @@ DEFUN (no_debug_rip_zebra, return CMD_SUCCESS; } +static int config_write_debug(struct vty *vty); /* Debug node. */ -static struct cmd_node debug_node = {DEBUG_NODE, - "", /* Debug node has no interface. */ - 1}; +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = config_write_debug, +}; static int config_write_debug(struct vty *vty) { @@ -210,7 +214,7 @@ void rip_debug_init(void) rip_debug_packet = 0; rip_debug_zebra = 0; - install_node(&debug_node, config_write_debug); + install_node(&debug_node); install_element(ENABLE_NODE, &show_debugging_rip_cmd); install_element(ENABLE_NODE, &debug_rip_events_cmd); diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index c05d776eb1..177f53db45 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -1193,8 +1193,13 @@ int rip_show_network_config(struct vty *vty, struct rip *rip) return 0; } +static int rip_interface_config_write(struct vty *vty); static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", 1, + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = rip_interface_config_write, }; void rip_interface_sync(struct interface *ifp) @@ -1236,7 +1241,7 @@ void rip_if_init(void) hook_register_prio(if_del, 0, rip_interface_delete_hook); /* Install interface node. */ - install_node(&interface_node, rip_interface_config_write); + install_node(&interface_node); if_cmd_init(); if_zapi_callbacks(rip_ifp_create, rip_ifp_up, rip_ifp_down, rip_ifp_destroy); diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 73e94deefc..9ec32a53e3 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -117,6 +117,7 @@ static const struct frr_yang_module_info *const ripd_yang_modules[] = { &frr_interface_info, &frr_ripd_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(ripd, RIP, .vty_port = RIP_VTY_PORT, diff --git a/ripd/rip_nb.h b/ripd/rip_nb.h index 441b253fea..26bb3cb3bd 100644 --- a/ripd/rip_nb.h +++ b/ripd/rip_nb.h @@ -23,186 +23,109 @@ extern const struct frr_yang_module_info frr_ripd_info; /* Mandatory callbacks. */ -int ripd_instance_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_destroy(enum nb_event event, const struct lyd_node *dnode); -const void *ripd_instance_get_next(const void *parent_list_entry, - const void *list_entry); -int ripd_instance_get_keys(const void *list_entry, struct yang_list_keys *keys); -const void *ripd_instance_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys); -int ripd_instance_allow_ecmp_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); +int ripd_instance_create(struct nb_cb_create_args *args); +int ripd_instance_destroy(struct nb_cb_destroy_args *args); +const void *ripd_instance_get_next(struct nb_cb_get_next_args *args); +int ripd_instance_get_keys(struct nb_cb_get_keys_args *args); +const void *ripd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args); +int ripd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args); int ripd_instance_default_information_originate_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_default_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_distance_default_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_distance_source_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_distance_source_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_distance_source_distance_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int ripd_instance_default_metric_modify(struct nb_cb_modify_args *args); +int ripd_instance_distance_default_modify(struct nb_cb_modify_args *args); +int ripd_instance_distance_source_create(struct nb_cb_create_args *args); +int ripd_instance_distance_source_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_distance_source_distance_modify( + struct nb_cb_modify_args *args); int ripd_instance_distance_source_access_list_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int ripd_instance_distance_source_access_list_destroy( - enum nb_event event, const struct lyd_node *dnode); -int ripd_instance_explicit_neighbor_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_explicit_neighbor_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_network_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_network_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_interface_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_offset_list_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_offset_list_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_offset_list_access_list_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_offset_list_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_passive_default_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_passive_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_passive_interface_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_non_passive_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_non_passive_interface_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_redistribute_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_redistribute_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_redistribute_route_map_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_redistribute_route_map_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_redistribute_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_redistribute_metric_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_static_route_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_static_route_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripd_instance_timers_flush_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_timers_holddown_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_timers_update_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_version_receive_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripd_instance_version_send_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -const void * -ripd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry, - const void *list_entry); + struct nb_cb_destroy_args *args); +int ripd_instance_explicit_neighbor_create(struct nb_cb_create_args *args); +int ripd_instance_explicit_neighbor_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_network_create(struct nb_cb_create_args *args); +int ripd_instance_network_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_interface_create(struct nb_cb_create_args *args); +int ripd_instance_interface_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_offset_list_create(struct nb_cb_create_args *args); +int ripd_instance_offset_list_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_offset_list_access_list_modify( + struct nb_cb_modify_args *args); +int ripd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args); +int ripd_instance_passive_default_modify(struct nb_cb_modify_args *args); +int ripd_instance_passive_interface_create(struct nb_cb_create_args *args); +int ripd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_non_passive_interface_create(struct nb_cb_create_args *args); +int ripd_instance_non_passive_interface_destroy( + struct nb_cb_destroy_args *args); +int ripd_instance_redistribute_create(struct nb_cb_create_args *args); +int ripd_instance_redistribute_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args); +int ripd_instance_redistribute_route_map_destroy( + struct nb_cb_destroy_args *args); +int ripd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args); +int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_static_route_create(struct nb_cb_create_args *args); +int ripd_instance_static_route_destroy(struct nb_cb_destroy_args *args); +int ripd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args); +int ripd_instance_timers_holddown_interval_modify( + struct nb_cb_modify_args *args); +int ripd_instance_timers_update_interval_modify(struct nb_cb_modify_args *args); +int ripd_instance_version_receive_modify(struct nb_cb_modify_args *args); +int ripd_instance_version_send_modify(struct nb_cb_modify_args *args); +const void *ripd_instance_state_neighbors_neighbor_get_next( + struct nb_cb_get_next_args *args); int ripd_instance_state_neighbors_neighbor_get_keys( - const void *list_entry, struct yang_list_keys *keys); + struct nb_cb_get_keys_args *args); const void *ripd_instance_state_neighbors_neighbor_lookup_entry( - const void *parent_list_entry, const struct yang_list_keys *keys); -struct yang_data * -ripd_instance_state_neighbors_neighbor_address_get_elem(const char *xpath, - const void *list_entry); + struct nb_cb_lookup_entry_args *args); +struct yang_data *ripd_instance_state_neighbors_neighbor_address_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data *ripd_instance_state_neighbors_neighbor_last_update_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); const void * -ripd_instance_state_routes_route_get_next(const void *parent_list_entry, - const void *list_entry); -int ripd_instance_state_routes_route_get_keys(const void *list_entry, - struct yang_list_keys *keys); +ripd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args); +int ripd_instance_state_routes_route_get_keys(struct nb_cb_get_keys_args *args); const void *ripd_instance_state_routes_route_lookup_entry( - const void *parent_list_entry, const struct yang_list_keys *keys); -struct yang_data * -ripd_instance_state_routes_route_prefix_get_elem(const char *xpath, - const void *list_entry); -struct yang_data * -ripd_instance_state_routes_route_next_hop_get_elem(const char *xpath, - const void *list_entry); -struct yang_data * -ripd_instance_state_routes_route_interface_get_elem(const char *xpath, - const void *list_entry); -struct yang_data * -ripd_instance_state_routes_route_metric_get_elem(const char *xpath, - const void *list_entry); -int clear_rip_route_rpc(const char *xpath, const struct list *input, - struct list *output); -int lib_interface_rip_split_horizon_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_rip_v2_broadcast_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_rip_version_receive_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int lib_interface_rip_version_send_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_lookup_entry_args *args); +struct yang_data *ripd_instance_state_routes_route_prefix_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *ripd_instance_state_routes_route_next_hop_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *ripd_instance_state_routes_route_interface_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *ripd_instance_state_routes_route_metric_get_elem( + struct nb_cb_get_elem_args *args); +int clear_rip_route_rpc(struct nb_cb_rpc_args *args); +int lib_interface_rip_split_horizon_modify(struct nb_cb_modify_args *args); +int lib_interface_rip_v2_broadcast_modify(struct nb_cb_modify_args *args); +int lib_interface_rip_version_receive_modify(struct nb_cb_modify_args *args); +int lib_interface_rip_version_send_modify(struct nb_cb_modify_args *args); int lib_interface_rip_authentication_scheme_mode_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_rip_authentication_scheme_md5_auth_length_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_rip_authentication_scheme_md5_auth_length_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int lib_interface_rip_authentication_password_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_rip_authentication_password_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); int lib_interface_rip_authentication_key_chain_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); int lib_interface_rip_authentication_key_chain_destroy( - enum nb_event event, const struct lyd_node *dnode); + struct nb_cb_destroy_args *args); /* Optional 'apply_finish' callbacks. */ -void ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode); -void ripd_instance_timers_apply_finish(const struct lyd_node *dnode); +void ripd_instance_redistribute_apply_finish( + struct nb_cb_apply_finish_args *args); +void ripd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args); /* Optional 'cli_show' callbacks. */ void cli_show_router_rip(struct vty *vty, struct lyd_node *dnode, diff --git a/ripd/rip_nb_config.c b/ripd/rip_nb_config.c index e75db342af..c640ca27af 100644 --- a/ripd/rip_nb_config.c +++ b/ripd/rip_nb_config.c @@ -38,22 +38,21 @@ /* * XPath: /frr-ripd:ripd/instance */ -int ripd_instance_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_create(struct nb_cb_create_args *args) { struct rip *rip; struct vrf *vrf; const char *vrf_name; int socket; - vrf_name = yang_dnode_get_string(dnode, "./vrf"); + vrf_name = yang_dnode_get_string(args->dnode, "./vrf"); vrf = vrf_lookup_by_name(vrf_name); /* * Try to create a RIP socket only if the VRF is enabled, otherwise * create a disabled RIP instance and wait for the VRF to be enabled. */ - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: break; case NB_EV_PREPARE: @@ -63,37 +62,37 @@ int ripd_instance_create(enum nb_event event, const struct lyd_node *dnode, socket = rip_create_socket(vrf); if (socket < 0) return NB_ERR_RESOURCE; - resource->fd = socket; + args->resource->fd = socket; break; case NB_EV_ABORT: if (!vrf || !vrf_is_enabled(vrf)) break; - socket = resource->fd; + socket = args->resource->fd; close(socket); break; case NB_EV_APPLY: if (vrf && vrf_is_enabled(vrf)) - socket = resource->fd; + socket = args->resource->fd; else socket = -1; rip = rip_create(vrf_name, vrf, socket); - nb_running_set_entry(dnode, rip); + nb_running_set_entry(args->dnode, rip); break; } return NB_OK; } -int ripd_instance_destroy(enum nb_event event, const struct lyd_node *dnode) +int ripd_instance_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_unset_entry(dnode); + rip = nb_running_unset_entry(args->dnode); rip_clean(rip); return NB_OK; @@ -102,17 +101,15 @@ int ripd_instance_destroy(enum nb_event event, const struct lyd_node *dnode) /* * XPath: /frr-ripd:ripd/instance/allow-ecmp */ -int ripd_instance_allow_ecmp_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->ecmp = yang_dnode_get_bool(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->ecmp = yang_dnode_get_bool(args->dnode, NULL); if (!rip->ecmp) rip_ecmp_disable(rip); @@ -123,18 +120,17 @@ int ripd_instance_allow_ecmp_modify(enum nb_event event, * XPath: /frr-ripd:ripd/instance/default-information-originate */ int ripd_instance_default_information_originate_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct rip *rip; bool default_information; struct prefix_ipv4 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - default_information = yang_dnode_get_bool(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + default_information = yang_dnode_get_bool(args->dnode, NULL); memset(&p, 0, sizeof(struct prefix_ipv4)); p.family = AF_INET; @@ -156,17 +152,15 @@ int ripd_instance_default_information_originate_modify( /* * XPath: /frr-ripd:ripd/instance/default-metric */ -int ripd_instance_default_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_default_metric_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->default_metric = yang_dnode_get_uint8(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->default_metric = yang_dnode_get_uint8(args->dnode, NULL); /* rip_update_default_metric (); */ return NB_OK; @@ -175,17 +169,15 @@ int ripd_instance_default_metric_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/distance/default */ -int ripd_instance_distance_default_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_distance_default_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->distance = yang_dnode_get_uint8(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->distance = yang_dnode_get_uint8(args->dnode, NULL); return NB_OK; } @@ -193,39 +185,36 @@ int ripd_instance_distance_default_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/distance/source */ -int ripd_instance_distance_source_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_distance_source_create(struct nb_cb_create_args *args) { struct rip *rip; struct prefix_ipv4 prefix; struct route_node *rn; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - yang_dnode_get_ipv4p(&prefix, dnode, "./prefix"); + yang_dnode_get_ipv4p(&prefix, args->dnode, "./prefix"); apply_mask_ipv4(&prefix); /* Get RIP distance node. */ - rip = nb_running_get_entry(dnode, NULL, true); + rip = nb_running_get_entry(args->dnode, NULL, true); rn = route_node_get(rip->distance_table, (struct prefix *)&prefix); rn->info = rip_distance_new(); - nb_running_set_entry(dnode, rn); + nb_running_set_entry(args->dnode, rn); return NB_OK; } -int ripd_instance_distance_source_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_distance_source_destroy(struct nb_cb_destroy_args *args) { struct route_node *rn; struct rip_distance *rdistance; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rn = nb_running_unset_entry(dnode); + rn = nb_running_unset_entry(args->dnode); rdistance = rn->info; rip_distance_free(rdistance); rn->info = NULL; @@ -237,20 +226,19 @@ int ripd_instance_distance_source_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/distance/source/distance */ -int ripd_instance_distance_source_distance_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_distance_source_distance_modify( + struct nb_cb_modify_args *args) { struct route_node *rn; uint8_t distance; struct rip_distance *rdistance; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Set distance value. */ - rn = nb_running_get_entry(dnode, NULL, true); - distance = yang_dnode_get_uint8(dnode, NULL); + rn = nb_running_get_entry(args->dnode, NULL, true); + distance = yang_dnode_get_uint8(args->dnode, NULL); rdistance = rn->info; rdistance->distance = distance; @@ -261,20 +249,19 @@ int ripd_instance_distance_source_distance_modify(enum nb_event event, * XPath: /frr-ripd:ripd/instance/distance/source/access-list */ int ripd_instance_distance_source_access_list_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { const char *acl_name; struct route_node *rn; struct rip_distance *rdistance; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - acl_name = yang_dnode_get_string(dnode, NULL); + acl_name = yang_dnode_get_string(args->dnode, NULL); /* Set access-list */ - rn = nb_running_get_entry(dnode, NULL, true); + rn = nb_running_get_entry(args->dnode, NULL, true); rdistance = rn->info; if (rdistance->access_list) free(rdistance->access_list); @@ -284,16 +271,16 @@ int ripd_instance_distance_source_access_list_modify( } int ripd_instance_distance_source_access_list_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { struct route_node *rn; struct rip_distance *rdistance; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; /* Reset access-list configuration. */ - rn = nb_running_get_entry(dnode, NULL, true); + rn = nb_running_get_entry(args->dnode, NULL, true); rdistance = rn->info; free(rdistance->access_list); rdistance->access_list = NULL; @@ -304,37 +291,34 @@ int ripd_instance_distance_source_access_list_destroy( /* * XPath: /frr-ripd:ripd/instance/explicit-neighbor */ -int ripd_instance_explicit_neighbor_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_explicit_neighbor_create(struct nb_cb_create_args *args) { struct rip *rip; struct prefix_ipv4 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); + rip = nb_running_get_entry(args->dnode, NULL, true); p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; - yang_dnode_get_ipv4(&p.prefix, dnode, NULL); + yang_dnode_get_ipv4(&p.prefix, args->dnode, NULL); return rip_neighbor_add(rip, &p); } -int ripd_instance_explicit_neighbor_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_explicit_neighbor_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; struct prefix_ipv4 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); + rip = nb_running_get_entry(args->dnode, NULL, true); p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; - yang_dnode_get_ipv4(&p.prefix, dnode, NULL); + yang_dnode_get_ipv4(&p.prefix, args->dnode, NULL); return rip_neighbor_delete(rip, &p); } @@ -342,34 +326,31 @@ int ripd_instance_explicit_neighbor_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/network */ -int ripd_instance_network_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_network_create(struct nb_cb_create_args *args) { struct rip *rip; struct prefix p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv4p(&p, dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv4p(&p, args->dnode, NULL); apply_mask_ipv4((struct prefix_ipv4 *)&p); return rip_enable_network_add(rip, &p); } -int ripd_instance_network_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_network_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; struct prefix p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv4p(&p, dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv4p(&p, args->dnode, NULL); apply_mask_ipv4((struct prefix_ipv4 *)&p); return rip_enable_network_delete(rip, &p); @@ -378,33 +359,30 @@ int ripd_instance_network_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/interface */ -int ripd_instance_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_interface_create(struct nb_cb_create_args *args) { struct rip *rip; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return rip_enable_if_add(rip, ifname); } -int ripd_instance_interface_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_interface_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return rip_enable_if_delete(rip, ifname); } @@ -412,38 +390,35 @@ int ripd_instance_interface_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/offset-list */ -int ripd_instance_offset_list_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_offset_list_create(struct nb_cb_create_args *args) { struct rip *rip; const char *ifname; struct rip_offset_list *offset; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, "./interface"); + rip = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, "./interface"); offset = rip_offset_list_new(rip, ifname); - nb_running_set_entry(dnode, offset); + nb_running_set_entry(args->dnode, offset); return NB_OK; } -int ripd_instance_offset_list_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_offset_list_destroy(struct nb_cb_destroy_args *args) { int direct; struct rip_offset_list *offset; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - direct = yang_dnode_get_enum(dnode, "./direction"); + direct = yang_dnode_get_enum(args->dnode, "./direction"); - offset = nb_running_unset_entry(dnode); + offset = nb_running_unset_entry(args->dnode); if (offset->direct[direct].alist_name) { free(offset->direct[direct].alist_name); offset->direct[direct].alist_name = NULL; @@ -458,21 +433,19 @@ int ripd_instance_offset_list_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/offset-list/access-list */ -int ripd_instance_offset_list_access_list_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_offset_list_access_list_modify(struct nb_cb_modify_args *args) { int direct; struct rip_offset_list *offset; const char *alist_name; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - direct = yang_dnode_get_enum(dnode, "../direction"); - alist_name = yang_dnode_get_string(dnode, NULL); + direct = yang_dnode_get_enum(args->dnode, "../direction"); + alist_name = yang_dnode_get_string(args->dnode, NULL); - offset = nb_running_get_entry(dnode, NULL, true); + offset = nb_running_get_entry(args->dnode, NULL, true); if (offset->direct[direct].alist_name) free(offset->direct[direct].alist_name); offset->direct[direct].alist_name = strdup(alist_name); @@ -483,21 +456,19 @@ int ripd_instance_offset_list_access_list_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/offset-list/metric */ -int ripd_instance_offset_list_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args) { int direct; uint8_t metric; struct rip_offset_list *offset; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - direct = yang_dnode_get_enum(dnode, "../direction"); - metric = yang_dnode_get_uint8(dnode, NULL); + direct = yang_dnode_get_enum(args->dnode, "../direction"); + metric = yang_dnode_get_uint8(args->dnode, NULL); - offset = nb_running_get_entry(dnode, NULL, true); + offset = nb_running_get_entry(args->dnode, NULL, true); offset->direct[direct].metric = metric; return NB_OK; @@ -506,17 +477,15 @@ int ripd_instance_offset_list_metric_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/passive-default */ -int ripd_instance_passive_default_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_passive_default_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->passive_default = yang_dnode_get_bool(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->passive_default = yang_dnode_get_bool(args->dnode, NULL); rip_passive_nondefault_clean(rip); return NB_OK; @@ -525,33 +494,30 @@ int ripd_instance_passive_default_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/passive-interface */ -int ripd_instance_passive_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_passive_interface_create(struct nb_cb_create_args *args) { struct rip *rip; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return rip_passive_nondefault_set(rip, ifname); } -int ripd_instance_passive_interface_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return rip_passive_nondefault_unset(rip, ifname); } @@ -559,33 +525,30 @@ int ripd_instance_passive_interface_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/non-passive-interface */ -int ripd_instance_non_passive_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_non_passive_interface_create(struct nb_cb_create_args *args) { struct rip *rip; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return rip_passive_nondefault_unset(rip, ifname); } -int ripd_instance_non_passive_interface_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_non_passive_interface_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return rip_passive_nondefault_set(rip, ifname); } @@ -593,35 +556,32 @@ int ripd_instance_non_passive_interface_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/redistribute */ -int ripd_instance_redistribute_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_redistribute_create(struct nb_cb_create_args *args) { struct rip *rip; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "./protocol"); + rip = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "./protocol"); rip->redist[type].enabled = true; return NB_OK; } -int ripd_instance_redistribute_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_redistribute_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "./protocol"); + rip = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "./protocol"); rip->redist[type].enabled = false; if (rip->redist[type].route_map.name) { @@ -638,13 +598,14 @@ int ripd_instance_redistribute_destroy(enum nb_event event, return NB_OK; } -void ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode) +void ripd_instance_redistribute_apply_finish( + struct nb_cb_apply_finish_args *args) { struct rip *rip; int type; - rip = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "./protocol"); + rip = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "./protocol"); if (rip->enabled) rip_redistribute_conf_update(rip, type); @@ -653,20 +614,18 @@ void ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode) /* * XPath: /frr-ripd:ripd/instance/redistribute/route-map */ -int ripd_instance_redistribute_route_map_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args) { struct rip *rip; int type; const char *rmap_name; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); - rmap_name = yang_dnode_get_string(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); + rmap_name = yang_dnode_get_string(args->dnode, NULL); if (rip->redist[type].route_map.name) free(rip->redist[type].route_map.name); @@ -676,17 +635,17 @@ int ripd_instance_redistribute_route_map_modify(enum nb_event event, return NB_OK; } -int ripd_instance_redistribute_route_map_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_redistribute_route_map_destroy( + struct nb_cb_destroy_args *args) { struct rip *rip; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); + rip = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); free(rip->redist[type].route_map.name); rip->redist[type].route_map.name = NULL; @@ -698,20 +657,18 @@ int ripd_instance_redistribute_route_map_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/redistribute/metric */ -int ripd_instance_redistribute_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args) { struct rip *rip; int type; uint8_t metric; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); - metric = yang_dnode_get_uint8(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); + metric = yang_dnode_get_uint8(args->dnode, NULL); rip->redist[type].metric_config = true; rip->redist[type].metric = metric; @@ -719,17 +676,16 @@ int ripd_instance_redistribute_metric_modify(enum nb_event event, return NB_OK; } -int ripd_instance_redistribute_metric_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); + rip = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); rip->redist[type].metric_config = false; rip->redist[type].metric = 0; @@ -740,19 +696,17 @@ int ripd_instance_redistribute_metric_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/static-route */ -int ripd_instance_static_route_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_static_route_create(struct nb_cb_create_args *args) { struct rip *rip; struct nexthop nh; struct prefix_ipv4 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv4p(&p, dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv4p(&p, args->dnode, NULL); apply_mask_ipv4(&p); memset(&nh, 0, sizeof(nh)); @@ -763,17 +717,16 @@ int ripd_instance_static_route_create(enum nb_event event, return NB_OK; } -int ripd_instance_static_route_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripd_instance_static_route_destroy(struct nb_cb_destroy_args *args) { struct rip *rip; struct prefix_ipv4 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv4p(&p, dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv4p(&p, args->dnode, NULL); apply_mask_ipv4(&p); rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0); @@ -784,11 +737,11 @@ int ripd_instance_static_route_destroy(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/timers/ */ -void ripd_instance_timers_apply_finish(const struct lyd_node *dnode) +void ripd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args) { struct rip *rip; - rip = nb_running_get_entry(dnode, NULL, true); + rip = nb_running_get_entry(args->dnode, NULL, true); /* Reset update timer thread. */ rip_event(rip, RIP_UPDATE_EVENT, 0); @@ -797,17 +750,15 @@ void ripd_instance_timers_apply_finish(const struct lyd_node *dnode) /* * XPath: /frr-ripd:ripd/instance/timers/flush-interval */ -int ripd_instance_timers_flush_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->garbage_time = yang_dnode_get_uint32(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->garbage_time = yang_dnode_get_uint32(args->dnode, NULL); return NB_OK; } @@ -815,17 +766,16 @@ int ripd_instance_timers_flush_interval_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/timers/holddown-interval */ -int ripd_instance_timers_holddown_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_timers_holddown_interval_modify( + struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->timeout_time = yang_dnode_get_uint32(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->timeout_time = yang_dnode_get_uint32(args->dnode, NULL); return NB_OK; } @@ -833,17 +783,15 @@ int ripd_instance_timers_holddown_interval_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/timers/update-interval */ -int ripd_instance_timers_update_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_timers_update_interval_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->update_time = yang_dnode_get_uint32(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->update_time = yang_dnode_get_uint32(args->dnode, NULL); return NB_OK; } @@ -851,17 +799,15 @@ int ripd_instance_timers_update_interval_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/version/receive */ -int ripd_instance_version_receive_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_version_receive_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->version_recv = yang_dnode_get_enum(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->version_recv = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } @@ -869,17 +815,15 @@ int ripd_instance_version_receive_modify(enum nb_event event, /* * XPath: /frr-ripd:ripd/instance/version/send */ -int ripd_instance_version_send_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripd_instance_version_send_modify(struct nb_cb_modify_args *args) { struct rip *rip; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - rip = nb_running_get_entry(dnode, NULL, true); - rip->version_send = yang_dnode_get_enum(dnode, NULL); + rip = nb_running_get_entry(args->dnode, NULL, true); + rip->version_send = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } @@ -887,19 +831,17 @@ int ripd_instance_version_send_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/split-horizon */ -int lib_interface_rip_split_horizon_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_rip_split_horizon_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; - ri->split_horizon = yang_dnode_get_enum(dnode, NULL); + ri->split_horizon = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } @@ -907,19 +849,17 @@ int lib_interface_rip_split_horizon_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/v2-broadcast */ -int lib_interface_rip_v2_broadcast_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_rip_v2_broadcast_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; - ri->v2_broadcast = yang_dnode_get_bool(dnode, NULL); + ri->v2_broadcast = yang_dnode_get_bool(args->dnode, NULL); return NB_OK; } @@ -927,19 +867,17 @@ int lib_interface_rip_v2_broadcast_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-receive */ -int lib_interface_rip_version_receive_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_rip_version_receive_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; - ri->ri_receive = yang_dnode_get_enum(dnode, NULL); + ri->ri_receive = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } @@ -947,19 +885,17 @@ int lib_interface_rip_version_receive_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-ripd:rip/version-send */ -int lib_interface_rip_version_send_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_rip_version_send_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; - ri->ri_send = yang_dnode_get_enum(dnode, NULL); + ri->ri_send = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } @@ -968,18 +904,17 @@ int lib_interface_rip_version_send_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/mode */ int lib_interface_rip_authentication_scheme_mode_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; - ri->auth_type = yang_dnode_get_enum(dnode, NULL); + ri->auth_type = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } @@ -989,32 +924,31 @@ int lib_interface_rip_authentication_scheme_mode_modify( * /frr-interface:lib/interface/frr-ripd:rip/authentication-scheme/md5-auth-length */ int lib_interface_rip_authentication_scheme_md5_auth_length_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; - ri->md5_auth_len = yang_dnode_get_enum(dnode, NULL); + ri->md5_auth_len = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } int lib_interface_rip_authentication_scheme_md5_auth_length_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; ri->md5_auth_len = yang_get_default_enum( "%s/authentication-scheme/md5-auth-length", RIP_IFACE); @@ -1026,34 +960,33 @@ int lib_interface_rip_authentication_scheme_md5_auth_length_destroy( * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-password */ int lib_interface_rip_authentication_password_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); ri->auth_str = XSTRDUP(MTYPE_RIP_INTERFACE_STRING, - yang_dnode_get_string(dnode, NULL)); + yang_dnode_get_string(args->dnode, NULL)); return NB_OK; } int lib_interface_rip_authentication_password_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; XFREE(MTYPE_RIP_INTERFACE_STRING, ri->auth_str); @@ -1064,34 +997,33 @@ int lib_interface_rip_authentication_password_destroy( * XPath: /frr-interface:lib/interface/frr-ripd:rip/authentication-key-chain */ int lib_interface_rip_authentication_key_chain_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); ri->key_chain = XSTRDUP(MTYPE_RIP_INTERFACE_STRING, - yang_dnode_get_string(dnode, NULL)); + yang_dnode_get_string(args->dnode, NULL)); return NB_OK; } int lib_interface_rip_authentication_key_chain_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { struct interface *ifp; struct rip_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; XFREE(MTYPE_RIP_INTERFACE_STRING, ri->key_chain); diff --git a/ripd/rip_nb_rpcs.c b/ripd/rip_nb_rpcs.c index 0ca85296fd..52f2985cb3 100644 --- a/ripd/rip_nb_rpcs.c +++ b/ripd/rip_nb_rpcs.c @@ -78,13 +78,13 @@ static void clear_rip_route(struct rip *rip) } } -int clear_rip_route_rpc(const char *xpath, const struct list *input, - struct list *output) +int clear_rip_route_rpc(struct nb_cb_rpc_args *args) { struct rip *rip; struct yang_data *yang_vrf; - yang_vrf = yang_data_list_find(input, "%s/%s", xpath, "input/vrf"); + yang_vrf = yang_data_list_find(args->input, "%s/%s", args->xpath, + "input/vrf"); if (yang_vrf) { rip = rip_lookup_by_vrf_name(yang_vrf->value); if (rip) diff --git a/ripd/rip_nb_state.c b/ripd/rip_nb_state.c index 2f7eb3cb5e..e88f33ec68 100644 --- a/ripd/rip_nb_state.c +++ b/ripd/rip_nb_state.c @@ -37,12 +37,11 @@ /* * XPath: /frr-ripd:ripd/instance */ -const void *ripd_instance_get_next(const void *parent_list_entry, - const void *list_entry) +const void *ripd_instance_get_next(struct nb_cb_get_next_args *args) { - struct rip *rip = (struct rip *)list_entry; + struct rip *rip = (struct rip *)args->list_entry; - if (list_entry == NULL) + if (args->list_entry == NULL) rip = RB_MIN(rip_instance_head, &rip_instances); else rip = RB_NEXT(rip_instance_head, rip); @@ -50,20 +49,19 @@ const void *ripd_instance_get_next(const void *parent_list_entry, return rip; } -int ripd_instance_get_keys(const void *list_entry, struct yang_list_keys *keys) +int ripd_instance_get_keys(struct nb_cb_get_keys_args *args) { - const struct rip *rip = list_entry; + const struct rip *rip = args->list_entry; - keys->num = 1; - strlcpy(keys->key[0], rip->vrf_name, sizeof(keys->key[0])); + args->keys->num = 1; + strlcpy(args->keys->key[0], rip->vrf_name, sizeof(args->keys->key[0])); return NB_OK; } -const void *ripd_instance_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +const void *ripd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args) { - const char *vrf_name = keys->key[0]; + const char *vrf_name = args->keys->key[0]; return rip_lookup_by_vrf_name(vrf_name); } @@ -71,43 +69,42 @@ const void *ripd_instance_lookup_entry(const void *parent_list_entry, /* * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor */ -const void * -ripd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry, - const void *list_entry) +const void *ripd_instance_state_neighbors_neighbor_get_next( + struct nb_cb_get_next_args *args) { - const struct rip *rip = parent_list_entry; + const struct rip *rip = args->parent_list_entry; struct listnode *node; - if (list_entry == NULL) + if (args->list_entry == NULL) node = listhead(rip->peer_list); else - node = listnextnode((struct listnode *)list_entry); + node = listnextnode((struct listnode *)args->list_entry); return node; } -int ripd_instance_state_neighbors_neighbor_get_keys(const void *list_entry, - struct yang_list_keys *keys) +int ripd_instance_state_neighbors_neighbor_get_keys( + struct nb_cb_get_keys_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct rip_peer *peer = listgetdata(node); - keys->num = 1; - (void)inet_ntop(AF_INET, &peer->addr, keys->key[0], - sizeof(keys->key[0])); + args->keys->num = 1; + (void)inet_ntop(AF_INET, &peer->addr, args->keys->key[0], + sizeof(args->keys->key[0])); return NB_OK; } const void *ripd_instance_state_neighbors_neighbor_lookup_entry( - const void *parent_list_entry, const struct yang_list_keys *keys) + struct nb_cb_lookup_entry_args *args) { - const struct rip *rip = parent_list_entry; + const struct rip *rip = args->parent_list_entry; struct in_addr address; struct rip_peer *peer; struct listnode *node; - yang_str2ipv4(keys->key[0], &address); + yang_str2ipv4(args->keys->key[0], &address); for (ALL_LIST_ELEMENTS_RO(rip->peer_list, node, peer)) { if (IPV4_ADDR_SAME(&peer->addr, &address)) @@ -120,21 +117,20 @@ const void *ripd_instance_state_neighbors_neighbor_lookup_entry( /* * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/address */ -struct yang_data * -ripd_instance_state_neighbors_neighbor_address_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripd_instance_state_neighbors_neighbor_address_get_elem( + struct nb_cb_get_elem_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct rip_peer *peer = listgetdata(node); - return yang_data_new_ipv4(xpath, &peer->addr); + return yang_data_new_ipv4(args->xpath, &peer->addr); } /* * XPath: /frr-ripd:ripd/instance/state/neighbors/neighbor/last-update */ struct yang_data *ripd_instance_state_neighbors_neighbor_last_update_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { /* TODO: yang:date-and-time is tricky */ return NULL; @@ -145,12 +141,12 @@ struct yang_data *ripd_instance_state_neighbors_neighbor_last_update_get_elem( */ struct yang_data * ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct rip_peer *peer = listgetdata(node); - return yang_data_new_uint32(xpath, peer->recv_badpackets); + return yang_data_new_uint32(args->xpath, peer->recv_badpackets); } /* @@ -158,54 +154,52 @@ ripd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( */ struct yang_data * ripd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct rip_peer *peer = listgetdata(node); - return yang_data_new_uint32(xpath, peer->recv_badroutes); + return yang_data_new_uint32(args->xpath, peer->recv_badroutes); } /* * XPath: /frr-ripd:ripd/instance/state/routes/route */ const void * -ripd_instance_state_routes_route_get_next(const void *parent_list_entry, - const void *list_entry) +ripd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args) { - const struct rip *rip = parent_list_entry; + const struct rip *rip = args->parent_list_entry; struct route_node *rn; - if (list_entry == NULL) + if (args->list_entry == NULL) rn = route_top(rip->table); else - rn = route_next((struct route_node *)list_entry); + rn = route_next((struct route_node *)args->list_entry); while (rn && rn->info == NULL) rn = route_next(rn); return rn; } -int ripd_instance_state_routes_route_get_keys(const void *list_entry, - struct yang_list_keys *keys) +int ripd_instance_state_routes_route_get_keys(struct nb_cb_get_keys_args *args) { - const struct route_node *rn = list_entry; + const struct route_node *rn = args->list_entry; - keys->num = 1; - (void)prefix2str(&rn->p, keys->key[0], sizeof(keys->key[0])); + args->keys->num = 1; + (void)prefix2str(&rn->p, args->keys->key[0], + sizeof(args->keys->key[0])); return NB_OK; } -const void * -ripd_instance_state_routes_route_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +const void *ripd_instance_state_routes_route_lookup_entry( + struct nb_cb_lookup_entry_args *args) { - const struct rip *rip = parent_list_entry; + const struct rip *rip = args->parent_list_entry; struct prefix prefix; struct route_node *rn; - yang_str2ipv4p(keys->key[0], &prefix); + yang_str2ipv4p(args->keys->key[0], &prefix); rn = route_node_lookup(rip->table, &prefix); if (!rn || !rn->info) @@ -219,30 +213,28 @@ ripd_instance_state_routes_route_lookup_entry(const void *parent_list_entry, /* * XPath: /frr-ripd:ripd/instance/state/routes/route/prefix */ -struct yang_data * -ripd_instance_state_routes_route_prefix_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripd_instance_state_routes_route_prefix_get_elem( + struct nb_cb_get_elem_args *args) { - const struct route_node *rn = list_entry; + const struct route_node *rn = args->list_entry; const struct rip_info *rinfo = listnode_head(rn->info); - return yang_data_new_ipv4p(xpath, &rinfo->rp->p); + return yang_data_new_ipv4p(args->xpath, &rinfo->rp->p); } /* * XPath: /frr-ripd:ripd/instance/state/routes/route/next-hop */ -struct yang_data * -ripd_instance_state_routes_route_next_hop_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripd_instance_state_routes_route_next_hop_get_elem( + struct nb_cb_get_elem_args *args) { - const struct route_node *rn = list_entry; + const struct route_node *rn = args->list_entry; const struct rip_info *rinfo = listnode_head(rn->info); switch (rinfo->nh.type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - return yang_data_new_ipv4(xpath, &rinfo->nh.gate.ipv4); + return yang_data_new_ipv4(args->xpath, &rinfo->nh.gate.ipv4); default: return NULL; } @@ -251,11 +243,10 @@ ripd_instance_state_routes_route_next_hop_get_elem(const char *xpath, /* * XPath: /frr-ripd:ripd/instance/state/routes/route/interface */ -struct yang_data * -ripd_instance_state_routes_route_interface_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripd_instance_state_routes_route_interface_get_elem( + struct nb_cb_get_elem_args *args) { - const struct route_node *rn = list_entry; + const struct route_node *rn = args->list_entry; const struct rip_info *rinfo = listnode_head(rn->info); const struct rip *rip = rip_info_get_instance(rinfo); @@ -263,7 +254,7 @@ ripd_instance_state_routes_route_interface_get_elem(const char *xpath, case NEXTHOP_TYPE_IFINDEX: case NEXTHOP_TYPE_IPV4_IFINDEX: return yang_data_new_string( - xpath, + args->xpath, ifindex2ifname(rinfo->nh.ifindex, rip->vrf->vrf_id)); default: return NULL; @@ -273,12 +264,11 @@ ripd_instance_state_routes_route_interface_get_elem(const char *xpath, /* * XPath: /frr-ripd:ripd/instance/state/routes/route/metric */ -struct yang_data * -ripd_instance_state_routes_route_metric_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripd_instance_state_routes_route_metric_get_elem( + struct nb_cb_get_elem_args *args) { - const struct route_node *rn = list_entry; + const struct route_node *rn = args->list_entry; const struct rip_info *rinfo = listnode_head(rn->info); - return yang_data_new_uint8(xpath, rinfo->metric); + return yang_data_new_uint8(args->xpath, rinfo->metric); } diff --git a/ripd/ripd.c b/ripd/ripd.c index f092da847d..fc53796bd2 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -44,6 +44,7 @@ #include "privs.h" #include "lib_errors.h" #include "northbound_cli.h" +#include "network.h" #include "ripd/ripd.h" #include "ripd/rip_nb.h" @@ -2647,7 +2648,7 @@ static int rip_triggered_update(struct thread *t) random interval between 1 and 5 seconds. If other changes that would trigger updates occur before the timer expires, a single update is triggered when the timer expires. */ - interval = (random() % 5) + 1; + interval = (frr_weak_random() % 5) + 1; rip->t_triggered_interval = NULL; thread_add_timer(master, rip_triggered_interval, rip, interval, @@ -2844,7 +2845,8 @@ static int rip_update_jitter(unsigned long time) if (jitter_input < JITTER_BOUND) jitter_input = JITTER_BOUND; - jitter = (((random() % ((jitter_input * 2) + 1)) - jitter_input)); + jitter = (((frr_weak_random() % ((jitter_input * 2) + 1)) + - jitter_input)); return jitter / JITTER_BOUND; } @@ -2972,8 +2974,8 @@ static void rip_distance_show(struct vty *vty, struct rip *rip) " Address Distance List\n"); header = 0; } - sprintf(buf, "%s/%d", inet_ntoa(rn->p.u.prefix4), - rn->p.prefixlen); + snprintf(buf, sizeof(buf), "%s/%d", + inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen); vty_out(vty, " %-20s %4d %s\n", buf, rdistance->distance, rdistance->access_list ? rdistance->access_list @@ -3327,8 +3329,15 @@ static int config_write_rip(struct vty *vty) return write; } +static int config_write_rip(struct vty *vty); /* RIP node structure. */ -static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1}; +static struct cmd_node rip_node = { + .name = "rip", + .node = RIP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", + .config_write = config_write_rip, +}; /* Distribute-list update functions. */ static void rip_distribute_update(struct distribute_ctx *ctx, @@ -3731,7 +3740,7 @@ void rip_vrf_terminate(void) void rip_init(void) { /* Install top nodes. */ - install_node(&rip_node, config_write_rip); + install_node(&rip_node); /* Install rip commands. */ install_element(VIEW_NODE, &show_ip_rip_cmd); diff --git a/ripd/subdir.am b/ripd/subdir.am index 00984672ed..9b86c65517 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -7,9 +7,9 @@ noinst_LIBRARIES += ripd/librip.a sbin_PROGRAMS += ripd/ripd dist_examples_DATA += ripd/ripd.conf.sample vtysh_scan += \ - $(top_srcdir)/ripd/rip_cli.c \ - $(top_srcdir)/ripd/rip_debug.c \ - $(top_srcdir)/ripd/ripd.c \ + ripd/rip_cli.c \ + ripd/rip_debug.c \ + ripd/ripd.c \ # end if SNMP @@ -35,8 +35,9 @@ ripd_librip_a_SOURCES = \ ripd/ripd.c \ # end -ripd/rip_cli_clippy.c: $(CLIPPY_DEPS) -ripd/rip_cli.$(OBJEXT): ripd/rip_cli_clippy.c +clippy_scan += \ + ripd/rip_cli.c \ + # end noinst_HEADERS += \ ripd/rip_debug.h \ diff --git a/ripngd/ripng_debug.c b/ripngd/ripng_debug.c index fe63d8fdea..54edb17ecc 100644 --- a/ripngd/ripng_debug.c +++ b/ripngd/ripng_debug.c @@ -174,10 +174,13 @@ DEFUN (no_debug_ripng_zebra, return CMD_SUCCESS; } +static int config_write_debug(struct vty *vty); /* Debug node. */ static struct cmd_node debug_node = { - DEBUG_NODE, "", /* Debug node has no interface. */ - 1 /* VTYSH */ + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = config_write_debug, }; static int config_write_debug(struct vty *vty) @@ -213,7 +216,7 @@ void ripng_debug_init(void) ripng_debug_packet = 0; ripng_debug_zebra = 0; - install_node(&debug_node, config_write_debug); + install_node(&debug_node); install_element(VIEW_NODE, &show_debugging_ripng_cmd); diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index 25d9ed2b9e..e8c907227e 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -954,9 +954,14 @@ static int interface_config_write(struct vty *vty) return write; } +static int interface_config_write(struct vty *vty); /* ripngd's interface node. */ static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */ + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = interface_config_write, }; /* Initialization of interface. */ @@ -967,7 +972,7 @@ void ripng_if_init(void) hook_register_prio(if_del, 0, ripng_if_delete_hook); /* Install interface node. */ - install_node(&interface_node, interface_config_write); + install_node(&interface_node); if_cmd_init(); if_zapi_callbacks(ripng_ifp_create, ripng_ifp_up, ripng_ifp_down, ripng_ifp_destroy); diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index 99adb2cba7..fbac750db3 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -117,6 +117,7 @@ static const struct frr_yang_module_info *const ripngd_yang_modules[] = { &frr_interface_info, &frr_ripngd_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(ripngd, RIPNG, .vty_port = RIPNG_VTY_PORT, diff --git a/ripngd/ripng_nb.h b/ripngd/ripng_nb.h index 45e92e0a10..d6aecbf6b0 100644 --- a/ripngd/ripng_nb.h +++ b/ripngd/ripng_nb.h @@ -23,129 +23,82 @@ extern const struct frr_yang_module_info frr_ripngd_info; /* Mandatory callbacks. */ -int ripngd_instance_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_destroy(enum nb_event event, const struct lyd_node *dnode); -const void *ripngd_instance_get_next(const void *parent_list_entry, - const void *list_entry); -int ripngd_instance_get_keys(const void *list_entry, - struct yang_list_keys *keys); -const void *ripngd_instance_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys); -int ripngd_instance_allow_ecmp_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); +int ripngd_instance_create(struct nb_cb_create_args *args); +int ripngd_instance_destroy(struct nb_cb_destroy_args *args); +const void *ripngd_instance_get_next(struct nb_cb_get_next_args *args); +int ripngd_instance_get_keys(struct nb_cb_get_keys_args *args); +const void *ripngd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args); +int ripngd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args); int ripngd_instance_default_information_originate_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_default_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_network_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_network_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_interface_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_offset_list_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_offset_list_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_offset_list_access_list_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_offset_list_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_passive_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_passive_interface_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_redistribute_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_redistribute_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_redistribute_route_map_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_modify_args *args); +int ripngd_instance_default_metric_modify(struct nb_cb_modify_args *args); +int ripngd_instance_network_create(struct nb_cb_create_args *args); +int ripngd_instance_network_destroy(struct nb_cb_destroy_args *args); +int ripngd_instance_interface_create(struct nb_cb_create_args *args); +int ripngd_instance_interface_destroy(struct nb_cb_destroy_args *args); +int ripngd_instance_offset_list_create(struct nb_cb_create_args *args); +int ripngd_instance_offset_list_destroy(struct nb_cb_destroy_args *args); +int ripngd_instance_offset_list_access_list_modify( + struct nb_cb_modify_args *args); +int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args); +int ripngd_instance_passive_interface_create(struct nb_cb_create_args *args); +int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args); +int ripngd_instance_redistribute_create(struct nb_cb_create_args *args); +int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args *args); +int ripngd_instance_redistribute_route_map_modify( + struct nb_cb_modify_args *args); int ripngd_instance_redistribute_route_map_destroy( - enum nb_event event, const struct lyd_node *dnode); -int ripngd_instance_redistribute_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_redistribute_metric_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_static_route_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_static_route_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_aggregate_address_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_aggregate_address_destroy(enum nb_event event, - const struct lyd_node *dnode); -int ripngd_instance_timers_flush_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_destroy_args *args); +int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args); +int ripngd_instance_redistribute_metric_destroy( + struct nb_cb_destroy_args *args); +int ripngd_instance_static_route_create(struct nb_cb_create_args *args); +int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args *args); +int ripngd_instance_aggregate_address_create(struct nb_cb_create_args *args); +int ripngd_instance_aggregate_address_destroy(struct nb_cb_destroy_args *args); +int ripngd_instance_timers_flush_interval_modify( + struct nb_cb_modify_args *args); int ripngd_instance_timers_holddown_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource); -int ripngd_instance_timers_update_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); -const void * -ripngd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry, - const void *list_entry); + struct nb_cb_modify_args *args); +int ripngd_instance_timers_update_interval_modify( + struct nb_cb_modify_args *args); +const void *ripngd_instance_state_neighbors_neighbor_get_next( + struct nb_cb_get_next_args *args); int ripngd_instance_state_neighbors_neighbor_get_keys( - const void *list_entry, struct yang_list_keys *keys); + struct nb_cb_get_keys_args *args); const void *ripngd_instance_state_neighbors_neighbor_lookup_entry( - const void *parent_list_entry, const struct yang_list_keys *keys); + struct nb_cb_lookup_entry_args *args); struct yang_data *ripngd_instance_state_neighbors_neighbor_address_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data *ripngd_instance_state_neighbors_neighbor_last_update_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); struct yang_data * ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem( - const char *xpath, const void *list_entry); + struct nb_cb_get_elem_args *args); const void * -ripngd_instance_state_routes_route_get_next(const void *parent_list_entry, - const void *list_entry); -int ripngd_instance_state_routes_route_get_keys(const void *list_entry, - struct yang_list_keys *keys); +ripngd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args); +int ripngd_instance_state_routes_route_get_keys( + struct nb_cb_get_keys_args *args); const void *ripngd_instance_state_routes_route_lookup_entry( - const void *parent_list_entry, const struct yang_list_keys *keys); -struct yang_data * -ripngd_instance_state_routes_route_prefix_get_elem(const char *xpath, - const void *list_entry); -struct yang_data * -ripngd_instance_state_routes_route_next_hop_get_elem(const char *xpath, - const void *list_entry); -struct yang_data * -ripngd_instance_state_routes_route_interface_get_elem(const char *xpath, - const void *list_entry); -struct yang_data * -ripngd_instance_state_routes_route_metric_get_elem(const char *xpath, - const void *list_entry); -int clear_ripng_route_rpc(const char *xpath, const struct list *input, - struct list *output); -int lib_interface_ripng_split_horizon_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource); + struct nb_cb_lookup_entry_args *args); +struct yang_data *ripngd_instance_state_routes_route_prefix_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *ripngd_instance_state_routes_route_next_hop_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *ripngd_instance_state_routes_route_interface_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *ripngd_instance_state_routes_route_metric_get_elem( + struct nb_cb_get_elem_args *args); +int clear_ripng_route_rpc(struct nb_cb_rpc_args *args); +int lib_interface_ripng_split_horizon_modify(struct nb_cb_modify_args *args); /* Optional 'apply_finish' callbacks. */ -void ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode); -void ripngd_instance_timers_apply_finish(const struct lyd_node *dnode); +void ripngd_instance_redistribute_apply_finish( + struct nb_cb_apply_finish_args *args); +void ripngd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args); /* Optional 'cli_show' callbacks. */ void cli_show_router_ripng(struct vty *vty, struct lyd_node *dnode, diff --git a/ripngd/ripng_nb_config.c b/ripngd/ripng_nb_config.c index b39c1d443a..85f378bc9e 100644 --- a/ripngd/ripng_nb_config.c +++ b/ripngd/ripng_nb_config.c @@ -39,22 +39,21 @@ /* * XPath: /frr-ripngd:ripngd/instance */ -int ripngd_instance_create(enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_create(struct nb_cb_create_args *args) { struct ripng *ripng; struct vrf *vrf; const char *vrf_name; int socket; - vrf_name = yang_dnode_get_string(dnode, "./vrf"); + vrf_name = yang_dnode_get_string(args->dnode, "./vrf"); vrf = vrf_lookup_by_name(vrf_name); /* * Try to create a RIPng socket only if the VRF is enabled, otherwise * create a disabled RIPng instance and wait for the VRF to be enabled. */ - switch (event) { + switch (args->event) { case NB_EV_VALIDATE: break; case NB_EV_PREPARE: @@ -64,48 +63,47 @@ int ripngd_instance_create(enum nb_event event, const struct lyd_node *dnode, socket = ripng_make_socket(vrf); if (socket < 0) return NB_ERR_RESOURCE; - resource->fd = socket; + args->resource->fd = socket; break; case NB_EV_ABORT: if (!vrf || !vrf_is_enabled(vrf)) break; - socket = resource->fd; + socket = args->resource->fd; close(socket); break; case NB_EV_APPLY: if (vrf && vrf_is_enabled(vrf)) - socket = resource->fd; + socket = args->resource->fd; else socket = -1; ripng = ripng_create(vrf_name, vrf, socket); - nb_running_set_entry(dnode, ripng); + nb_running_set_entry(args->dnode, ripng); break; } return NB_OK; } -int ripngd_instance_destroy(enum nb_event event, const struct lyd_node *dnode) +int ripngd_instance_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_unset_entry(dnode); + ripng = nb_running_unset_entry(args->dnode); ripng_clean(ripng); return NB_OK; } -const void *ripngd_instance_get_next(const void *parent_list_entry, - const void *list_entry) +const void *ripngd_instance_get_next(struct nb_cb_get_next_args *args) { - struct ripng *ripng = (struct ripng *)list_entry; + struct ripng *ripng = (struct ripng *)args->list_entry; - if (list_entry == NULL) + if (args->list_entry == NULL) ripng = RB_MIN(ripng_instance_head, &ripng_instances); else ripng = RB_NEXT(ripng_instance_head, ripng); @@ -113,21 +111,20 @@ const void *ripngd_instance_get_next(const void *parent_list_entry, return ripng; } -int ripngd_instance_get_keys(const void *list_entry, - struct yang_list_keys *keys) +int ripngd_instance_get_keys(struct nb_cb_get_keys_args *args) { - const struct ripng *ripng = list_entry; + const struct ripng *ripng = args->list_entry; - keys->num = 1; - strlcpy(keys->key[0], ripng->vrf_name, sizeof(keys->key[0])); + args->keys->num = 1; + strlcpy(args->keys->key[0], ripng->vrf_name, + sizeof(args->keys->key[0])); return NB_OK; } -const void *ripngd_instance_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +const void *ripngd_instance_lookup_entry(struct nb_cb_lookup_entry_args *args) { - const char *vrf_name = keys->key[0]; + const char *vrf_name = args->keys->key[0]; return ripng_lookup_by_vrf_name(vrf_name); } @@ -135,17 +132,15 @@ const void *ripngd_instance_lookup_entry(const void *parent_list_entry, /* * XPath: /frr-ripngd:ripngd/instance/allow-ecmp */ -int ripngd_instance_allow_ecmp_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_allow_ecmp_modify(struct nb_cb_modify_args *args) { struct ripng *ripng; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ripng->ecmp = yang_dnode_get_bool(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ripng->ecmp = yang_dnode_get_bool(args->dnode, NULL); if (!ripng->ecmp) ripng_ecmp_disable(ripng); @@ -156,18 +151,17 @@ int ripngd_instance_allow_ecmp_modify(enum nb_event event, * XPath: /frr-ripngd:ripngd/instance/default-information-originate */ int ripngd_instance_default_information_originate_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct ripng *ripng; bool default_information; struct prefix_ipv6 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - default_information = yang_dnode_get_bool(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + default_information = yang_dnode_get_bool(args->dnode, NULL); str2prefix_ipv6("::/0", &p); if (default_information) { @@ -184,17 +178,15 @@ int ripngd_instance_default_information_originate_modify( /* * XPath: /frr-ripngd:ripngd/instance/default-metric */ -int ripngd_instance_default_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_default_metric_modify(struct nb_cb_modify_args *args) { struct ripng *ripng; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ripng->default_metric = yang_dnode_get_uint8(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ripng->default_metric = yang_dnode_get_uint8(args->dnode, NULL); return NB_OK; } @@ -202,34 +194,31 @@ int ripngd_instance_default_metric_modify(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/network */ -int ripngd_instance_network_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_network_create(struct nb_cb_create_args *args) { struct ripng *ripng; struct prefix p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv6p(&p, dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv6p(&p, args->dnode, NULL); apply_mask_ipv6((struct prefix_ipv6 *)&p); return ripng_enable_network_add(ripng, &p); } -int ripngd_instance_network_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_network_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; struct prefix p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv6p(&p, dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv6p(&p, args->dnode, NULL); apply_mask_ipv6((struct prefix_ipv6 *)&p); return ripng_enable_network_delete(ripng, &p); @@ -238,33 +227,30 @@ int ripngd_instance_network_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/interface */ -int ripngd_instance_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_interface_create(struct nb_cb_create_args *args) { struct ripng *ripng; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return ripng_enable_if_add(ripng, ifname); } -int ripngd_instance_interface_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_interface_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return ripng_enable_if_delete(ripng, ifname); } @@ -272,38 +258,35 @@ int ripngd_instance_interface_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/offset-list */ -int ripngd_instance_offset_list_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_offset_list_create(struct nb_cb_create_args *args) { struct ripng *ripng; const char *ifname; struct ripng_offset_list *offset; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, "./interface"); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, "./interface"); offset = ripng_offset_list_new(ripng, ifname); - nb_running_set_entry(dnode, offset); + nb_running_set_entry(args->dnode, offset); return NB_OK; } -int ripngd_instance_offset_list_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_offset_list_destroy(struct nb_cb_destroy_args *args) { int direct; struct ripng_offset_list *offset; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - direct = yang_dnode_get_enum(dnode, "./direction"); + direct = yang_dnode_get_enum(args->dnode, "./direction"); - offset = nb_running_unset_entry(dnode); + offset = nb_running_unset_entry(args->dnode); if (offset->direct[direct].alist_name) { free(offset->direct[direct].alist_name); offset->direct[direct].alist_name = NULL; @@ -318,21 +301,20 @@ int ripngd_instance_offset_list_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/offset-list/access-list */ -int ripngd_instance_offset_list_access_list_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_offset_list_access_list_modify( + struct nb_cb_modify_args *args) { int direct; struct ripng_offset_list *offset; const char *alist_name; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - direct = yang_dnode_get_enum(dnode, "../direction"); - alist_name = yang_dnode_get_string(dnode, NULL); + direct = yang_dnode_get_enum(args->dnode, "../direction"); + alist_name = yang_dnode_get_string(args->dnode, NULL); - offset = nb_running_get_entry(dnode, NULL, true); + offset = nb_running_get_entry(args->dnode, NULL, true); if (offset->direct[direct].alist_name) free(offset->direct[direct].alist_name); offset->direct[direct].alist_name = strdup(alist_name); @@ -343,21 +325,19 @@ int ripngd_instance_offset_list_access_list_modify(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/offset-list/metric */ -int ripngd_instance_offset_list_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args) { int direct; uint8_t metric; struct ripng_offset_list *offset; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - direct = yang_dnode_get_enum(dnode, "../direction"); - metric = yang_dnode_get_uint8(dnode, NULL); + direct = yang_dnode_get_enum(args->dnode, "../direction"); + metric = yang_dnode_get_uint8(args->dnode, NULL); - offset = nb_running_get_entry(dnode, NULL, true); + offset = nb_running_get_entry(args->dnode, NULL, true); offset->direct[direct].metric = metric; return NB_OK; @@ -366,33 +346,30 @@ int ripngd_instance_offset_list_metric_modify(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/passive-interface */ -int ripngd_instance_passive_interface_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_passive_interface_create(struct nb_cb_create_args *args) { struct ripng *ripng; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return ripng_passive_interface_set(ripng, ifname); } -int ripngd_instance_passive_interface_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; const char *ifname; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ifname = yang_dnode_get_string(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ifname = yang_dnode_get_string(args->dnode, NULL); return ripng_passive_interface_unset(ripng, ifname); } @@ -400,35 +377,32 @@ int ripngd_instance_passive_interface_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/redistribute */ -int ripngd_instance_redistribute_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_redistribute_create(struct nb_cb_create_args *args) { struct ripng *ripng; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "./protocol"); + ripng = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "./protocol"); ripng->redist[type].enabled = true; return NB_OK; } -int ripngd_instance_redistribute_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "./protocol"); + ripng = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "./protocol"); ripng->redist[type].enabled = false; if (ripng->redist[type].route_map.name) { @@ -445,13 +419,14 @@ int ripngd_instance_redistribute_destroy(enum nb_event event, return NB_OK; } -void ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode) +void ripngd_instance_redistribute_apply_finish( + struct nb_cb_apply_finish_args *args) { struct ripng *ripng; int type; - ripng = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "./protocol"); + ripng = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "./protocol"); if (ripng->enabled) ripng_redistribute_conf_update(ripng, type); @@ -460,20 +435,19 @@ void ripngd_instance_redistribute_apply_finish(const struct lyd_node *dnode) /* * XPath: /frr-ripngd:ripngd/instance/redistribute/route-map */ -int ripngd_instance_redistribute_route_map_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_redistribute_route_map_modify( + struct nb_cb_modify_args *args) { struct ripng *ripng; int type; const char *rmap_name; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); - rmap_name = yang_dnode_get_string(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); + rmap_name = yang_dnode_get_string(args->dnode, NULL); if (ripng->redist[type].route_map.name) free(ripng->redist[type].route_map.name); @@ -483,17 +457,17 @@ int ripngd_instance_redistribute_route_map_modify(enum nb_event event, return NB_OK; } -int ripngd_instance_redistribute_route_map_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_redistribute_route_map_destroy( + struct nb_cb_destroy_args *args) { struct ripng *ripng; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); + ripng = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); free(ripng->redist[type].route_map.name); ripng->redist[type].route_map.name = NULL; @@ -505,20 +479,18 @@ int ripngd_instance_redistribute_route_map_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/redistribute/metric */ -int ripngd_instance_redistribute_metric_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args) { struct ripng *ripng; int type; uint8_t metric; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); - metric = yang_dnode_get_uint8(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); + metric = yang_dnode_get_uint8(args->dnode, NULL); ripng->redist[type].metric_config = true; ripng->redist[type].metric = metric; @@ -526,17 +498,16 @@ int ripngd_instance_redistribute_metric_modify(enum nb_event event, return NB_OK; } -int ripngd_instance_redistribute_metric_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; int type; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_enum(dnode, "../protocol"); + ripng = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_enum(args->dnode, "../protocol"); ripng->redist[type].metric_config = false; ripng->redist[type].metric = 0; @@ -547,18 +518,16 @@ int ripngd_instance_redistribute_metric_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/static-route */ -int ripngd_instance_static_route_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_static_route_create(struct nb_cb_create_args *args) { struct ripng *ripng; struct prefix_ipv6 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv6p(&p, dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv6p(&p, args->dnode, NULL); apply_mask_ipv6(&p); ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, &p, @@ -567,17 +536,16 @@ int ripngd_instance_static_route_create(enum nb_event event, return NB_OK; } -int ripngd_instance_static_route_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; struct prefix_ipv6 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv6p(&p, dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv6p(&p, args->dnode, NULL); apply_mask_ipv6(&p); ripng_redistribute_delete(ripng, ZEBRA_ROUTE_RIPNG, RIPNG_ROUTE_STATIC, @@ -589,18 +557,16 @@ int ripngd_instance_static_route_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/aggregate-address */ -int ripngd_instance_aggregate_address_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_aggregate_address_create(struct nb_cb_create_args *args) { struct ripng *ripng; struct prefix_ipv6 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv6p(&p, dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv6p(&p, args->dnode, NULL); apply_mask_ipv6(&p); ripng_aggregate_add(ripng, (struct prefix *)&p); @@ -608,17 +574,16 @@ int ripngd_instance_aggregate_address_create(enum nb_event event, return NB_OK; } -int ripngd_instance_aggregate_address_destroy(enum nb_event event, - const struct lyd_node *dnode) +int ripngd_instance_aggregate_address_destroy(struct nb_cb_destroy_args *args) { struct ripng *ripng; struct prefix_ipv6 p; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - yang_dnode_get_ipv6p(&p, dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_ipv6p(&p, args->dnode, NULL); apply_mask_ipv6(&p); ripng_aggregate_delete(ripng, (struct prefix *)&p); @@ -629,11 +594,11 @@ int ripngd_instance_aggregate_address_destroy(enum nb_event event, /* * XPath: /frr-ripngd:ripngd/instance/timers */ -void ripngd_instance_timers_apply_finish(const struct lyd_node *dnode) +void ripngd_instance_timers_apply_finish(struct nb_cb_apply_finish_args *args) { struct ripng *ripng; - ripng = nb_running_get_entry(dnode, NULL, true); + ripng = nb_running_get_entry(args->dnode, NULL, true); /* Reset update timer thread. */ ripng_event(ripng, RIPNG_UPDATE_EVENT, 0); @@ -642,17 +607,15 @@ void ripngd_instance_timers_apply_finish(const struct lyd_node *dnode) /* * XPath: /frr-ripngd:ripngd/instance/timers/flush-interval */ -int ripngd_instance_timers_flush_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args) { struct ripng *ripng; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ripng->garbage_time = yang_dnode_get_uint16(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ripng->garbage_time = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -661,16 +624,15 @@ int ripngd_instance_timers_flush_interval_modify(enum nb_event event, * XPath: /frr-ripngd:ripngd/instance/timers/holddown-interval */ int ripngd_instance_timers_holddown_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { struct ripng *ripng; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ripng->timeout_time = yang_dnode_get_uint16(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ripng->timeout_time = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -678,17 +640,16 @@ int ripngd_instance_timers_holddown_interval_modify( /* * XPath: /frr-ripngd:ripngd/instance/timers/update-interval */ -int ripngd_instance_timers_update_interval_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int ripngd_instance_timers_update_interval_modify( + struct nb_cb_modify_args *args) { struct ripng *ripng; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ripng = nb_running_get_entry(dnode, NULL, true); - ripng->update_time = yang_dnode_get_uint16(dnode, NULL); + ripng = nb_running_get_entry(args->dnode, NULL, true); + ripng->update_time = yang_dnode_get_uint16(args->dnode, NULL); return NB_OK; } @@ -696,19 +657,17 @@ int ripngd_instance_timers_update_interval_modify(enum nb_event event, /* * XPath: /frr-interface:lib/interface/frr-ripngd:ripng/split-horizon */ -int lib_interface_ripng_split_horizon_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +int lib_interface_ripng_split_horizon_modify(struct nb_cb_modify_args *args) { struct interface *ifp; struct ripng_interface *ri; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); + ifp = nb_running_get_entry(args->dnode, NULL, true); ri = ifp->info; - ri->split_horizon = yang_dnode_get_enum(dnode, NULL); + ri->split_horizon = yang_dnode_get_enum(args->dnode, NULL); return NB_OK; } diff --git a/ripngd/ripng_nb_rpcs.c b/ripngd/ripng_nb_rpcs.c index 0396daf890..4dfe9d9640 100644 --- a/ripngd/ripng_nb_rpcs.c +++ b/ripngd/ripng_nb_rpcs.c @@ -80,13 +80,13 @@ static void clear_ripng_route(struct ripng *ripng) } } -int clear_ripng_route_rpc(const char *xpath, const struct list *input, - struct list *output) +int clear_ripng_route_rpc(struct nb_cb_rpc_args *args) { struct ripng *ripng; struct yang_data *yang_vrf; - yang_vrf = yang_data_list_find(input, "%s/%s", xpath, "input/vrf"); + yang_vrf = yang_data_list_find(args->input, "%s/%s", args->xpath, + "input/vrf"); if (yang_vrf) { ripng = ripng_lookup_by_vrf_name(yang_vrf->value); if (ripng) diff --git a/ripngd/ripng_nb_state.c b/ripngd/ripng_nb_state.c index 75dec3cb3e..926573b407 100644 --- a/ripngd/ripng_nb_state.c +++ b/ripngd/ripng_nb_state.c @@ -38,43 +38,42 @@ /* * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor */ -const void * -ripngd_instance_state_neighbors_neighbor_get_next(const void *parent_list_entry, - const void *list_entry) +const void *ripngd_instance_state_neighbors_neighbor_get_next( + struct nb_cb_get_next_args *args) { - const struct ripng *ripng = parent_list_entry; + const struct ripng *ripng = args->parent_list_entry; struct listnode *node; - if (list_entry == NULL) + if (args->list_entry == NULL) node = listhead(ripng->peer_list); else - node = listnextnode((struct listnode *)list_entry); + node = listnextnode((struct listnode *)args->list_entry); return node; } int ripngd_instance_state_neighbors_neighbor_get_keys( - const void *list_entry, struct yang_list_keys *keys) + struct nb_cb_get_keys_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct ripng_peer *peer = listgetdata(node); - keys->num = 1; - (void)inet_ntop(AF_INET6, &peer->addr, keys->key[0], - sizeof(keys->key[0])); + args->keys->num = 1; + (void)inet_ntop(AF_INET6, &peer->addr, args->keys->key[0], + sizeof(args->keys->key[0])); return NB_OK; } const void *ripngd_instance_state_neighbors_neighbor_lookup_entry( - const void *parent_list_entry, const struct yang_list_keys *keys) + struct nb_cb_lookup_entry_args *args) { - const struct ripng *ripng = parent_list_entry; + const struct ripng *ripng = args->parent_list_entry; struct in6_addr address; struct ripng_peer *peer; struct listnode *node; - yang_str2ipv6(keys->key[0], &address); + yang_str2ipv6(args->keys->key[0], &address); for (ALL_LIST_ELEMENTS_RO(ripng->peer_list, node, peer)) { if (IPV6_ADDR_SAME(&peer->addr, &address)) @@ -88,19 +87,19 @@ const void *ripngd_instance_state_neighbors_neighbor_lookup_entry( * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/address */ struct yang_data *ripngd_instance_state_neighbors_neighbor_address_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct ripng_peer *peer = listgetdata(node); - return yang_data_new_ipv6(xpath, &peer->addr); + return yang_data_new_ipv6(args->xpath, &peer->addr); } /* * XPath: /frr-ripngd:ripngd/instance/state/neighbors/neighbor/last-update */ struct yang_data *ripngd_instance_state_neighbors_neighbor_last_update_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { /* TODO: yang:date-and-time is tricky */ return NULL; @@ -111,12 +110,12 @@ struct yang_data *ripngd_instance_state_neighbors_neighbor_last_update_get_elem( */ struct yang_data * ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct ripng_peer *peer = listgetdata(node); - return yang_data_new_uint32(xpath, peer->recv_badpackets); + return yang_data_new_uint32(args->xpath, peer->recv_badpackets); } /* @@ -124,54 +123,53 @@ ripngd_instance_state_neighbors_neighbor_bad_packets_rcvd_get_elem( */ struct yang_data * ripngd_instance_state_neighbors_neighbor_bad_routes_rcvd_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct listnode *node = list_entry; + const struct listnode *node = args->list_entry; const struct ripng_peer *peer = listgetdata(node); - return yang_data_new_uint32(xpath, peer->recv_badroutes); + return yang_data_new_uint32(args->xpath, peer->recv_badroutes); } /* * XPath: /frr-ripngd:ripngd/instance/state/routes/route */ const void * -ripngd_instance_state_routes_route_get_next(const void *parent_list_entry, - const void *list_entry) +ripngd_instance_state_routes_route_get_next(struct nb_cb_get_next_args *args) { - const struct ripng *ripng = parent_list_entry; + const struct ripng *ripng = args->parent_list_entry; struct agg_node *rn; - if (list_entry == NULL) + if (args->list_entry == NULL) rn = agg_route_top(ripng->table); else - rn = agg_route_next((struct agg_node *)list_entry); + rn = agg_route_next((struct agg_node *)args->list_entry); while (rn && rn->info == NULL) rn = agg_route_next(rn); return rn; } -int ripngd_instance_state_routes_route_get_keys(const void *list_entry, - struct yang_list_keys *keys) +int ripngd_instance_state_routes_route_get_keys( + struct nb_cb_get_keys_args *args) { - const struct agg_node *rn = list_entry; + const struct agg_node *rn = args->list_entry; - keys->num = 1; - (void)prefix2str(agg_node_get_prefix(rn), keys->key[0], - sizeof(keys->key[0])); + args->keys->num = 1; + (void)prefix2str(agg_node_get_prefix(rn), args->keys->key[0], + sizeof(args->keys->key[0])); return NB_OK; } const void *ripngd_instance_state_routes_route_lookup_entry( - const void *parent_list_entry, const struct yang_list_keys *keys) + struct nb_cb_lookup_entry_args *args) { - const struct ripng *ripng = parent_list_entry; + const struct ripng *ripng = args->parent_list_entry; struct prefix prefix; struct agg_node *rn; - yang_str2ipv6p(keys->key[0], &prefix); + yang_str2ipv6p(args->keys->key[0], &prefix); rn = agg_node_lookup(ripng->table, &prefix); if (!rn || !rn->info) @@ -185,53 +183,50 @@ const void *ripngd_instance_state_routes_route_lookup_entry( /* * XPath: /frr-ripngd:ripngd/instance/state/routes/route/prefix */ -struct yang_data * -ripngd_instance_state_routes_route_prefix_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripngd_instance_state_routes_route_prefix_get_elem( + struct nb_cb_get_elem_args *args) { - const struct agg_node *rn = list_entry; + const struct agg_node *rn = args->list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); - return yang_data_new_ipv6p(xpath, agg_node_get_prefix(rinfo->rp)); + return yang_data_new_ipv6p(args->xpath, agg_node_get_prefix(rinfo->rp)); } /* * XPath: /frr-ripngd:ripngd/instance/state/routes/route/next-hop */ -struct yang_data * -ripngd_instance_state_routes_route_next_hop_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripngd_instance_state_routes_route_next_hop_get_elem( + struct nb_cb_get_elem_args *args) { - const struct agg_node *rn = list_entry; + const struct agg_node *rn = args->list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); - return yang_data_new_ipv6(xpath, &rinfo->nexthop); + return yang_data_new_ipv6(args->xpath, &rinfo->nexthop); } /* * XPath: /frr-ripngd:ripngd/instance/state/routes/route/interface */ -struct yang_data * -ripngd_instance_state_routes_route_interface_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripngd_instance_state_routes_route_interface_get_elem( + struct nb_cb_get_elem_args *args) { - const struct agg_node *rn = list_entry; + const struct agg_node *rn = args->list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); const struct ripng *ripng = ripng_info_get_instance(rinfo); return yang_data_new_string( - xpath, ifindex2ifname(rinfo->ifindex, ripng->vrf->vrf_id)); + args->xpath, + ifindex2ifname(rinfo->ifindex, ripng->vrf->vrf_id)); } /* * XPath: /frr-ripngd:ripngd/instance/state/routes/route/metric */ -struct yang_data * -ripngd_instance_state_routes_route_metric_get_elem(const char *xpath, - const void *list_entry) +struct yang_data *ripngd_instance_state_routes_route_metric_get_elem( + struct nb_cb_get_elem_args *args) { - const struct agg_node *rn = list_entry; + const struct agg_node *rn = args->list_entry; const struct ripng_info *rinfo = listnode_head(rn->info); - return yang_data_new_uint8(xpath, rinfo->metric); + return yang_data_new_uint8(args->xpath, rinfo->metric); } diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 1ea006abd6..625adcaa3c 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -37,6 +37,7 @@ #include "privs.h" #include "lib_errors.h" #include "northbound_cli.h" +#include "network.h" #include "ripngd/ripngd.h" #include "ripngd/ripng_route.h" @@ -1545,7 +1546,7 @@ int ripng_triggered_update(struct thread *t) random interval between 1 and 5 seconds. If other changes that would trigger updates occur before the timer expires, a single update is triggered when the timer expires. */ - interval = (random() % 5) + 1; + interval = (frr_weak_random() % 5) + 1; ripng->t_triggered_interval = NULL; thread_add_timer(master, ripng_triggered_interval, ripng, interval, @@ -1950,7 +1951,7 @@ int ripng_request(struct interface *ifp) static int ripng_update_jitter(int time) { - return ((random() % (time + 1)) - (time / 2)); + return ((frr_weak_random() % (time + 1)) - (time / 2)); } void ripng_event(struct ripng *ripng, enum ripng_event event, int sock) @@ -2434,9 +2435,14 @@ static int ripng_config_write(struct vty *vty) return write; } +static int ripng_config_write(struct vty *vty); /* RIPng node structure. */ static struct cmd_node cmd_ripng_node = { - RIPNG_NODE, "%s(config-router)# ", 1, + .name = "ripng", + .node = RIPNG_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", + .config_write = ripng_config_write, }; static void ripng_distribute_update(struct distribute_ctx *ctx, @@ -2850,7 +2856,7 @@ void ripng_vrf_terminate(void) void ripng_init(void) { /* Install RIPNG_NODE. */ - install_node(&cmd_ripng_node, ripng_config_write); + install_node(&cmd_ripng_node); /* Install ripng commands. */ install_element(VIEW_NODE, &show_ipv6_ripng_cmd); diff --git a/ripngd/subdir.am b/ripngd/subdir.am index 4e219c9947..48ba361372 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -6,9 +6,9 @@ if RIPNGD noinst_LIBRARIES += ripngd/libripng.a sbin_PROGRAMS += ripngd/ripngd vtysh_scan += \ - $(top_srcdir)/ripngd/ripng_cli.c \ - $(top_srcdir)/ripngd/ripng_debug.c \ - $(top_srcdir)/ripngd/ripngd.c \ + ripngd/ripng_cli.c \ + ripngd/ripng_debug.c \ + ripngd/ripngd.c \ # end man8 += $(MANBUILD)/frr-ripngd.8 endif @@ -30,8 +30,9 @@ ripngd_libripng_a_SOURCES = \ ripngd/ripngd.c \ # end -ripngd/ripng_cli_clippy.c: $(CLIPPY_DEPS) -ripngd/ripng_cli.$(OBJEXT): ripngd/ripng_cli_clippy.c +clippy_scan += \ + ripngd/ripng_cli.c \ + # end noinst_HEADERS += \ ripngd/ripng_debug.h \ diff --git a/sharpd/sharp_logpump.c b/sharpd/sharp_logpump.c index d07e2d273f..322d802b8a 100644 --- a/sharpd/sharp_logpump.c +++ b/sharpd/sharp_logpump.c @@ -77,6 +77,8 @@ static void *logpump_run(void *arg) period = 1000000000L / lp_frequency; + zlog_tls_buffer_init(); + clock_gettime(CLOCK_MONOTONIC, &start); next = start; do { @@ -109,6 +111,8 @@ static void *logpump_run(void *arg) #endif } while (delta < lp_duration); + zlog_tls_buffer_fini(); + #ifdef RUSAGE_THREAD getrusage(RUSAGE_THREAD, &lp_rusage); #else diff --git a/sharpd/sharp_main.c b/sharpd/sharp_main.c index 5133523f01..120d704918 100644 --- a/sharpd/sharp_main.c +++ b/sharpd/sharp_main.c @@ -114,6 +114,7 @@ struct quagga_signal_t sharp_signals[] = { static const struct frr_yang_module_info *const sharpd_yang_modules[] = { &frr_interface_info, &frr_route_map_info, + &frr_vrf_info, }; FRR_DAEMON_INFO(sharpd, SHARP, .vty_port = SHARP_VTY_PORT, diff --git a/sharpd/subdir.am b/sharpd/subdir.am index 8b32b2370c..4c43c50d43 100644 --- a/sharpd/subdir.am +++ b/sharpd/subdir.am @@ -6,7 +6,7 @@ if SHARPD noinst_LIBRARIES += sharpd/libsharp.a sbin_PROGRAMS += sharpd/sharpd dist_examples_DATA += sharpd/sharpd.conf.sample -vtysh_scan += $(top_srcdir)/sharpd/sharp_vty.c +vtysh_scan += sharpd/sharp_vty.c man8 += $(MANBUILD)/frr-sharpd.8 endif @@ -24,8 +24,9 @@ noinst_HEADERS += \ sharpd/sharp_zebra.h \ # end -sharpd/sharp_vty_clippy.c: $(CLIPPY_DEPS) -sharpd/sharp_vty.$(OBJEXT): sharpd/sharp_vty_clippy.c +clippy_scan += \ + sharpd/sharp_vty.c \ + # end sharpd_sharpd_SOURCES = sharpd/sharp_main.c sharpd_sharpd_LDADD = sharpd/libsharp.a lib/libfrr.la $(LIBCAP) diff --git a/staticd/static_main.c b/staticd/static_main.c index 3aa8a8db3e..c77a99f280 100644 --- a/staticd/static_main.c +++ b/staticd/static_main.c @@ -104,6 +104,7 @@ struct quagga_signal_t static_signals[] = { }; static const struct frr_yang_module_info *const staticd_yang_modules[] = { + &frr_vrf_info, }; #define STATIC_VTY_PORT 2616 diff --git a/staticd/static_vty.c b/staticd/static_vty.c index a950b0473e..75bce82eef 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -614,8 +614,8 @@ int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi, if (stable == NULL) return write; - sprintf(spacing, "%s%s", (svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", - cmd); + snprintf(spacing, sizeof(spacing), "%s%s", + (svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", cmd); /* * Static routes for vrfs not fully inited @@ -1470,11 +1470,16 @@ DEFUN_NOSH (show_debugging_static, return CMD_SUCCESS; } -static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = static_config_write_debug, +}; void static_vty_init(void) { - install_node(&debug_node, static_config_write_debug); + install_node(&debug_node); install_element(CONFIG_NODE, &ip_mroute_dist_cmd); diff --git a/staticd/subdir.am b/staticd/subdir.am index 30c69231c9..f2b3d11f29 100644 --- a/staticd/subdir.am +++ b/staticd/subdir.am @@ -6,7 +6,7 @@ if STATICD noinst_LIBRARIES += staticd/libstatic.a sbin_PROGRAMS += staticd/staticd dist_examples_DATA += staticd/staticd.conf.sample -vtysh_scan += $(top_srcdir)/staticd/static_vty.c +vtysh_scan += staticd/static_vty.c man8 += $(MANBUILD)/frr-staticd.8 endif @@ -30,8 +30,9 @@ noinst_HEADERS += \ staticd/static_vrf.h \ # end -staticd/static_vty_clippy.c: $(CLIPPY_DEPS) -staticd/static_vty.$(OBJEXT): staticd/static_vty_clippy.c +clippy_scan += \ + staticd/static_vty.c \ + # end staticd_staticd_SOURCES = staticd/static_main.c staticd_staticd_LDADD = staticd/libstatic.a lib/libfrr.la $(LIBCAP) diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c index 490b0ee73b..f6a892df42 100644 --- a/tests/bgpd/test_peer_attr.c +++ b/tests/bgpd/test_peer_attr.c @@ -1381,8 +1381,7 @@ static void test_peer_attr(struct test *test, struct test_peer_attr *pa) static void bgp_startup(void) { cmd_init(1); - openzlog("testbgpd", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_DAEMON); + zlog_aux_init("NONE: ", LOG_DEBUG); zprivs_preinit(&bgpd_privs); zprivs_init(&bgpd_privs); @@ -1438,7 +1437,6 @@ static void bgp_shutdown(void) zprivs_terminate(&bgpd_privs); thread_master_free(master); master = NULL; - closezlog(); } int main(void) diff --git a/tests/lib/cli/common_cli.c b/tests/lib/cli/common_cli.c index bd81656ca9..3cade4a2c9 100644 --- a/tests/lib/cli/common_cli.c +++ b/tests/lib/cli/common_cli.c @@ -53,7 +53,6 @@ static void vty_do_exit(int isexit) nb_terminate(); yang_terminate(); thread_master_free(master); - closezlog(); log_memstats(stderr, "testcli"); if (!isexit) @@ -71,11 +70,7 @@ int main(int argc, char **argv) /* master init. */ master = thread_master_create(NULL); - openzlog("common-cli", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_DAEMON); - zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED); - zlog_set_level(ZLOG_DEST_STDOUT, ZLOG_DISABLED); - zlog_set_level(ZLOG_DEST_MONITOR, LOG_DEBUG); + zlog_aux_init("NONE: ", ZLOG_DISABLED); /* Library inits. */ cmd_init(1); diff --git a/tests/lib/cli/test_commands.c b/tests/lib/cli/test_commands.c index 779a7539e9..2b345c91e8 100644 --- a/tests/lib/cli/test_commands.c +++ b/tests/lib/cli/test_commands.c @@ -49,50 +49,116 @@ static vector test_cmds; static char test_buf[32768]; static struct cmd_node bgp_node = { - BGP_NODE, "%s(config-router)# ", + .name = "bgp", + .node = BGP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", }; static struct cmd_node rip_node = { - RIP_NODE, "%s(config-router)# ", + .name = "rip", + .node = RIP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", }; static struct cmd_node isis_node = { - ISIS_NODE, "%s(config-router)# ", + .name = "isis", + .node = ISIS_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", }; static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", }; -static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# "}; +static struct cmd_node rmap_node = { + .name = "routemap", + .node = RMAP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-route-map)# ", +}; -static struct cmd_node zebra_node = {ZEBRA_NODE, "%s(config-router)# "}; +static struct cmd_node zebra_node = { + .name = "zebra", + .node = ZEBRA_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node bgp_vpnv4_node = {BGP_VPNV4_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_vpnv4_node = { + .name = "bgp vpnv4", + .node = BGP_VPNV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv4_node = {BGP_IPV4_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv4_node = { + .name = "bgp ipv4 unicast", + .node = BGP_IPV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv4m_node = {BGP_IPV4M_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv4m_node = { + .name = "bgp ipv4 multicast", + .node = BGP_IPV4M_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv6_node = {BGP_IPV6_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv6_node = { + .name = "bgp ipv6", + .node = BGP_IPV6_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv6m_node = {BGP_IPV6M_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv6m_node = { + .name = "bgp ipv6 multicast", + .node = BGP_IPV6M_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node ospf_node = {OSPF_NODE, "%s(config-router)# "}; +static struct cmd_node ospf_node = { + .name = "ospf", + .node = OSPF_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node ripng_node = {RIPNG_NODE, "%s(config-router)# "}; +static struct cmd_node ripng_node = { + .name = "ripng", + .node = RIPNG_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node ospf6_node = {OSPF6_NODE, "%s(config-ospf6)# "}; +static struct cmd_node ospf6_node = { + .name = "ospf6", + .node = OSPF6_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-ospf6)# ", +}; -static struct cmd_node keychain_node = {KEYCHAIN_NODE, "%s(config-keychain)# "}; +static struct cmd_node keychain_node = { + .name = "keychain", + .node = KEYCHAIN_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-keychain)# ", +}; -static struct cmd_node keychain_key_node = {KEYCHAIN_KEY_NODE, - "%s(config-keychain-key)# "}; +static struct cmd_node keychain_key_node = { + .name = "keychain key", + .node = KEYCHAIN_KEY_NODE, + .parent_node = KEYCHAIN_NODE, + .prompt = "%s(config-keychain-key)# ", +}; static int test_callback(const struct cmd_element *cmd, struct vty *vty, int argc, struct cmd_token *argv[]) @@ -145,23 +211,23 @@ static void test_init(void) yang_init(true); nb_init(master, NULL, 0); - install_node(&bgp_node, NULL); - install_node(&rip_node, NULL); - install_node(&interface_node, NULL); - install_node(&rmap_node, NULL); - install_node(&zebra_node, NULL); - install_node(&bgp_vpnv4_node, NULL); - install_node(&bgp_ipv4_node, NULL); - install_node(&bgp_ipv4m_node, NULL); - install_node(&bgp_ipv6_node, NULL); - install_node(&bgp_ipv6m_node, NULL); - install_node(&ospf_node, NULL); - install_node(&ripng_node, NULL); - install_node(&ospf6_node, NULL); - install_node(&keychain_node, NULL); - install_node(&keychain_key_node, NULL); - install_node(&isis_node, NULL); - install_node(&vty_node, NULL); + install_node(&bgp_node); + install_node(&rip_node); + install_node(&interface_node); + install_node(&rmap_node); + install_node(&zebra_node); + install_node(&bgp_vpnv4_node); + install_node(&bgp_ipv4_node); + install_node(&bgp_ipv4m_node); + install_node(&bgp_ipv6_node); + install_node(&bgp_ipv6m_node); + install_node(&ospf_node); + install_node(&ripng_node); + install_node(&ospf6_node); + install_node(&keychain_node); + install_node(&keychain_key_node); + install_node(&isis_node); + install_node(&vty_node); test_init_cmd(); diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c index 786fce33f9..202a321e1a 100644 --- a/tests/lib/northbound/test_oper_data.c +++ b/tests/lib/northbound/test_oper_data.c @@ -49,41 +49,38 @@ static struct list *vrfs; * XPath: /frr-test-module:frr-test-module/vrfs/vrf */ static const void * -frr_test_module_vrfs_vrf_get_next(const void *parent_list_entry, - const void *list_entry) +frr_test_module_vrfs_vrf_get_next(struct nb_cb_get_next_args *args) { struct listnode *node; - if (list_entry == NULL) + if (args->list_entry == NULL) node = listhead(vrfs); else - node = listnextnode((struct listnode *)list_entry); + node = listnextnode((struct listnode *)args->list_entry); return node; } -static int frr_test_module_vrfs_vrf_get_keys(const void *list_entry, - struct yang_list_keys *keys) +static int frr_test_module_vrfs_vrf_get_keys(struct nb_cb_get_keys_args *args) { const struct tvrf *vrf; - vrf = listgetdata((struct listnode *)list_entry); + vrf = listgetdata((struct listnode *)args->list_entry); - keys->num = 1; - strlcpy(keys->key[0], vrf->name, sizeof(keys->key[0])); + args->keys->num = 1; + strlcpy(args->keys->key[0], vrf->name, sizeof(args->keys->key[0])); return NB_OK; } static const void * -frr_test_module_vrfs_vrf_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +frr_test_module_vrfs_vrf_lookup_entry(struct nb_cb_lookup_entry_args *args) { struct listnode *node; struct tvrf *vrf; const char *vrfname; - vrfname = keys->key[0]; + vrfname = args->keys->key[0]; for (ALL_LIST_ELEMENTS_RO(vrfs, node, vrf)) { if (strmatch(vrf->name, vrfname)) @@ -97,39 +94,37 @@ frr_test_module_vrfs_vrf_lookup_entry(const void *parent_list_entry, * XPath: /frr-test-module:frr-test-module/vrfs/vrf/name */ static struct yang_data * -frr_test_module_vrfs_vrf_name_get_elem(const char *xpath, - const void *list_entry) +frr_test_module_vrfs_vrf_name_get_elem(struct nb_cb_get_elem_args *args) { const struct tvrf *vrf; - vrf = listgetdata((struct listnode *)list_entry); - return yang_data_new_string(xpath, vrf->name); + vrf = listgetdata((struct listnode *)args->list_entry); + return yang_data_new_string(args->xpath, vrf->name); } /* * XPath: /frr-test-module:frr-test-module/vrfs/vrf/interfaces/interface */ -static struct yang_data * -frr_test_module_vrfs_vrf_interfaces_interface_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *frr_test_module_vrfs_vrf_interfaces_interface_get_elem( + struct nb_cb_get_elem_args *args) { const char *interface; - interface = listgetdata((struct listnode *)list_entry); - return yang_data_new_string(xpath, interface); + interface = listgetdata((struct listnode *)args->list_entry); + return yang_data_new_string(args->xpath, interface); } static const void *frr_test_module_vrfs_vrf_interfaces_interface_get_next( - const void *parent_list_entry, const void *list_entry) + struct nb_cb_get_next_args *args) { const struct tvrf *vrf; struct listnode *node; - vrf = listgetdata((struct listnode *)parent_list_entry); - if (list_entry == NULL) + vrf = listgetdata((struct listnode *)args->parent_list_entry); + if (args->list_entry == NULL) node = listhead(vrf->interfaces); else - node = listnextnode((struct listnode *)list_entry); + node = listnextnode((struct listnode *)args->list_entry); return node; } @@ -138,17 +133,16 @@ static const void *frr_test_module_vrfs_vrf_interfaces_interface_get_next( * XPath: /frr-test-module:frr-test-module/vrfs/vrf/routes/route */ static const void * -frr_test_module_vrfs_vrf_routes_route_get_next(const void *parent_list_entry, - const void *list_entry) +frr_test_module_vrfs_vrf_routes_route_get_next(struct nb_cb_get_next_args *args) { const struct tvrf *vrf; struct listnode *node; - vrf = listgetdata((struct listnode *)parent_list_entry); - if (list_entry == NULL) + vrf = listgetdata((struct listnode *)args->parent_list_entry); + if (args->list_entry == NULL) node = listhead(vrf->routes); else - node = listnextnode((struct listnode *)list_entry); + node = listnextnode((struct listnode *)args->list_entry); return node; } @@ -156,67 +150,64 @@ frr_test_module_vrfs_vrf_routes_route_get_next(const void *parent_list_entry, /* * XPath: /frr-test-module:frr-test-module/vrfs/vrf/routes/route/prefix */ -static struct yang_data * -frr_test_module_vrfs_vrf_routes_route_prefix_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *frr_test_module_vrfs_vrf_routes_route_prefix_get_elem( + struct nb_cb_get_elem_args *args) { const struct troute *route; - route = listgetdata((struct listnode *)list_entry); - return yang_data_new_ipv4p(xpath, &route->prefix); + route = listgetdata((struct listnode *)args->list_entry); + return yang_data_new_ipv4p(args->xpath, &route->prefix); } /* * XPath: /frr-test-module:frr-test-module/vrfs/vrf/routes/route/next-hop */ static struct yang_data * -frr_test_module_vrfs_vrf_routes_route_next_hop_get_elem(const char *xpath, - const void *list_entry) +frr_test_module_vrfs_vrf_routes_route_next_hop_get_elem( + struct nb_cb_get_elem_args *args) { const struct troute *route; - route = listgetdata((struct listnode *)list_entry); - return yang_data_new_ipv4(xpath, &route->nexthop); + route = listgetdata((struct listnode *)args->list_entry); + return yang_data_new_ipv4(args->xpath, &route->nexthop); } /* * XPath: /frr-test-module:frr-test-module/vrfs/vrf/routes/route/interface */ static struct yang_data * -frr_test_module_vrfs_vrf_routes_route_interface_get_elem(const char *xpath, - const void *list_entry) +frr_test_module_vrfs_vrf_routes_route_interface_get_elem( + struct nb_cb_get_elem_args *args) { const struct troute *route; - route = listgetdata((struct listnode *)list_entry); - return yang_data_new_string(xpath, route->ifname); + route = listgetdata((struct listnode *)args->list_entry); + return yang_data_new_string(args->xpath, route->ifname); } /* * XPath: /frr-test-module:frr-test-module/vrfs/vrf/routes/route/metric */ -static struct yang_data * -frr_test_module_vrfs_vrf_routes_route_metric_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *frr_test_module_vrfs_vrf_routes_route_metric_get_elem( + struct nb_cb_get_elem_args *args) { const struct troute *route; - route = listgetdata((struct listnode *)list_entry); - return yang_data_new_uint8(xpath, route->metric); + route = listgetdata((struct listnode *)args->list_entry); + return yang_data_new_uint8(args->xpath, route->metric); } /* * XPath: /frr-test-module:frr-test-module/vrfs/vrf/routes/route/active */ -static struct yang_data * -frr_test_module_vrfs_vrf_routes_route_active_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *frr_test_module_vrfs_vrf_routes_route_active_get_elem( + struct nb_cb_get_elem_args *args) { const struct troute *route; - route = listgetdata((struct listnode *)list_entry); + route = listgetdata((struct listnode *)args->list_entry); if (route->active) - return yang_data_new(xpath, NULL); + return yang_data_new(args->xpath, NULL); return NULL; } @@ -374,7 +365,6 @@ static void vty_do_exit(int isexit) nb_terminate(); yang_terminate(); thread_master_free(master); - closezlog(); log_memstats(stderr, "test-nb-oper-data"); if (!isexit) @@ -402,11 +392,7 @@ int main(int argc, char **argv) /* master init. */ master = thread_master_create(NULL); - openzlog("test-nb-oper-data", "NONE", 0, - LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); - zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED); - zlog_set_level(ZLOG_DEST_STDOUT, ZLOG_DISABLED); - zlog_set_level(ZLOG_DEST_MONITOR, LOG_DEBUG); + zlog_aux_init("NONE: ", ZLOG_DISABLED); /* Library inits. */ cmd_init(1); diff --git a/tests/lib/test_checksum.c b/tests/lib/test_checksum.c index 13d35b0e99..ddb76c8f9d 100644 --- a/tests/lib/test_checksum.c +++ b/tests/lib/test_checksum.c @@ -23,6 +23,7 @@ #include <time.h> #include "checksum.h" +#include "network.h" struct thread_master *master; @@ -477,7 +478,7 @@ int main(int argc, char **argv) exercise %= MAXDATALEN; for (i = 0; i < exercise; i += sizeof(long int)) { - long int rand = random(); + long int rand = frr_weak_random(); for (j = sizeof(long int); j > 0; j--) buffer[i + (sizeof(long int) - j)] = diff --git a/tests/lib/test_segv.c b/tests/lib/test_segv.c index 43ca0837d5..8133637adc 100644 --- a/tests/lib/test_segv.c +++ b/tests/lib/test_segv.c @@ -73,11 +73,7 @@ int main(void) master = thread_master_create(NULL); signal_init(master, array_size(sigs), sigs); - openzlog("testsegv", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_DAEMON); - zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED); - zlog_set_level(ZLOG_DEST_STDOUT, LOG_DEBUG); - zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); + zlog_aux_init("NONE: ", LOG_DEBUG); thread_execute(master, threadfunc, 0, 0); diff --git a/tests/lib/test_sig.c b/tests/lib/test_sig.c index cf63a3d047..2aceafb8f0 100644 --- a/tests/lib/test_sig.c +++ b/tests/lib/test_sig.c @@ -57,11 +57,7 @@ int main(void) master = thread_master_create(NULL); signal_init(master, array_size(sigs), sigs); - openzlog("testsig", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_DAEMON); - zlog_set_level(ZLOG_DEST_SYSLOG, ZLOG_DISABLED); - zlog_set_level(ZLOG_DEST_STDOUT, LOG_DEBUG); - zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); + zlog_aux_init("NONE: ", LOG_DEBUG); while (thread_fetch(master, &t)) thread_call(&t); diff --git a/tests/lib/test_zlog.c b/tests/lib/test_zlog.c index 07885d9847..48fa7bce94 100644 --- a/tests/lib/test_zlog.c +++ b/tests/lib/test_zlog.c @@ -20,6 +20,7 @@ #include <zebra.h> #include <memory.h> #include "log.h" +#include "network.h" /* maximum amount of data to hexdump */ #define MAXDATA 16384 @@ -37,7 +38,7 @@ static bool test_zlog_hexdump(void) uint8_t d[nl]; for (unsigned int i = 0; i < nl; i++) - d[i] = random(); + d[i] = frr_weak_random(); zlog_hexdump(d, nl - 1); nl += 1 + (nl / 2); @@ -52,9 +53,7 @@ bool (*tests[])(void) = { int main(int argc, char **argv) { - openzlog("testzlog", "NONE", 0, LOG_CONS | LOG_NDELAY | LOG_PID, - LOG_ERR); - zlog_set_file("test_zlog.log", LOG_DEBUG); + zlog_aux_init("NONE: ", ZLOG_DISABLED); for (unsigned int i = 0; i < array_size(tests); i++) if (!tests[i]()) diff --git a/tests/lib/test_zmq.c b/tests/lib/test_zmq.c index b6624915e8..fe330d98d4 100644 --- a/tests/lib/test_zmq.c +++ b/tests/lib/test_zmq.c @@ -120,7 +120,7 @@ static void run_client(int syncfd) /* write callback */ printf("---\n"); - snprintf(buf, 32, "Done receiving"); + snprintf(buf, sizeof(buf), "Done receiving"); printf("client send: %s\n", buf); fflush(stdout); send_delim(zmqsock); diff --git a/tests/subdir.am b/tests/subdir.am index 5efdcbbd4c..04053a6f46 100644 --- a/tests/subdir.am +++ b/tests/subdir.am @@ -38,13 +38,10 @@ else TESTS_OSPF6D = endif -tests/lib/cli/test_cli_clippy.c: $(CLIPPY_DEPS) -tests/lib/cli/tests_lib_cli_test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c -tests/lib/cli/test_cli-test_cli.$(OBJEXT): tests/lib/cli/test_cli_clippy.c - -tests/ospf6d/test_lsdb_clippy.c: $(CLIPPY_DEPS) -tests/ospf6d/tests_ospf6d_test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c -tests/ospf6d/test_lsdb-test_lsdb.$(OBJEXT): tests/ospf6d/test_lsdb_clippy.c +clippy_scan += \ + tests/lib/cli/test_cli.c \ + tests/ospf6d/test_lsdb.c \ + # end check_PROGRAMS = \ tests/lib/cxxcompat \ diff --git a/tests/topotests/all-protocol-startup/r1/bgpd.conf b/tests/topotests/all-protocol-startup/r1/bgpd.conf index 34cbd086dd..7a7bba7ae7 100644 --- a/tests/topotests/all-protocol-startup/r1/bgpd.conf +++ b/tests/topotests/all-protocol-startup/r1/bgpd.conf @@ -4,6 +4,7 @@ log file bgpd.log router bgp 100 bgp router-id 192.168.0.1 bgp log-neighbor-changes + no bgp ebgp-requires-policy neighbor 192.168.7.10 remote-as 100 neighbor 192.168.7.20 remote-as 200 neighbor fc00:0:0:8::1000 remote-as 100 diff --git a/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref b/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref index 993b4df6a2..044cffae7a 100644 --- a/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref +++ b/tests/topotests/all-protocol-startup/r1/ipv4_routes.ref @@ -10,8 +10,14 @@ C>* 192.168.8.0/26 is directly connected, r1-eth8, XX:XX:XX C>* 192.168.9.0/26 is directly connected, r1-eth9, XX:XX:XX O 192.168.0.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX O 192.168.3.0/26 [110/10] is directly connected, r1-eth3, weight 1, XX:XX:XX -S>* 1.1.1.1/32 [1/0] is directly connected, r1-eth0, weight 1, XX:XX:XX -S>* 1.1.1.2/32 [1/0] is directly connected, r1-eth1, weight 1, XX:XX:XX +S>* 1.1.1.1/32 [1/0] is directly connected, r1-eth1, weight 1, XX:XX:XX +S>* 1.1.1.2/32 [1/0] is directly connected, r1-eth2, weight 1, XX:XX:XX +S>* 1.1.1.3/32 [1/0] is directly connected, r1-eth3, weight 1, XX:XX:XX +S>* 1.1.1.4/32 [1/0] is directly connected, r1-eth4, weight 1, XX:XX:XX +S>* 1.1.1.5/32 [1/0] is directly connected, r1-eth5, weight 1, XX:XX:XX +S>* 1.1.1.6/32 [1/0] is directly connected, r1-eth6, weight 1, XX:XX:XX +S>* 1.1.1.7/32 [1/0] is directly connected, r1-eth7, weight 1, XX:XX:XX +S>* 1.1.1.8/32 [1/0] is directly connected, r1-eth8, weight 1, XX:XX:XX S>* 4.5.6.10/32 [1/0] via 192.168.0.2, r1-eth0, weight 1, XX:XX:XX S>* 4.5.6.11/32 [1/0] via 192.168.0.2, r1-eth0, weight 1, XX:XX:XX S>* 4.5.6.12/32 [1/0] is directly connected, r1-eth0, weight 1, XX:XX:XX diff --git a/tests/topotests/all-protocol-startup/r1/zebra.conf b/tests/topotests/all-protocol-startup/r1/zebra.conf index 858a8a585d..c5ef79630e 100644 --- a/tests/topotests/all-protocol-startup/r1/zebra.conf +++ b/tests/topotests/all-protocol-startup/r1/zebra.conf @@ -27,8 +27,14 @@ ipv6 route 4:5::6:12/128 r1-eth0 ip route 4.5.6.15/32 192.168.0.2 255 ipv6 route 4:5::6:15/128 fc00:0:0:0::2 255 # Routes to put into a nexthop-group -ip route 1.1.1.1/32 r1-eth0 -ip route 1.1.1.2/32 r1-eth1 +ip route 1.1.1.1/32 r1-eth1 +ip route 1.1.1.2/32 r1-eth2 +ip route 1.1.1.3/32 r1-eth3 +ip route 1.1.1.4/32 r1-eth4 +ip route 1.1.1.5/32 r1-eth5 +ip route 1.1.1.6/32 r1-eth6 +ip route 1.1.1.7/32 r1-eth7 +ip route 1.1.1.8/32 r1-eth8 # Create a route that has overlapping distance # so we have backups diff --git a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py index 5f23525a1b..f78c2b4bc0 100755 --- a/tests/topotests/all-protocol-startup/test_all_protocol_startup.py +++ b/tests/topotests/all-protocol-startup/test_all_protocol_startup.py @@ -347,6 +347,35 @@ def test_converge_protocols(): # For debugging after starting FRR/Quagga daemons, uncomment the next line ## CLI(net) +def route_get_nhg_id(route_str): + output = net["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str) + match = re.search(r"Nexthop Group ID: (\d+)", output) + assert match is not None, "Nexthop Group ID not found for sharpd route %s" % route_str + + nhg_id = int(match.group(1)) + return nhg_id + +def verify_nexthop_group(nhg_id, recursive=False): + # Verify NHG is valid/installed + output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id) + + match = re.search(r"Valid", output) + assert match is not None, "Nexthop Group ID=%d not marked Valid" % nhg_id + + # If recursive, we need to look at its resolved group + if recursive: + match = re.search(r"Depends: \((\d+)\)", output) + resolved_id = int(match.group(1)) + verify_nexthop_group(resolved_id, False) + else: + match = re.search(r"Installed", output) + assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhg_id + +def verify_route_nexthop_group(route_str, recursive=False): + # Verify route and that zebra created NHGs for and they are valid/installed + nhg_id = route_get_nhg_id(route_str) + verify_nexthop_group(nhg_id, recursive) + def test_nexthop_groups(): global fatal_error global net @@ -358,25 +387,77 @@ def test_nexthop_groups(): print("\n\n** Verifying Nexthop Groups") print("******************************************\n") + ### Nexthop Group Tests + + ## Basic test + # Create a lib nexthop-group - net["r1"].cmd('vtysh -c "c t" -c "nexthop-group red" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"') + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"') # Create with sharpd using nexthop-group - net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group red 1"') + net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group basic 1"') - # Verify route and that zebra created NHGs for and they are valid/installed - output = net["r1"].cmd('vtysh -c "show ip route 2.2.2.1/32 nexthop-group"') - match = re.search(r"Nexthop Group ID: (\d+)", output); - assert match is not None, "Nexthop Group ID not found for sharpd route 2.2.2.1/32" + verify_route_nexthop_group("2.2.2.1/32") - nhe_id = int(match.group(1)) + ## Connected - output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhe_id) - match = re.search(r"Valid", output) - assert match is not None, "Nexthop Group ID=%d not marked Valid" % nhe_id + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"') - match = re.search(r"Installed", output) - assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhe_id + net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.2 nexthop-group connected 1"') + + verify_route_nexthop_group("2.2.2.2/32") + + ## Recursive + + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"') + + net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"') + + verify_route_nexthop_group("3.3.3.1/32", True) + + ## Duplicate + + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"') + + net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.2 nexthop-group duplicate 1"') + + verify_route_nexthop_group("3.3.3.2/32") + + ## Two 4-Way ECMP + + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \ + -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"') + + net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.1 nexthop-group fourA 1"') + + verify_route_nexthop_group("4.4.4.1/32") + + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \ + -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"') + + net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.2 nexthop-group fourB 1"') + + verify_route_nexthop_group("4.4.4.2/32") + + ## Recursive to 8-Way ECMP + + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"') + + net["r1"].cmd('vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"') + + verify_route_nexthop_group("5.5.5.1/32") + + ##CLI(net) + + ## Remove all NHG routes + + net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.1 1"') + net["r1"].cmd('vtysh -c "sharp remove routes 2.2.2.2 1"') + net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.1 1"') + net["r1"].cmd('vtysh -c "sharp remove routes 3.3.3.2 1"') + net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.1 1"') + net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.2 1"') + net["r1"].cmd('vtysh -c "sharp remove routes 5.5.5.1 1"') def test_rip_status(): global fatal_error @@ -924,6 +1005,82 @@ def test_route_map(): assert failures == 0, "Show route-map command failed for router r%s:\n%s" % (i, diff) +def test_nexthop_groups_with_route_maps(): + global fatal_error + global net + + # Skip if previous fatal error condition is raised + if (fatal_error != ""): + pytest.skip(fatal_error) + + print("\n\n** Verifying Nexthop Groups With Route-Maps") + print("******************************************\n") + + ### Nexthop Group With Route-Map Tests + + # Create a lib nexthop-group + net["r1"].cmd('vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"') + + ## Route-Map Proto Source + + route_str = "2.2.2.1" + src_str = "192.168.0.1" + + net["r1"].cmd('vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str) + net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NH-SRC"') + + net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % route_str) + + verify_route_nexthop_group("%s/32" % route_str) + + # Only a valid test on linux using nexthop objects + if sys.platform.startswith("linux"): + output = net["r1"].cmd('ip route show %s/32' % route_str) + match = re.search(r"src %s" % src_str, output) + assert match is not None, "Route %s/32 not installed with src %s" % (route_str, src_str) + + # Remove NHG routes and route-map + net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % route_str) + net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NH-SRC"') + net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str) + net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"') + + ## Route-Map Deny/Permit with same nexthop group + + permit_route_str = "3.3.3.1" + deny_route_str = "3.3.3.2" + + net["r1"].cmd('vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str) + net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"') + net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE deny 222"') + net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NOPE"') + + # This route should be permitted + net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str) + + verify_route_nexthop_group("%s/32" % permit_route_str) + + # This route should be denied + net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str) + + nhg_id = route_get_nhg_id(deny_route_str) + output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id) + + match = re.search(r"Valid", output) + assert match is None, "Nexthop Group ID=%d should not be marked Valid" % nhg_id + + match = re.search(r"Installed", output) + assert match is None, "Nexthop Group ID=%d should not be marked Installed" % nhg_id + + # Remove NHG routes and route-map + net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % permit_route_str) + net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % deny_route_str) + net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NOPE"') + net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE permit 111"') + net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE deny 222"') + net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE"') + net["r1"].cmd('vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str) + def test_mpls_interfaces(): global fatal_error global net diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf index fa6d60a8fc..f69b3c4ba3 100644 --- a/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf +++ b/tests/topotests/bfd-bgp-cbit-topo3/r1/bgpd.conf @@ -1,6 +1,7 @@ debug bgp neighbor-events router bgp 101 bgp router-id 10.254.254.1 + no bgp ebgp-requires-policy timers bgp 8 24 bgp graceful-restart neighbor 2001:db8:4::1 remote-as 102 @@ -14,7 +15,7 @@ router bgp 101 exit-address-family address-family ipv6 unicast network 2001:db8:8::/64 - network 2001:db8:9::/64 + network 2001:db8:9::/64 neighbor 2001:db8:4::1 activate exit-address-family ! diff --git a/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf index ea5334029c..51b611b2a7 100644 --- a/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf +++ b/tests/topotests/bfd-bgp-cbit-topo3/r3/bgpd.conf @@ -1,6 +1,7 @@ debug bgp neighbor-events router bgp 102 bgp router-id 10.254.254.3 + no bgp ebgp-requires-policy timers bgp 20 60 bgp graceful-restart ! simulate NSF machine diff --git a/tests/topotests/bfd-topo1/r1/bgpd.conf b/tests/topotests/bfd-topo1/r1/bgpd.conf index 78a5611844..87f20d29e9 100644 --- a/tests/topotests/bfd-topo1/r1/bgpd.conf +++ b/tests/topotests/bfd-topo1/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 101 + no bgp ebgp-requires-policy neighbor 192.168.0.2 remote-as 102 neighbor 192.168.0.2 bfd address-family ipv4 unicast diff --git a/tests/topotests/bfd-topo1/r2/bgpd.conf b/tests/topotests/bfd-topo1/r2/bgpd.conf index af10cfaf40..f87e12f0a7 100644 --- a/tests/topotests/bfd-topo1/r2/bgpd.conf +++ b/tests/topotests/bfd-topo1/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 102 + no bgp ebgp-requires-policy neighbor 192.168.0.1 remote-as 101 neighbor 192.168.0.1 bfd neighbor 192.168.1.1 remote-as 103 diff --git a/tests/topotests/bfd-topo1/r3/bgpd.conf b/tests/topotests/bfd-topo1/r3/bgpd.conf index 041fd7a759..0340e067f1 100644 --- a/tests/topotests/bfd-topo1/r3/bgpd.conf +++ b/tests/topotests/bfd-topo1/r3/bgpd.conf @@ -1,4 +1,5 @@ router bgp 103 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 102 neighbor 192.168.1.2 bfd address-family ipv4 unicast diff --git a/tests/topotests/bfd-topo1/r4/bgpd.conf b/tests/topotests/bfd-topo1/r4/bgpd.conf index 9c504699ba..980d927e97 100644 --- a/tests/topotests/bfd-topo1/r4/bgpd.conf +++ b/tests/topotests/bfd-topo1/r4/bgpd.conf @@ -1,4 +1,5 @@ router bgp 104 + no bgp ebgp-requires-policy neighbor 192.168.2.2 remote-as 102 neighbor 192.168.2.2 bfd address-family ipv4 unicast diff --git a/tests/topotests/bfd-topo2/r1/bgpd.conf b/tests/topotests/bfd-topo2/r1/bgpd.conf index 1623b4578b..4d96bec2cb 100644 --- a/tests/topotests/bfd-topo2/r1/bgpd.conf +++ b/tests/topotests/bfd-topo2/r1/bgpd.conf @@ -1,5 +1,6 @@ router bgp 101 bgp router-id 10.254.254.1 + no bgp ebgp-requires-policy neighbor r2g peer-group neighbor r2g remote-as external neighbor r2g bfd diff --git a/tests/topotests/bfd-topo2/r2/bgpd.conf b/tests/topotests/bfd-topo2/r2/bgpd.conf index bf42d21812..4d02fc4f29 100644 --- a/tests/topotests/bfd-topo2/r2/bgpd.conf +++ b/tests/topotests/bfd-topo2/r2/bgpd.conf @@ -1,5 +1,6 @@ router bgp 102 bgp router-id 10.254.254.2 + no bgp ebgp-requires-policy neighbor r2g peer-group neighbor r2g remote-as external neighbor r2g bfd diff --git a/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf index 7ad4e2bd74..136e53a43f 100644 --- a/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf +++ b/tests/topotests/bfd-vrf-topo1/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 101 vrf r1-cust1 + no bgp ebgp-requires-policy neighbor 192.168.0.2 remote-as 102 ! neighbor 192.168.0.2 ebgp-multihop 10 neighbor 192.168.0.2 bfd diff --git a/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf index 0715ea32a5..2bd13e22b2 100644 --- a/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf +++ b/tests/topotests/bfd-vrf-topo1/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 102 vrf r2-cust1 + no bgp ebgp-requires-policy neighbor 192.168.0.1 remote-as 101 neighbor 192.168.0.1 bfd neighbor 192.168.1.1 remote-as 103 diff --git a/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf index 277f027d5b..c0cd45f7fe 100644 --- a/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf +++ b/tests/topotests/bfd-vrf-topo1/r3/bgpd.conf @@ -1,4 +1,5 @@ router bgp 103 vrf r3-cust1 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 102 neighbor 192.168.1.2 bfd address-family ipv4 unicast diff --git a/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf b/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf index 66bf28587d..fe1185768d 100644 --- a/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf +++ b/tests/topotests/bfd-vrf-topo1/r4/bgpd.conf @@ -1,4 +1,5 @@ router bgp 104 vrf r4-cust1 + no bgp ebgp-requires-policy neighbor 192.168.2.2 remote-as 102 neighbor 192.168.2.2 bfd address-family ipv4 unicast diff --git a/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf b/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf index 627dc76c1b..d3beb2d320 100644 --- a/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf +++ b/tests/topotests/bgp-ecmp-topo1/r1/bgpd.conf @@ -5,6 +5,7 @@ log file bgpd.log router bgp 100 bgp router-id 10.0.255.1 bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy neighbor 10.0.1.101 remote-as 99 neighbor 10.0.1.102 remote-as 99 neighbor 10.0.1.103 remote-as 99 diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf b/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf index 720b83e485..d337201f71 100644 --- a/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf +++ b/tests/topotests/bgp-evpn-vxlan_topo1/PE1/bgpd.conf @@ -1,10 +1,9 @@ router bgp 65000 + timers 3 9 bgp router-id 10.10.10.10 no bgp default ipv4-unicast neighbor 10.30.30.30 remote-as 65000 - neighbor 10.30.30.30 ebgp-multihop 2 neighbor 10.30.30.30 update-source lo - neighbor 10.30.30.30 capability extended-nexthop address-family l2vpn evpn neighbor 10.30.30.30 activate advertise-all-vni diff --git a/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf b/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf index 7739795367..d99e33fc06 100644 --- a/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf +++ b/tests/topotests/bgp-evpn-vxlan_topo1/PE2/bgpd.conf @@ -1,10 +1,9 @@ router bgp 65000 + timers bgp 3 9 bgp router-id 10.30.30.30 no bgp default ipv4-unicast neighbor 10.10.10.10 remote-as 65000 - neighbor 10.10.10.10 ebgp-multihop 2 neighbor 10.10.10.10 update-source lo - neighbor 10.10.10.10 capability extended-nexthop ! address-family l2vpn evpn neighbor 10.10.10.10 activate diff --git a/tests/topotests/bgp-vrf-route-leak-basic/r1/bgpd.conf b/tests/topotests/bgp-vrf-route-leak-basic/r1/bgpd.conf index 626c268392..03dfbf9322 100644 --- a/tests/topotests/bgp-vrf-route-leak-basic/r1/bgpd.conf +++ b/tests/topotests/bgp-vrf-route-leak-basic/r1/bgpd.conf @@ -1,14 +1,16 @@ hostname r1 router bgp 99 vrf DONNA + no bgp ebgp-requires-policy address-family ipv4 unicast redistribute connected import vrf EVA ! ! router bgp 99 vrf EVA + no bgp ebgp-requires-policy address-family ipv4 unicast redistribute connected import vrf DONNA ! -!
\ No newline at end of file +! diff --git a/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf b/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf index 528d02af36..9d519fae88 100644 --- a/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf +++ b/tests/topotests/bgp_aggregate-address_origin/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf b/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf index 73d4d0aeea..38cf5aaca7 100644 --- a/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf +++ b/tests/topotests/bgp_aggregate-address_origin/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 exit-address-family ! diff --git a/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf b/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf index ef34817bb1..292f0e967f 100644 --- a/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf +++ b/tests/topotests/bgp_aggregate-address_route-map/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf b/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf index 73d4d0aeea..38cf5aaca7 100644 --- a/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf +++ b/tests/topotests/bgp_aggregate-address_route-map/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 exit-address-family ! diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf b/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf index fc273ba7c6..75741a3c3e 100644 --- a/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf +++ b/tests/topotests/bgp_as_wide_bgp_identifier/r1/bgpd.conf @@ -1,5 +1,6 @@ ! exit1 router bgp 65001 bgp router-id 10.10.10.10 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65002 ! diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf b/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf index 1134d98b38..18a6c66f69 100644 --- a/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf +++ b/tests/topotests/bgp_as_wide_bgp_identifier/r2/bgpd.conf @@ -1,6 +1,7 @@ ! spine router bgp 65002 bgp router-id 10.10.10.10 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 neighbor 192.168.255.3 remote-as 65002 ! diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf b/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf index fa943d10c3..27bf126000 100644 --- a/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf +++ b/tests/topotests/bgp_as_wide_bgp_identifier/r3/bgpd.conf @@ -1,5 +1,6 @@ ! exit2 router bgp 65002 bgp router-id 10.10.10.10 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65002 ! diff --git a/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf b/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf index 6e1273f464..9518894351 100644 --- a/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf +++ b/tests/topotests/bgp_comm-list_delete/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 address-family ipv4 unicast redistribute connected route-map r2-out diff --git a/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf b/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf index 3d354d56b1..e4c1167745 100644 --- a/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf +++ b/tests/topotests/bgp_comm-list_delete/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 address-family ipv4 neighbor 192.168.255.1 route-map r1-in in diff --git a/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf index a9925ab661..12e56e27c4 100644 --- a/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf +++ b/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 address-family ipv4 unicast neighbor 192.168.255.2 default-originate route-map default diff --git a/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf index a8a6c49f4d..b6b560aa4d 100644 --- a/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf +++ b/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_distance_change/r1/bgpd.conf b/tests/topotests/bgp_distance_change/r1/bgpd.conf index 67994702bc..cd2ef675fc 100644 --- a/tests/topotests/bgp_distance_change/r1/bgpd.conf +++ b/tests/topotests/bgp_distance_change/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 exit-address-family ! diff --git a/tests/topotests/bgp_distance_change/r2/bgpd.conf b/tests/topotests/bgp_distance_change/r2/bgpd.conf index 206f626da4..0faec85032 100644 --- a/tests/topotests/bgp_distance_change/r2/bgpd.conf +++ b/tests/topotests/bgp_distance_change/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 address-family ipv4 redistribute connected diff --git a/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf index e06fa08b57..aaa01ebcf9 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf +++ b/tests/topotests/bgp_ebgp_requires_policy/r1/bgpd.conf @@ -1,5 +1,4 @@ router bgp 65000 - bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 1000 neighbor 192.168.255.2 local-as 500 address-family ipv4 unicast diff --git a/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf index 0549697ff0..27427a9aaa 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf +++ b/tests/topotests/bgp_ebgp_requires_policy/r2/bgpd.conf @@ -1,2 +1,3 @@ router bgp 1000 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 500 diff --git a/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf index b4e304d82a..2deb4b663d 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf +++ b/tests/topotests/bgp_ebgp_requires_policy/r3/bgpd.conf @@ -1,5 +1,4 @@ router bgp 65000 - bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 1000 neighbor 192.168.255.2 local-as 500 address-family ipv4 unicast diff --git a/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf index 0549697ff0..27427a9aaa 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf +++ b/tests/topotests/bgp_ebgp_requires_policy/r4/bgpd.conf @@ -1,2 +1,3 @@ router bgp 1000 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 500 diff --git a/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf index 99e6b6818d..92a2797921 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf +++ b/tests/topotests/bgp_ebgp_requires_policy/r5/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65000 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf index 164f975cb7..342f53d4c7 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf +++ b/tests/topotests/bgp_ebgp_requires_policy/r6/bgpd.conf @@ -1,3 +1,2 @@ router bgp 65000 - bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 diff --git a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py index bdacff3a9c..18e36311ad 100644 --- a/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py +++ b/tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py @@ -27,6 +27,16 @@ bgp_ebgp_requires_policy.py: Test if eBGP sender without a filter applied to the peer is allowed to send advertisements. + +Scenario 1: + r1 has a filter applied for outgoing direction, + r2 receives 192.168.255.1/32. +Scenario 2: + r3 hasn't a filter appied for outgoing direction, + r4 does not receive 192.168.255.1/32. +Scenario 3: + r5 and r6 establish iBGP session which in turn should ignore + RFC8212. All routes for both directions MUST work. """ import os @@ -112,27 +122,27 @@ def test_ebgp_requires_policy(): test_func = functools.partial(_bgp_converge, "r2") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(router) + assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(tgen.gears["r2"]) test_func = functools.partial(_bgp_has_routes, "r2") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(router) + assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(tgen.gears["r2"]) test_func = functools.partial(_bgp_converge, "r4") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(router) + assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(tgen.gears["r4"]) test_func = functools.partial(_bgp_has_routes, "r4") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(router) + assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(tgen.gears["r4"]) test_func = functools.partial(_bgp_converge, "r6") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(router) + assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(tgen.gears["r6"]) test_func = functools.partial(_bgp_has_routes, "r6") success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert success is True, 'eBGP policy is not working (r6) in "{}"'.format(router) + assert success is True, 'eBGP policy is not working (r6) in "{}"'.format(tgen.gears["r6"]) if __name__ == "__main__": diff --git a/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf b/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf index 1623b4578b..4d96bec2cb 100644 --- a/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf +++ b/tests/topotests/bgp_ipv6_rtadv/r1/bgpd.conf @@ -1,5 +1,6 @@ router bgp 101 bgp router-id 10.254.254.1 + no bgp ebgp-requires-policy neighbor r2g peer-group neighbor r2g remote-as external neighbor r2g bfd diff --git a/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf b/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf index bf42d21812..4d02fc4f29 100644 --- a/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf +++ b/tests/topotests/bgp_ipv6_rtadv/r2/bgpd.conf @@ -1,5 +1,6 @@ router bgp 102 bgp router-id 10.254.254.2 + no bgp ebgp-requires-policy neighbor r2g peer-group neighbor r2g remote-as external neighbor r2g bfd diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf index bd10248d7b..4ce87f773b 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce1/bgpd.conf @@ -7,6 +7,7 @@ log monitor notifications log commands router bgp 5226 bgp router-id 99.0.0.1 + no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as 5226 neighbor 192.168.1.1 update-source 192.168.1.2 address-family ipv4 unicast @@ -28,6 +29,3 @@ route-map rm-nh permit 10 ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf index ab86c5e1b8..0d5ec148b1 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce2/bgpd.conf @@ -7,6 +7,7 @@ log monitor notifications log commands router bgp 5226 bgp router-id 99.0.0.2 + no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as 5226 neighbor 192.168.1.1 update-source 192.168.1.2 address-family ipv4 unicast @@ -28,6 +29,3 @@ route-map rm-nh permit 10 ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf index 7d239b0bd5..d58b9b1c90 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/ce3/bgpd.conf @@ -7,6 +7,7 @@ log monitor notifications log commands router bgp 5226 bgp router-id 99.0.0.3 + no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as 5226 neighbor 192.168.1.1 update-source 192.168.1.2 address-family ipv4 unicast @@ -28,6 +29,3 @@ route-map rm-nh permit 10 ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf index 7ec941ee6b..33041262f6 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 1.1.1.1 bgp cluster-id 1.1.1.1 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 5226 neighbor 192.168.1.2 update-source 192.168.1.1 neighbor 192.168.1.2 route-reflector-client diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf index 241c2ac0ae..524051426b 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 2.2.2.2 bgp cluster-id 2.2.2.2 + no bgp ebgp-requires-policy neighbor 1.1.1.1 remote-as 5226 neighbor 1.1.1.1 update-source 2.2.2.2 neighbor 3.3.3.3 remote-as 5226 @@ -28,6 +29,3 @@ router bgp 5226 neighbor 4.4.4.4 route-reflector-client exit-address-family end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf index 5591c633c6..29b9f0da6c 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/bgpd.conf @@ -8,8 +8,9 @@ log commands router bgp 5226 bgp router-id 3.3.3.3 bgp cluster-id 3.3.3.3 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 5226 - neighbor 192.168.1.2 update-source 192.168.1.2 + neighbor 192.168.1.2 update-source 192.168.1.2 neighbor 192.168.1.2 route-reflector-client neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 3.3.3.3 @@ -37,6 +38,3 @@ router bgp 5226 vnc redistribute ipv4 bgp-direct ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf index 145390d724..e09b505ee4 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 4.4.4.4 bgp cluster-id 4.4.4.4 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 5226 neighbor 192.168.1.2 update-source 192.168.1.1 neighbor 192.168.1.2 route-reflector-client @@ -37,6 +38,3 @@ router bgp 5226 vnc redistribute ipv4 bgp-direct ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf index a38fb1e9a1..3786350996 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf @@ -9,6 +9,7 @@ log file bgpd.log router bgp 5227 bgp router-id 99.0.0.1 + no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as 5227 neighbor 192.168.1.1 update-source 192.168.1.2 address-family ipv4 unicast @@ -41,6 +42,3 @@ route-map sharp-nh permit 10 ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf index 3aeb9f9c9f..ffe2d54f58 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf @@ -9,6 +9,7 @@ log file bgpd.log router bgp 5227 bgp router-id 99.0.0.2 + no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as 5227 neighbor 192.168.1.1 update-source 192.168.1.2 address-family ipv4 unicast @@ -41,6 +42,3 @@ route-map sharp-nh permit 10 ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf index a65b36f364..31a00b8f73 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf @@ -9,6 +9,7 @@ log file bgpd.log router bgp 5227 bgp router-id 99.0.0.3 + no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as 5227 neighbor 192.168.1.1 update-source 192.168.1.2 address-family ipv4 unicast @@ -31,6 +32,3 @@ route-map rm-nh permit 10 ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf index cb08db5314..f57f96bec4 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf @@ -9,6 +9,7 @@ log file bgpd.log router bgp 5228 vrf ce4-cust2 bgp router-id 99.0.0.4 + no bgp ebgp-requires-policy neighbor 192.168.2.1 remote-as 5228 neighbor 192.168.2.1 update-source 192.168.2.2 address-family ipv4 unicast @@ -31,6 +32,3 @@ route-map rm-nh permit 10 ! end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf index c1bad0b7c6..a9549e8fee 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf @@ -16,6 +16,7 @@ log file bgpd.log debugging router bgp 5226 bgp router-id 1.1.1.1 bgp cluster-id 1.1.1.1 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 1.1.1.1 @@ -31,6 +32,7 @@ router bgp 5226 router bgp 5227 vrf r1-cust1 bgp router-id 192.168.1.1 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 5227 neighbor 192.168.1.2 update-source 192.168.1.1 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf index 4ccb0ca5c0..cda6d9429a 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r2/bgpd.conf @@ -10,6 +10,7 @@ log file bgpd.log debugging router bgp 5226 bgp router-id 2.2.2.2 bgp cluster-id 2.2.2.2 + no bgp ebgp-requires-policy neighbor 1.1.1.1 remote-as 5226 neighbor 1.1.1.1 update-source 2.2.2.2 neighbor 3.3.3.3 remote-as 5226 @@ -30,6 +31,3 @@ router bgp 5226 neighbor 4.4.4.4 route-reflector-client exit-address-family end - - - diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf index c4b6ac9bb4..e2a8de7db7 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r3/bgpd.conf @@ -11,6 +11,7 @@ log file bgpd.log router bgp 5226 bgp router-id 3.3.3.3 bgp cluster-id 3.3.3.3 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 3.3.3.3 @@ -25,9 +26,10 @@ router bgp 5226 router bgp 5227 vrf r3-cust1 bgp router-id 192.168.1.1 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 5227 - neighbor 192.168.1.2 update-source 192.168.1.1 + neighbor 192.168.1.2 update-source 192.168.1.1 address-family ipv4 unicast neighbor 192.168.1.2 activate diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf index 6295406e69..7b267a6ee1 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r4/bgpd.conf @@ -14,6 +14,7 @@ log file bgpd.log debug router bgp 5226 bgp router-id 4.4.4.4 bgp cluster-id 4.4.4.4 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 4.4.4.4 @@ -28,9 +29,10 @@ router bgp 5226 router bgp 5227 vrf r4-cust1 bgp router-id 192.168.1.1 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as 5227 - neighbor 192.168.1.2 update-source 192.168.1.1 + neighbor 192.168.1.2 update-source 192.168.1.1 address-family ipv4 unicast neighbor 192.168.1.2 activate @@ -47,6 +49,7 @@ router bgp 5227 vrf r4-cust1 router bgp 5228 vrf r4-cust2 bgp router-id 192.168.2.1 + no bgp ebgp-requires-policy neighbor 192.168.2.2 remote-as 5228 neighbor 192.168.2.2 update-source 192.168.2.1 diff --git a/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf index 595e244a21..40c19062a2 100644 --- a/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r1/bgpd.conf @@ -2,6 +2,7 @@ hostname r1 ! router bgp 65101 bgp router-id 11.1.1.1 + no bgp ebgp-requires-policy bgp bestpath as-path multipath-relax neighbor 11.1.1.2 remote-as external neighbor 11.1.1.6 remote-as external diff --git a/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf index 88a7bdce22..80588e7961 100644 --- a/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r10/bgpd.conf @@ -7,6 +7,7 @@ route-map redist permit 10 ! router bgp 65354 bgp router-id 11.1.6.2 + no bgp ebgp-requires-policy neighbor 11.1.6.1 remote-as external ! address-family ipv4 unicast diff --git a/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf index 2b6e9aeb6f..6fec1913c8 100644 --- a/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r2/bgpd.conf @@ -3,6 +3,7 @@ hostname r2 router bgp 65201 bgp router-id 11.1.2.1 bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy neighbor 11.1.1.1 remote-as external neighbor 11.1.2.2 remote-as external neighbor 11.1.2.6 remote-as external diff --git a/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf index 8b7c0c1792..1c2ca88306 100644 --- a/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r3/bgpd.conf @@ -3,6 +3,7 @@ hostname r3 router bgp 65202 bgp router-id 11.1.3.1 bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy neighbor 11.1.1.5 remote-as external neighbor 11.1.3.2 remote-as external ! diff --git a/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf index fa1f37843f..022a230643 100644 --- a/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r4/bgpd.conf @@ -18,6 +18,7 @@ route-map anycast_ip permit 20 router bgp 65301 bgp router-id 11.1.4.1 bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy neighbor 11.1.2.1 remote-as external neighbor 11.1.4.2 remote-as external neighbor 11.1.4.6 remote-as external diff --git a/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf index 8614f3e178..fc4e3888d8 100644 --- a/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r5/bgpd.conf @@ -11,6 +11,7 @@ route-map anycast_ip permit 20 router bgp 65302 bgp router-id 11.1.5.1 bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy neighbor 11.1.2.5 remote-as external neighbor 11.1.5.2 remote-as external ! diff --git a/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf index 3e5c6df6e1..f08f6337f4 100644 --- a/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r6/bgpd.conf @@ -11,6 +11,7 @@ route-map anycast_ip permit 20 router bgp 65303 bgp router-id 11.1.6.1 bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy neighbor 11.1.3.1 remote-as external neighbor 11.1.6.2 remote-as external ! diff --git a/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf index 7862023f55..98dfe2471a 100644 --- a/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r7/bgpd.conf @@ -7,6 +7,7 @@ route-map redist permit 10 ! router bgp 65351 bgp router-id 11.1.4.2 + no bgp ebgp-requires-policy neighbor 11.1.4.1 remote-as external ! address-family ipv4 unicast diff --git a/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf index 02110d9175..b4ba8e8a72 100644 --- a/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r8/bgpd.conf @@ -7,6 +7,7 @@ route-map redist permit 10 ! router bgp 65352 bgp router-id 11.1.4.6 + no bgp ebgp-requires-policy neighbor 11.1.4.5 remote-as external ! address-family ipv4 unicast diff --git a/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf b/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf index d64663fa16..31f971dd08 100644 --- a/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf +++ b/tests/topotests/bgp_link_bw_ip/r9/bgpd.conf @@ -7,6 +7,7 @@ route-map redist permit 10 ! router bgp 65353 bgp router-id 11.1.5.2 + no bgp ebgp-requires-policy neighbor 11.1.5.1 remote-as external ! address-family ipv4 unicast diff --git a/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf index e2f034453f..6f8fcd753d 100644 --- a/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf +++ b/tests/topotests/bgp_local_as_private_remove/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 1000 neighbor 192.168.255.2 local-as 500 address-family ipv4 unicast diff --git a/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf index 0549697ff0..27427a9aaa 100644 --- a/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf +++ b/tests/topotests/bgp_local_as_private_remove/r2/bgpd.conf @@ -1,2 +1,3 @@ router bgp 1000 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 500 diff --git a/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf index 4e57f71c48..f2050ddfdb 100644 --- a/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf +++ b/tests/topotests/bgp_local_as_private_remove/r3/bgpd.conf @@ -1,4 +1,5 @@ router bgp 3000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 1000 neighbor 192.168.255.2 local-as 500 address-family ipv4 unicast diff --git a/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf b/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf index 0549697ff0..27427a9aaa 100644 --- a/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf +++ b/tests/topotests/bgp_local_as_private_remove/r4/bgpd.conf @@ -1,2 +1,3 @@ router bgp 1000 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 500 diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf index 235b42b3d5..f0df56e947 100644 --- a/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf +++ b/tests/topotests/bgp_maximum_prefix_invalid_update/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf b/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf index e016284159..ef50dd0d7f 100644 --- a/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf +++ b/tests/topotests/bgp_maximum_prefix_invalid_update/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 address-family ipv4 neighbor 192.168.255.1 maximum-prefix 1 diff --git a/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf b/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf index 9a68809631..03e3eb6e08 100644 --- a/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf +++ b/tests/topotests/bgp_maximum_prefix_out/r1/bgpd.conf @@ -1,5 +1,6 @@ ! router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65002 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf b/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf index 1659c4bec4..2d47b2f661 100644 --- a/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf +++ b/tests/topotests/bgp_maximum_prefix_out/r2/bgpd.conf @@ -1,5 +1,6 @@ ! router bgp 65002 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 exit-address-family ! diff --git a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf index 71397a9942..5f65a54d7f 100644 --- a/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf +++ b/tests/topotests/bgp_multiview_topo1/r1/bgpd.conf @@ -13,6 +13,7 @@ log file bgpd.log ! router bgp 100 view 1 bgp router-id 172.30.1.1 + no bgp ebgp-requires-policy network 172.20.0.0/28 route-map local1 timers bgp 60 180 neighbor 172.16.1.1 remote-as 65001 @@ -21,6 +22,7 @@ router bgp 100 view 1 ! router bgp 100 view 2 bgp router-id 172.30.1.1 + no bgp ebgp-requires-policy network 172.20.0.0/28 route-map local2 timers bgp 60 180 neighbor 172.16.1.3 remote-as 65003 @@ -28,6 +30,7 @@ router bgp 100 view 2 ! router bgp 100 view 3 bgp router-id 172.30.1.1 + no bgp ebgp-requires-policy network 172.20.0.0/28 timers bgp 60 180 neighbor 172.16.1.6 remote-as 65006 diff --git a/tests/topotests/bgp_prefix_sid/r1/bgpd.conf b/tests/topotests/bgp_prefix_sid/r1/bgpd.conf index 7a38cc307f..2f8759f960 100644 --- a/tests/topotests/bgp_prefix_sid/r1/bgpd.conf +++ b/tests/topotests/bgp_prefix_sid/r1/bgpd.conf @@ -5,6 +5,7 @@ log commands router bgp 1 bgp router-id 10.0.0.1 no bgp default ipv4-unicast + no bgp ebgp-requires-policy neighbor 10.0.0.101 remote-as 2 neighbor 10.0.0.102 remote-as 3 ! diff --git a/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf index 7b24c4bbf9..94bfc5e561 100644 --- a/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf +++ b/tests/topotests/bgp_reject_as_sets/r1/bgpd.conf @@ -1,5 +1,6 @@ ! exit1 router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65002 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf index c991b5bcd8..f217b7f794 100644 --- a/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf +++ b/tests/topotests/bgp_reject_as_sets/r2/bgpd.conf @@ -1,6 +1,7 @@ ! spine router bgp 65002 bgp reject-as-sets + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 neighbor 192.168.254.2 remote-as 65003 address-family ipv4 unicast diff --git a/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf b/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf index bee518c84b..8d085a0e4b 100644 --- a/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf +++ b/tests/topotests/bgp_reject_as_sets/r3/bgpd.conf @@ -1,5 +1,6 @@ ! exit2 router bgp 65003 + no bgp ebgp-requires-policy neighbor 192.168.254.1 remote-as 65002 address-family ipv4 unicast neighbor 192.168.254.1 allowas-in diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf index 05eac758f1..b3fe5ff23d 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r1/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 1.1.1.1 bgp cluster-id 1.1.1.1 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 1.1.1.1 ! diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf index 241c2ac0ae..524051426b 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r2/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 2.2.2.2 bgp cluster-id 2.2.2.2 + no bgp ebgp-requires-policy neighbor 1.1.1.1 remote-as 5226 neighbor 1.1.1.1 update-source 2.2.2.2 neighbor 3.3.3.3 remote-as 5226 @@ -28,6 +29,3 @@ router bgp 5226 neighbor 4.4.4.4 route-reflector-client exit-address-family end - - - diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf index 67b26e3a50..fbb6a65d61 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 3.3.3.3 bgp cluster-id 3.3.3.3 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 3.3.3.3 ! @@ -45,6 +46,3 @@ router bgp 5226 exit-vnc ! end - - - diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf index 2ba5c74e5b..d61f776f3d 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity/r4/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 4.4.4.4 bgp cluster-id 4.4.4.4 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 4.4.4.4 ! @@ -46,6 +47,3 @@ router bgp 5226 exit-vnc ! end - - - diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf index f7f5e2ee96..626d8227e7 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r1/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 1.1.1.1 bgp cluster-id 1.1.1.1 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 1.1.1.1 ! diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf index 241c2ac0ae..524051426b 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r2/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 2.2.2.2 bgp cluster-id 2.2.2.2 + no bgp ebgp-requires-policy neighbor 1.1.1.1 remote-as 5226 neighbor 1.1.1.1 update-source 2.2.2.2 neighbor 3.3.3.3 remote-as 5226 @@ -28,6 +29,3 @@ router bgp 5226 neighbor 4.4.4.4 route-reflector-client exit-address-family end - - - diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf index 17e351988d..8c75a39efa 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 3.3.3.3 bgp cluster-id 3.3.3.3 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 3.3.3.3 ! @@ -46,6 +47,3 @@ router bgp 5226 exit-vnc ! end - - - diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf index 0b8808cb80..38f8758cbc 100644 --- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf +++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r4/bgpd.conf @@ -8,6 +8,7 @@ log commands router bgp 5226 bgp router-id 4.4.4.4 bgp cluster-id 4.4.4.4 + no bgp ebgp-requires-policy neighbor 2.2.2.2 remote-as 5226 neighbor 2.2.2.2 update-source 4.4.4.4 ! @@ -47,6 +48,3 @@ router bgp 5226 exit-vnc ! end - - - diff --git a/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf b/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf index 29a119c291..fa77cce073 100644 --- a/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf +++ b/tests/topotests/bgp_rr_ibgp/spine1/bgpd.conf @@ -1,5 +1,6 @@ hostname spine1 router bgp 99 + no bgp ebgp-requires-policy neighbor 192.168.2.1 remote-as internal neighbor 192.168.4.2 remote-as internal address-family ipv4 uni diff --git a/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf b/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf index e8ec0f7680..b028ab4e8b 100644 --- a/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf +++ b/tests/topotests/bgp_rr_ibgp/tor1/bgpd.conf @@ -1,4 +1,5 @@ hostname tor1 router bgp 99 + no bgp ebgp-requires-policy neighbor 192.168.2.3 remote-as internal redistribute connected diff --git a/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf b/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf index b091c97ac3..99c34158b9 100644 --- a/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf +++ b/tests/topotests/bgp_rr_ibgp/tor2/bgpd.conf @@ -1,4 +1,5 @@ hostname tor2 router bgp 99 + no bgp ebgp-requires-policy neighbor 192.168.4.3 remote-as internal redistribute connected diff --git a/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf b/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf index a91b564bff..b16e94d7c1 100644 --- a/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf +++ b/tests/topotests/bgp_sender-as-path-loop-detection/r1/bgpd.conf @@ -1,5 +1,6 @@ ! exit1 router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65002 address-family ipv4 unicast neighbor 192.168.255.1 route-map prepend out diff --git a/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf b/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf index 6e8e89360f..674877edd3 100644 --- a/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf +++ b/tests/topotests/bgp_sender-as-path-loop-detection/r2/bgpd.conf @@ -1,5 +1,6 @@ ! spine router bgp 65002 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 neighbor 192.168.255.2 solo neighbor 192.168.254.2 remote-as 65003 diff --git a/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf b/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf index 8962befad2..4ee7a39ab2 100644 --- a/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf +++ b/tests/topotests/bgp_sender-as-path-loop-detection/r3/bgpd.conf @@ -1,4 +1,5 @@ ! exit2 router bgp 65003 + no bgp ebgp-requires-policy neighbor 192.168.254.1 remote-as 65002 ! diff --git a/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf b/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf index 1a9c5325ad..7dab52fef0 100644 --- a/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf +++ b/tests/topotests/bgp_set_local-preference_add_subtract/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65000 neighbor 192.168.255.3 remote-as 65000 exit-address-family diff --git a/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf b/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf index 89e1256667..a8a0384632 100644 --- a/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf +++ b/tests/topotests/bgp_set_local-preference_add_subtract/r2/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 address-family ipv4 redistribute connected diff --git a/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf b/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf index fabd4605f3..2f5dceede2 100644 --- a/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf +++ b/tests/topotests/bgp_set_local-preference_add_subtract/r3/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.1 remote-as 65000 address-family ipv4 redistribute connected diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf index 235b42b3d5..f0df56e947 100644 --- a/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf +++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r1/bgpd.conf @@ -1,4 +1,5 @@ router bgp 65000 + no bgp ebgp-requires-policy neighbor 192.168.255.2 remote-as 65001 address-family ipv4 unicast redistribute connected diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf index c05bfd5a6b..422a7345f9 100644 --- a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf +++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/bgpd.conf @@ -1,5 +1,5 @@ router bgp 65001 + no bgp ebgp-requires-policy bgp default show-hostname neighbor 192.168.255.1 remote-as 65000 - address-family ipv4 unicast - redistribute connected + neighbor 192.168.254.1 remote-as 65001 diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf index 5abba71ce8..e9e2e4391f 100644 --- a/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf +++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r2/zebra.conf @@ -5,5 +5,8 @@ interface lo interface r2-eth0 ip address 192.168.255.2/24 ! +interface r2-eth1 + ip address 192.168.254.2/24 +! ip forwarding ! diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf new file mode 100644 index 0000000000..8fcf6a736d --- /dev/null +++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/bgpd.conf @@ -0,0 +1,3 @@ +router bgp 65001 + bgp default show-hostname + neighbor 192.168.254.2 remote-as 65001 diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf new file mode 100644 index 0000000000..a8b8bc38c5 --- /dev/null +++ b/tests/topotests/bgp_show_ip_bgp_fqdn/r3/zebra.conf @@ -0,0 +1,6 @@ +! +interface r3-eth0 + ip address 192.168.254.1/24 +! +ip forwarding +! diff --git a/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py b/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py index c41ae7cb2a..e8ad180935 100644 --- a/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py +++ b/tests/topotests/bgp_show_ip_bgp_fqdn/test_bgp_show_ip_bgp_fqdn.py @@ -26,6 +26,13 @@ test_bgp_show_ip_bgp_fqdn.py: Test if FQND is visible in `show [ip] bgp` output if `bgp default show-hostname` is toggled. + +Topology: +r1 <-- eBGP --> r2 <-- iBGP --> r3 + +1. Check if both hostname and ip are added to JSON output +for 172.16.255.254/32 on r2. +2. Check if only ip is added to JSON output for 172.16.255.254/32 on r3. """ import os @@ -49,13 +56,17 @@ class TemplateTopo(Topo): def build(self, *_args, **_opts): tgen = get_topogen(self) - for routern in range(1, 3): + for routern in range(1, 4): tgen.add_router("r{}".format(routern)) switch = tgen.add_switch("s1") switch.add_link(tgen.gears["r1"]) switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + def setup_module(mod): tgen = Topogen(TemplateTopo, mod.__name__) @@ -85,30 +96,36 @@ def test_bgp_show_ip_bgp_hostname(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - router = tgen.gears["r2"] - def _bgp_converge(router): - output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) - expected = { - "192.168.255.1": { - "bgpState": "Established", - "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, - } - } + output = json.loads(router.vtysh_cmd("show ip bgp 172.16.255.254/32 json")) + expected = {"prefix": "172.16.255.254/32"} return topotest.json_cmp(output, expected) def _bgp_show_nexthop_hostname_and_ip(router): output = json.loads(router.vtysh_cmd("show ip bgp json")) - for nh in output["routes"]["172.16.255.253/32"][0]["nexthops"]: + for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]: if "hostname" in nh and "ip" in nh: return True return False - test_func = functools.partial(_bgp_converge, router) + def _bgp_show_nexthop_ip_only(router): + output = json.loads(router.vtysh_cmd("show ip bgp json")) + for nh in output["routes"]["172.16.255.254/32"][0]["nexthops"]: + if "ip" in nh and not "hostname" in nh: + return True + return False + + test_func = functools.partial(_bgp_converge, tgen.gears["r2"]) success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert result is None, 'Failed bgp convergence in "{}"'.format(router) - assert _bgp_show_nexthop_hostname_and_ip(router) == True + test_func = functools.partial(_bgp_converge, tgen.gears["r3"]) + success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + + assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r2"]) + assert _bgp_show_nexthop_hostname_and_ip(tgen.gears["r2"]) == True + + assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r3"]) + assert _bgp_show_nexthop_ip_only(tgen.gears["r3"]) == True if __name__ == "__main__": diff --git a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf index 3c974c767f..002cecd1fa 100644 --- a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf +++ b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r1/bgpd.conf @@ -1,5 +1,6 @@ router bgp 101 vrf r1-cust1 bgp router-id 10.254.254.1 + no bgp ebgp-requires-policy neighbor r2g peer-group neighbor r2g remote-as external neighbor r2g bfd diff --git a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf index 39362abd46..0878b9b995 100644 --- a/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf +++ b/tests/topotests/bgp_vrf_lite_ipv6_rtadv/r2/bgpd.conf @@ -1,5 +1,6 @@ router bgp 102 vrf r2-cust1 bgp router-id 10.254.254.2 + no bgp ebgp-requires-policy neighbor r2g peer-group neighbor r2g remote-as external neighbor r2g bfd diff --git a/tests/topotests/bgp_vrf_netns/r1/bgpd.conf b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf index e3f158d7b3..dabf9521ac 100644 --- a/tests/topotests/bgp_vrf_netns/r1/bgpd.conf +++ b/tests/topotests/bgp_vrf_netns/r1/bgpd.conf @@ -2,6 +2,7 @@ router bgp 100 vrf r1-cust1 bgp router-id 10.0.1.1 bgp bestpath as-path multipath-relax + no bgp ebgp-requires-policy neighbor 10.0.1.101 remote-as 99 ! ! diff --git a/tests/topotests/evpn-pim-1/leaf1/bgpd.conf b/tests/topotests/evpn-pim-1/leaf1/bgpd.conf index 33d34db677..4dedfecd61 100644 --- a/tests/topotests/evpn-pim-1/leaf1/bgpd.conf +++ b/tests/topotests/evpn-pim-1/leaf1/bgpd.conf @@ -1,9 +1,10 @@ router bgp 65002 + no bgp ebgp-requires-policy neighbor 192.168.1.1 remote-as external redistribute connected address-family l2vpn evpn neighbor 192.168.1.1 activate advertise-all-vni ! -!
\ No newline at end of file +! diff --git a/tests/topotests/evpn-pim-1/leaf2/bgpd.conf b/tests/topotests/evpn-pim-1/leaf2/bgpd.conf index 3dd9f237be..5bc708240d 100644 --- a/tests/topotests/evpn-pim-1/leaf2/bgpd.conf +++ b/tests/topotests/evpn-pim-1/leaf2/bgpd.conf @@ -1,9 +1,10 @@ router bgp 65003 + no bgp ebgp-requires-policy neighbor 192.168.2.1 remote-as external redistribute connected address-family l2vpn evpn neighbor 192.168.2.1 activate advertise-all-vni ! -!
\ No newline at end of file +! diff --git a/tests/topotests/evpn-pim-1/spine/bgpd.conf b/tests/topotests/evpn-pim-1/spine/bgpd.conf index 9a845043e9..16c17b29cc 100644 --- a/tests/topotests/evpn-pim-1/spine/bgpd.conf +++ b/tests/topotests/evpn-pim-1/spine/bgpd.conf @@ -1,5 +1,6 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as external neighbor 192.168.2.3 remote-as external redistribute connected diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index b2cd2d284d..cafba60abf 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -209,6 +209,9 @@ def __create_bgp_global(tgen, input_dict, router, build=False): config_data.append(cmd) + # Skip RFC8212 in topotests + config_data.append("no bgp ebgp-requires-policy") + router_id = bgp_data.setdefault("router_id", None) del_router_id = bgp_data.setdefault("del_router_id", False) if del_router_id: diff --git a/tests/topotests/pim-basic/r1/bgpd.conf b/tests/topotests/pim-basic/r1/bgpd.conf index 8acaac96a0..1ca643f758 100644 --- a/tests/topotests/pim-basic/r1/bgpd.conf +++ b/tests/topotests/pim-basic/r1/bgpd.conf @@ -1,3 +1,4 @@ router bgp 65001 + no bgp ebgp-requires-policy neighbor 10.0.30.3 remote-as external redistribute connected diff --git a/tests/topotests/pim-basic/rp/bgpd.conf b/tests/topotests/pim-basic/rp/bgpd.conf index 6b16c067a5..451799288a 100644 --- a/tests/topotests/pim-basic/rp/bgpd.conf +++ b/tests/topotests/pim-basic/rp/bgpd.conf @@ -1,3 +1,4 @@ router bgp 65003 + no bgp ebgp-requires-policy neighbor 10.0.30.1 remote-as external redistribute connected diff --git a/tools/cocci.h b/tools/cocci.h index d25fcbbe23..8ca42b349f 100644 --- a/tools/cocci.h +++ b/tools/cocci.h @@ -27,3 +27,61 @@ struct type *le_next; /* next element */ \ struct type **le_prev; /* address of previous next element */ \ } + +#define STREAM_GETC(S, P) \ + do { \ + uint8_t _pval; \ + if (!stream_getc2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GETW(S, P) \ + do { \ + uint16_t _pval; \ + if (!stream_getw2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GETL(S, P) \ + do { \ + uint32_t _pval; \ + if (!stream_getl2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GETF(S, P) \ + do { \ + union { \ + float r; \ + uint32_t d; \ + } _pval; \ + if (stream_getl2((S), &_pval.d)) \ + goto stream_failure; \ + (P) = _pval.r; \ + } while (0) + +#define STREAM_GETQ(S, P) \ + do { \ + uint64_t _pval; \ + if (!stream_getq2((S), &_pval)) \ + goto stream_failure; \ + (P) = _pval; \ + } while (0) + +#define STREAM_GET(P, STR, SIZE) \ + do { \ + if (!stream_get2((P), (STR), (SIZE))) \ + goto stream_failure; \ + } while (0) + +#define AF_FOREACH(af) for ((af) = BGP_AF_START; (af) < BGP_AF_MAX; (af)++) + +#define FOREACH_AFI_SAFI(afi, safi) \ + \ + for (afi = AFI_IP; afi < AFI_MAX; afi++) \ + for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) + +#define FOREACH_SAFI(safi) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) diff --git a/tools/coccinelle/nb-cbs.cocci b/tools/coccinelle/nb-cbs.cocci new file mode 100644 index 0000000000..6e4d32ead4 --- /dev/null +++ b/tools/coccinelle/nb-cbs.cocci @@ -0,0 +1,298 @@ +@@ +identifier func =~ ".*_create$"; +identifier event, dnode, resource; +@@ + +int +- func(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) ++ func(struct nb_cb_create_args *args) + { +<... +( +- event ++ args->event +| +- dnode ++ args->dnode +| +- resource ++ args->resource +) +...> + } + +@@ +identifier func =~ ".*_modify$"; +identifier event, dnode, resource; +@@ + +int +- func(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) ++ func(struct nb_cb_modify_args *args) + { +<... +( +- event ++ args->event +| +- dnode ++ args->dnode +| +- resource ++ args->resource +) +...> + } + +@@ +identifier func =~ ".*_destroy$"; +identifier event, dnode; +@@ + +int +- func(enum nb_event event, const struct lyd_node *dnode) ++ func(struct nb_cb_destroy_args *args) + { +<... +( +- dnode ++ args->dnode +| +- event ++ args->event +) +...> + } + +@@ +identifier func =~ ".*_pre_validate$"; +identifier dnode; +@@ + +int +- func(const struct lyd_node dnode) ++ func(struct nb_cb_pre_validate_args *args) + { +<... +- dnode ++ args->dnode +...> + } + +@@ +identifier func =~ ".*_apply_finish$"; +identifier dnode; +@@ + +void +- func(const struct lyd_node *dnode) ++ func(struct nb_cb_apply_finish_args *args) + { +<... +- dnode ++ args->dnode +...> + } + +@@ +identifier func =~ ".*_get_elem$"; +identifier xpath, list_entry; +@@ + +struct yang_data * +- func(const char *xpath, const void *list_entry) ++ func(struct nb_cb_get_elem_args *args) + { +<... +( +- xpath ++ args->xpath +| +- list_entry ++ args->list_entry +) +...> + } + +@@ +identifier func =~ ".*_get_next$"; +identifier parent_list_entry, list_entry; +@@ + +const void * +- func(const void *parent_list_entry, const void *list_entry) ++ func(struct nb_cb_get_next_args *args) + { +<... +( +- parent_list_entry ++ args->parent_list_entry +| +- list_entry ++ args->list_entry +) +...> + } + +@@ +identifier func =~ ".*_get_keys$"; +identifier list_entry, keys; +@@ + +int +- func(const void *list_entry, struct yang_list_keys *keys) ++ func(struct nb_cb_get_keys_args *args) + { +<... +( +- list_entry ++ args->list_entry +| +- keys ++ args->keys +) +...> + } + +@@ +identifier func =~ ".*_lookup_entry$"; +identifier parent_list_entry, keys; +@@ + +const void * +- func(const void *parent_list_entry, const struct yang_list_keys *keys) ++ func(struct nb_cb_lookup_entry_args *args) + { +<... +( +- parent_list_entry ++ args->parent_list_entry +| +- keys ++ args->keys +) +...> + } + +@@ +identifier func =~ ".*_rpc$"; +identifier xpath, input, output; +@@ + +int +- func(const char *xpath, const struct list *input, struct list *output) ++ func(struct nb_cb_rpc_args *args) + { +<... +( +- xpath ++ args->xpath +| +- input ++ args->input +| +- output ++ args->output +) +...> + } + +@@ +identifier func =~ ".*_create$"; +identifier event, dnode, resource; +@@ + +int +- func(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) ++ func(struct nb_cb_create_args *args) +; + +@@ +identifier func =~ ".*_modify$"; +identifier event, dnode, resource; +@@ + +int +- func(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) ++ func(struct nb_cb_modify_args *args) +; + +@@ +identifier func =~ ".*_destroy$"; +identifier event, dnode; +@@ + +int +- func(enum nb_event event, const struct lyd_node *dnode) ++ func(struct nb_cb_destroy_args *args) +; + +@@ +identifier func =~ ".*_pre_validate$"; +identifier dnode; +@@ + +int +- func(const struct lyd_node dnode) ++ func(struct nb_cb_pre_validate_args *args) +; + +@@ +identifier func =~ ".*_apply_finish$"; +identifier dnode; +@@ + +void +- func(const struct lyd_node *dnode) ++ func(struct nb_cb_apply_finish_args *args) +; + +@@ +identifier func =~ ".*_get_elem$"; +identifier xpath, list_entry; +@@ + +struct yang_data * +- func(const char *xpath, const void *list_entry) ++ func(struct nb_cb_get_elem_args *args) +; + +@@ +identifier func =~ ".*_get_next$"; +identifier parent_list_entry, list_entry; +@@ + +const void * +- func(const void *parent_list_entry, const void *list_entry) ++ func(struct nb_cb_get_next_args *args) +; + +@@ +identifier func =~ ".*_get_keys$"; +identifier list_entry, keys; +@@ + +int +- func(const void *list_entry, struct yang_list_keys *keys) ++ func(struct nb_cb_get_keys_args *args) +; + +@@ +identifier func =~ ".*_lookup_entry$"; +identifier parent_list_entry, keys; +@@ + +const void * +- func(const void *parent_list_entry, const struct yang_list_keys *keys) ++ func(struct nb_cb_lookup_entry_args *args) +; + +@@ +identifier func =~ ".*_rpc$"; +identifier xpath, input, output; +@@ + +int +- func(const char *xpath, const struct list *input, struct list *output) ++ func(struct nb_cb_rpc_args *args) +; diff --git a/tools/gen_northbound_callbacks.c b/tools/gen_northbound_callbacks.c index 7118986854..8dccbac3ae 100644 --- a/tools/gen_northbound_callbacks.c +++ b/tools/gen_northbound_callbacks.c @@ -46,70 +46,62 @@ static struct nb_callback_info { .operation = NB_OP_CREATE, .return_type = "int ", .return_value = "NB_OK", - .arguments = - "enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource", + .arguments = "struct nb_cb_create_args *args", }, { .operation = NB_OP_MODIFY, .return_type = "int ", .return_value = "NB_OK", - .arguments = - "enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource", + .arguments = "struct nb_cb_modify_args *args", }, { .operation = NB_OP_DESTROY, .return_type = "int ", .return_value = "NB_OK", - .arguments = - "enum nb_event event, const struct lyd_node *dnode", + .arguments = "struct nb_cb_destroy_args *args", }, { .operation = NB_OP_MOVE, .return_type = "int ", .return_value = "NB_OK", - .arguments = - "enum nb_event event, const struct lyd_node *dnode", + .arguments = "struct nb_cb_move_args *args", }, { .operation = NB_OP_APPLY_FINISH, .optional = true, .return_type = "void ", .return_value = "", - .arguments = "const struct lyd_node *dnode", + .arguments = "struct nb_cb_apply_finish_args *args", }, { .operation = NB_OP_GET_ELEM, .return_type = "struct yang_data *", .return_value = "NULL", - .arguments = "const char *xpath, const void *list_entry", + .arguments = "struct nb_cb_get_elem_args *args", }, { .operation = NB_OP_GET_NEXT, .return_type = "const void *", .return_value = "NULL", - .arguments = - "const void *parent_list_entry, const void *list_entry", + .arguments = "struct nb_cb_get_next_args *args", }, { .operation = NB_OP_GET_KEYS, .return_type = "int ", .return_value = "NB_OK", - .arguments = - "const void *list_entry, struct yang_list_keys *keys", + .arguments = "struct nb_cb_get_keys_args *args", }, { .operation = NB_OP_LOOKUP_ENTRY, .return_type = "const void *", .return_value = "NULL", - .arguments = - "const void *parent_list_entry, const struct yang_list_keys *keys", + .arguments = "struct nb_cb_lookup_entry_args *args", }, { .operation = NB_OP_RPC, .return_type = "int ", .return_value = "NB_OK", - .arguments = - "const char *xpath, const struct list *input, struct list *output", + .arguments = "struct nb_cb_rpc_args *args", }, { /* sentinel */ diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c index 13118a2769..7ad2a84500 100644 --- a/tools/start-stop-daemon.c +++ b/tools/start-stop-daemon.c @@ -605,9 +605,9 @@ static void parse_options(int argc, char *const *argv) static int pid_is_exec(pid_t pid, const struct stat *esb) { struct stat sb; - char buf[32]; + char buf[PATH_MAX]; - sprintf(buf, "/proc/%ld/exe", (long)pid); + snprintf(buf, sizeof(buf), "/proc/%ld/exe", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino); @@ -617,9 +617,9 @@ static int pid_is_exec(pid_t pid, const struct stat *esb) static int pid_is_user(pid_t pid, uid_t uid) { struct stat sb; - char buf[32]; + char buf[PATH_MAX]; - sprintf(buf, "/proc/%ld", (long)pid); + snprintf(buf, sizeof(buf), "/proc/%ld", (long)pid); if (stat(buf, &sb) != 0) return 0; return (sb.st_uid == uid); @@ -628,11 +628,11 @@ static int pid_is_user(pid_t pid, uid_t uid) static int pid_is_cmd(pid_t pid, const char *name) { - char buf[32]; + char buf[PATH_MAX]; FILE *f; int c; - sprintf(buf, "/proc/%ld/stat", (long)pid); + snprintf(buf, sizeof(buf), "/proc/%ld/stat", (long)pid); f = fopen(buf, "r"); if (!f) return 0; diff --git a/tools/symalyzer.py b/tools/symalyzer.py index b3b5c4e567..cff21f9f93 100755 --- a/tools/symalyzer.py +++ b/tools/symalyzer.py @@ -21,49 +21,9 @@ import sys, os, subprocess import re from collections import namedtuple -class MakeVars(object): - ''' - makevars['FOO_CFLAGS'] gets you "FOO_CFLAGS" from Makefile - ''' - def __init__(self): - self._data = dict() +sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'python')) - def getvars(self, varlist): - ''' - get a batch list of variables from make. faster than individual calls. - ''' - rdfd, wrfd = os.pipe() - - shvars = ['shvar-%s' % s for s in varlist] - make = subprocess.Popen(['make', '-s', 'VARFD=%d' % wrfd] + shvars, pass_fds = [wrfd]) - os.close(wrfd) - data = b'' - - rdf = os.fdopen(rdfd, 'rb') - while True: - rdata = rdf.read() - if len(rdata) == 0: - break - data += rdata - - del rdf - make.wait() - - data = data.decode('US-ASCII').strip().split('\n') - for row in data: - k, v = row.split('=', 1) - v = v[1:-1] - self._data[k] = v - - def __getitem__(self, k): - if k not in self._data: - self.getvars([k]) - return self._data[k] - - def get(self, k, defval = None): - if k not in self._data: - self.getvars([k]) - return self._data[k] or defval +from makevars import MakeVars SymRowBase = namedtuple('SymRow', ['target', 'object', 'name', 'address', 'klass', 'typ', 'size', 'line', 'section', 'loc']) class SymRow(SymRowBase): @@ -324,7 +284,7 @@ def write_html_report(syms): else: with open('jquery-3.4.1.min.js.tmp', 'w') as fd: fd.write(r.text) - os.rename('jquery-3.4.1.min.js.tmp', 'jquery-3.4.1.min.js.tmp') + os.rename('jquery-3.4.1.min.js.tmp', 'jquery-3.4.1.min.js') sys.stderr.write('done.\n') def automake_escape(s): diff --git a/vrrpd/subdir.am b/vrrpd/subdir.am index 07358e0383..412ee1c3cf 100644 --- a/vrrpd/subdir.am +++ b/vrrpd/subdir.am @@ -6,7 +6,7 @@ if VRRPD noinst_LIBRARIES += vrrpd/libvrrp.a sbin_PROGRAMS += vrrpd/vrrpd # dist_examples_DATA += staticd/staticd.conf.sample -vtysh_scan += $(top_srcdir)/vrrpd/vrrp_vty.c +vtysh_scan += vrrpd/vrrp_vty.c man8 += $(MANBUILD)/frr-vrrpd.8 endif @@ -31,8 +31,9 @@ noinst_HEADERS += \ vrrpd/vrrp_zebra.h \ # end -vrrpd/vrrp_vty_clippy.c: $(CLIPPY_DEPS) -vrrpd/vrrp_vty.$(OBJEXT): vrrpd/vrrp_vty_clippy.c +clippy_scan += \ + vrrpd/vrrp_vty.c \ + # end vrrpd_vrrpd_SOURCES = vrrpd/vrrp_main.c vrrpd_vrrpd_LDADD = vrrpd/libvrrp.a lib/libfrr.la @LIBCAP@ diff --git a/vrrpd/vrrp_northbound.c b/vrrpd/vrrp_northbound.c index feaea6c038..c11e0352de 100644 --- a/vrrpd/vrrp_northbound.c +++ b/vrrpd/vrrp_northbound.c @@ -33,58 +33,55 @@ /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group */ -static int lib_interface_vrrp_vrrp_group_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +static int lib_interface_vrrp_vrrp_group_create(struct nb_cb_create_args *args) { struct interface *ifp; uint8_t vrid; uint8_t version = 3; struct vrrp_vrouter *vr; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - ifp = nb_running_get_entry(dnode, NULL, true); - vrid = yang_dnode_get_uint8(dnode, "./virtual-router-id"); - version = yang_dnode_get_enum(dnode, "./version"); + ifp = nb_running_get_entry(args->dnode, NULL, true); + vrid = yang_dnode_get_uint8(args->dnode, "./virtual-router-id"); + version = yang_dnode_get_enum(args->dnode, "./version"); vr = vrrp_vrouter_create(ifp, vrid, version); - nb_running_set_entry(dnode, vr); + nb_running_set_entry(args->dnode, vr); return NB_OK; } -static int lib_interface_vrrp_vrrp_group_destroy(enum nb_event event, - const struct lyd_node *dnode) +static int +lib_interface_vrrp_vrrp_group_destroy(struct nb_cb_destroy_args *args) { struct vrrp_vrouter *vr; - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - vr = nb_running_unset_entry(dnode); + vr = nb_running_unset_entry(args->dnode); vrrp_vrouter_destroy(vr); return NB_OK; } static const void * -lib_interface_vrrp_vrrp_group_get_next(const void *parent_list_entry, - const void *list_entry) +lib_interface_vrrp_vrrp_group_get_next(struct nb_cb_get_next_args *args) { struct list *l = hash_to_list(vrrp_vrouters_hash); struct listnode *ln; const struct vrrp_vrouter *curr; - const struct interface *ifp = parent_list_entry; + const struct interface *ifp = args->parent_list_entry; /* * If list_entry is null, we return the first vrrp instance with a * matching interface */ - bool nextone = list_entry ? false : true; + bool nextone = args->list_entry ? false : true; for (ALL_LIST_ELEMENTS_RO(l, ln, curr)) { - if (curr == list_entry) { + if (curr == args->list_entry) { nextone = true; continue; } @@ -100,23 +97,23 @@ done: return curr; } -static int lib_interface_vrrp_vrrp_group_get_keys(const void *list_entry, - struct yang_list_keys *keys) +static int +lib_interface_vrrp_vrrp_group_get_keys(struct nb_cb_get_keys_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - keys->num = 1; - snprintf(keys->key[0], sizeof(keys->key[0]), "%" PRIu32, vr->vrid); + args->keys->num = 1; + snprintf(args->keys->key[0], sizeof(args->keys->key[0]), "%" PRIu32, + vr->vrid); return NB_OK; } static const void * -lib_interface_vrrp_vrrp_group_lookup_entry(const void *parent_list_entry, - const struct yang_list_keys *keys) +lib_interface_vrrp_vrrp_group_lookup_entry(struct nb_cb_lookup_entry_args *args) { - uint32_t vrid = strtoul(keys->key[0], NULL, 10); - const struct interface *ifp = parent_list_entry; + uint32_t vrid = strtoul(args->keys->key[0], NULL, 10); + const struct interface *ifp = args->parent_list_entry; return vrrp_lookup(ifp, vrid); } @@ -125,20 +122,18 @@ lib_interface_vrrp_vrrp_group_lookup_entry(const void *parent_list_entry, * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/version */ static int -lib_interface_vrrp_vrrp_group_version_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_vrrp_vrrp_group_version_modify(struct nb_cb_modify_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; struct vrrp_vrouter *vr; uint8_t version; - vr = nb_running_get_entry(dnode, NULL, true); + vr = nb_running_get_entry(args->dnode, NULL, true); vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN); vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN); - version = yang_dnode_get_enum(dnode, NULL); + version = yang_dnode_get_enum(args->dnode, NULL); vr->version = version; vrrp_check_start(vr); @@ -170,24 +165,23 @@ static void vrrp_yang_add_del_virtual_address(const struct lyd_node *dnode, * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/virtual-address */ static int lib_interface_vrrp_vrrp_group_v4_virtual_address_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - vrrp_yang_add_del_virtual_address(dnode, true); + vrrp_yang_add_del_virtual_address(args->dnode, true); return NB_OK; } static int lib_interface_vrrp_vrrp_group_v4_virtual_address_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - vrrp_yang_add_del_virtual_address(dnode, false); + vrrp_yang_add_del_virtual_address(args->dnode, false); return NB_OK; } @@ -198,11 +192,11 @@ static int lib_interface_vrrp_vrrp_group_v4_virtual_address_destroy( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v4_current_priority_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint8(xpath, vr->v4->priority); + return yang_data_new_uint8(args->xpath, vr->v4->priority); } /* @@ -210,15 +204,15 @@ lib_interface_vrrp_vrrp_group_v4_current_priority_get_elem( * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/vrrp-interface */ static struct yang_data * -lib_interface_vrrp_vrrp_group_v4_vrrp_interface_get_elem(const char *xpath, - const void *list_entry) +lib_interface_vrrp_vrrp_group_v4_vrrp_interface_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; struct yang_data *val = NULL; if (vr->v4->mvl_ifp) - val = yang_data_new_string(xpath, vr->v4->mvl_ifp->name); + val = yang_data_new_string(args->xpath, vr->v4->mvl_ifp->name); return val; } @@ -228,17 +222,17 @@ lib_interface_vrrp_vrrp_group_v4_vrrp_interface_get_elem(const char *xpath, * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/source-address */ static struct yang_data * -lib_interface_vrrp_vrrp_group_v4_source_address_get_elem(const char *xpath, - const void *list_entry) +lib_interface_vrrp_vrrp_group_v4_source_address_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; struct yang_data *val = NULL; struct ipaddr ip; memset(&ip, 0x00, sizeof(ip)); if (memcmp(&vr->v4->src.ipaddr_v4, &ip.ipaddr_v4, sizeof(ip.ipaddr_v4))) - val = yang_data_new_ip(xpath, &vr->v4->src); + val = yang_data_new_ip(args->xpath, &vr->v4->src); return val; } @@ -246,13 +240,12 @@ lib_interface_vrrp_vrrp_group_v4_source_address_get_elem(const char *xpath, /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/state */ -static struct yang_data * -lib_interface_vrrp_vrrp_group_v4_state_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *lib_interface_vrrp_vrrp_group_v4_state_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_enum(xpath, vr->v4->fsm.state); + return yang_data_new_enum(args->xpath, vr->v4->fsm.state); } /* @@ -261,23 +254,22 @@ lib_interface_vrrp_vrrp_group_v4_state_get_elem(const char *xpath, */ static struct yang_data * lib_interface_vrrp_vrrp_group_v4_master_advertisement_interval_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint16(xpath, vr->v4->master_adver_interval); + return yang_data_new_uint16(args->xpath, vr->v4->master_adver_interval); } /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v4/skew-time */ -static struct yang_data * -lib_interface_vrrp_vrrp_group_v4_skew_time_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *lib_interface_vrrp_vrrp_group_v4_skew_time_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint16(xpath, vr->v4->skew_time); + return yang_data_new_uint16(args->xpath, vr->v4->skew_time); } /* @@ -286,11 +278,11 @@ lib_interface_vrrp_vrrp_group_v4_skew_time_get_elem(const char *xpath, */ static struct yang_data * lib_interface_vrrp_vrrp_group_v4_counter_state_transition_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint32(xpath, vr->v4->stats.trans_cnt); + return yang_data_new_uint32(args->xpath, vr->v4->stats.trans_cnt); } /* @@ -299,11 +291,11 @@ lib_interface_vrrp_vrrp_group_v4_counter_state_transition_get_elem( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v4_counter_tx_advertisement_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint32(xpath, vr->v4->stats.adver_tx_cnt); + return yang_data_new_uint32(args->xpath, vr->v4->stats.adver_tx_cnt); } /* @@ -312,11 +304,11 @@ lib_interface_vrrp_vrrp_group_v4_counter_tx_advertisement_get_elem( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v4_counter_tx_gratuitous_arp_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint32(xpath, vr->v4->stats.garp_tx_cnt); + return yang_data_new_uint32(args->xpath, vr->v4->stats.garp_tx_cnt); } /* @@ -325,11 +317,11 @@ lib_interface_vrrp_vrrp_group_v4_counter_tx_gratuitous_arp_get_elem( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v4_counter_rx_advertisement_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint32(xpath, vr->v4->stats.adver_rx_cnt); + return yang_data_new_uint32(args->xpath, vr->v4->stats.adver_rx_cnt); } /* @@ -337,24 +329,23 @@ lib_interface_vrrp_vrrp_group_v4_counter_rx_advertisement_get_elem( * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/virtual-address */ static int lib_interface_vrrp_vrrp_group_v6_virtual_address_create( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_create_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - vrrp_yang_add_del_virtual_address(dnode, true); + vrrp_yang_add_del_virtual_address(args->dnode, true); return NB_OK; } static int lib_interface_vrrp_vrrp_group_v6_virtual_address_destroy( - enum nb_event event, const struct lyd_node *dnode) + struct nb_cb_destroy_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; - vrrp_yang_add_del_virtual_address(dnode, false); + vrrp_yang_add_del_virtual_address(args->dnode, false); return NB_OK; } @@ -365,11 +356,11 @@ static int lib_interface_vrrp_vrrp_group_v6_virtual_address_destroy( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v6_current_priority_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint8(xpath, vr->v6->priority); + return yang_data_new_uint8(args->xpath, vr->v6->priority); } /* @@ -377,14 +368,14 @@ lib_interface_vrrp_vrrp_group_v6_current_priority_get_elem( * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/vrrp-interface */ static struct yang_data * -lib_interface_vrrp_vrrp_group_v6_vrrp_interface_get_elem(const char *xpath, - const void *list_entry) +lib_interface_vrrp_vrrp_group_v6_vrrp_interface_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; struct yang_data *val = NULL; if (vr->v6->mvl_ifp) - val = yang_data_new_string(xpath, vr->v6->mvl_ifp->name); + val = yang_data_new_string(args->xpath, vr->v6->mvl_ifp->name); return val; } @@ -394,14 +385,14 @@ lib_interface_vrrp_vrrp_group_v6_vrrp_interface_get_elem(const char *xpath, * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/source-address */ static struct yang_data * -lib_interface_vrrp_vrrp_group_v6_source_address_get_elem(const char *xpath, - const void *list_entry) +lib_interface_vrrp_vrrp_group_v6_source_address_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; struct yang_data *val = NULL; if (ipaddr_isset(&vr->v6->src)) - val = yang_data_new_ip(xpath, &vr->v6->src); + val = yang_data_new_ip(args->xpath, &vr->v6->src); return val; } @@ -409,13 +400,12 @@ lib_interface_vrrp_vrrp_group_v6_source_address_get_elem(const char *xpath, /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/state */ -static struct yang_data * -lib_interface_vrrp_vrrp_group_v6_state_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *lib_interface_vrrp_vrrp_group_v6_state_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_enum(xpath, vr->v6->fsm.state); + return yang_data_new_enum(args->xpath, vr->v6->fsm.state); } /* @@ -424,23 +414,22 @@ lib_interface_vrrp_vrrp_group_v6_state_get_elem(const char *xpath, */ static struct yang_data * lib_interface_vrrp_vrrp_group_v6_master_advertisement_interval_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint16(xpath, vr->v6->master_adver_interval); + return yang_data_new_uint16(args->xpath, vr->v6->master_adver_interval); } /* * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/v6/skew-time */ -static struct yang_data * -lib_interface_vrrp_vrrp_group_v6_skew_time_get_elem(const char *xpath, - const void *list_entry) +static struct yang_data *lib_interface_vrrp_vrrp_group_v6_skew_time_get_elem( + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint16(xpath, vr->v6->skew_time); + return yang_data_new_uint16(args->xpath, vr->v6->skew_time); } /* @@ -449,11 +438,11 @@ lib_interface_vrrp_vrrp_group_v6_skew_time_get_elem(const char *xpath, */ static struct yang_data * lib_interface_vrrp_vrrp_group_v6_counter_state_transition_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint32(xpath, vr->v6->stats.trans_cnt); + return yang_data_new_uint32(args->xpath, vr->v6->stats.trans_cnt); } /* @@ -462,11 +451,11 @@ lib_interface_vrrp_vrrp_group_v6_counter_state_transition_get_elem( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v6_counter_tx_advertisement_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { - const struct vrrp_vrouter *vr = list_entry; + const struct vrrp_vrouter *vr = args->list_entry; - return yang_data_new_uint32(xpath, vr->v6->stats.adver_tx_cnt); + return yang_data_new_uint32(args->xpath, vr->v6->stats.adver_tx_cnt); } /* @@ -475,7 +464,7 @@ lib_interface_vrrp_vrrp_group_v6_counter_tx_advertisement_get_elem( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v6_counter_tx_neighbor_advertisement_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { /* TODO: implement me. */ return NULL; @@ -487,7 +476,7 @@ lib_interface_vrrp_vrrp_group_v6_counter_tx_neighbor_advertisement_get_elem( */ static struct yang_data * lib_interface_vrrp_vrrp_group_v6_counter_rx_advertisement_get_elem( - const char *xpath, const void *list_entry) + struct nb_cb_get_elem_args *args) { /* TODO: implement me. */ return NULL; @@ -497,18 +486,16 @@ lib_interface_vrrp_vrrp_group_v6_counter_rx_advertisement_get_elem( * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/priority */ static int -lib_interface_vrrp_vrrp_group_priority_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_vrrp_vrrp_group_priority_modify(struct nb_cb_modify_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; struct vrrp_vrouter *vr; uint8_t priority; - vr = nb_running_get_entry(dnode, NULL, true); - priority = yang_dnode_get_uint8(dnode, NULL); + vr = nb_running_get_entry(args->dnode, NULL, true); + priority = yang_dnode_get_uint8(args->dnode, NULL); vrrp_set_priority(vr, priority); return NB_OK; @@ -518,18 +505,16 @@ lib_interface_vrrp_vrrp_group_priority_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/preempt */ static int -lib_interface_vrrp_vrrp_group_preempt_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_vrrp_vrrp_group_preempt_modify(struct nb_cb_modify_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; struct vrrp_vrouter *vr; bool preempt; - vr = nb_running_get_entry(dnode, NULL, true); - preempt = yang_dnode_get_bool(dnode, NULL); + vr = nb_running_get_entry(args->dnode, NULL, true); + preempt = yang_dnode_get_bool(args->dnode, NULL); vr->preempt_mode = preempt; return NB_OK; @@ -539,18 +524,16 @@ lib_interface_vrrp_vrrp_group_preempt_modify(enum nb_event event, * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/accept-mode */ static int -lib_interface_vrrp_vrrp_group_accept_mode_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_vrrp_vrrp_group_accept_mode_modify(struct nb_cb_modify_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; struct vrrp_vrouter *vr; bool accept; - vr = nb_running_get_entry(dnode, NULL, true); - accept = yang_dnode_get_bool(dnode, NULL); + vr = nb_running_get_entry(args->dnode, NULL, true); + accept = yang_dnode_get_bool(args->dnode, NULL); vr->accept_mode = accept; return NB_OK; @@ -561,17 +544,16 @@ lib_interface_vrrp_vrrp_group_accept_mode_modify(enum nb_event event, * /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/advertisement-interval */ static int lib_interface_vrrp_vrrp_group_advertisement_interval_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) + struct nb_cb_modify_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; struct vrrp_vrouter *vr; uint16_t advert_int; - vr = nb_running_get_entry(dnode, NULL, true); - advert_int = yang_dnode_get_uint16(dnode, NULL); + vr = nb_running_get_entry(args->dnode, NULL, true); + advert_int = yang_dnode_get_uint16(args->dnode, NULL); vrrp_set_advertisement_interval(vr, advert_int); return NB_OK; @@ -581,18 +563,16 @@ static int lib_interface_vrrp_vrrp_group_advertisement_interval_modify( * XPath: /frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group/shutdown */ static int -lib_interface_vrrp_vrrp_group_shutdown_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) +lib_interface_vrrp_vrrp_group_shutdown_modify(struct nb_cb_modify_args *args) { - if (event != NB_EV_APPLY) + if (args->event != NB_EV_APPLY) return NB_OK; struct vrrp_vrouter *vr; bool shutdown; - vr = nb_running_get_entry(dnode, NULL, true); - shutdown = yang_dnode_get_bool(dnode, NULL); + vr = nb_running_get_entry(args->dnode, NULL, true); + shutdown = yang_dnode_get_bool(args->dnode, NULL); vr->shutdown = shutdown; diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index 892c8dadd4..b6388cc5ba 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -744,15 +744,33 @@ static int vrrp_config_write_interface(struct vty *vty) return write; } -static struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1}; -static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; -static struct cmd_node vrrp_node = {VRRP_NODE, "", 1}; +static struct cmd_node interface_node = { + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = vrrp_config_write_interface, +}; + +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = vrrp_config_write_debug, +}; + +static struct cmd_node vrrp_node = { + .name = "vrrp", + .node = VRRP_NODE, + .prompt = "", + .config_write = vrrp_config_write_global, +}; void vrrp_vty_init(void) { - install_node(&debug_node, vrrp_config_write_debug); - install_node(&interface_node, vrrp_config_write_interface); - install_node(&vrrp_node, vrrp_config_write_global); + install_node(&debug_node); + install_node(&interface_node); + install_node(&vrrp_node); if_cmd_init(); install_element(VIEW_NODE, &vrrp_vrid_show_cmd); diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index c4f293fd3b..d5142b1b55 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -138,7 +138,7 @@ sub scan_file { $protocol = "VTYSH_FABRICD"; } else { - ($protocol) = ($file =~ /^.*\/([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/); + ($protocol) = ($file =~ /^(?:.*\/)?([a-z0-9]+)\/[a-zA-Z0-9_\-]+\.c$/); $protocol = "VTYSH_" . uc $protocol; } @@ -197,7 +197,7 @@ sub scan_file { } foreach (@ARGV) { - if (/\/isisd\//) { + if (/(^|\/)isisd\//) { # We scan all the IS-IS files twice, once for isisd, # once for fabricd. Exceptions are made for the files # that are not shared between the two. diff --git a/vtysh/subdir.am b/vtysh/subdir.am index 74595788b0..3e9b8a3dc9 100644 --- a/vtysh/subdir.am +++ b/vtysh/subdir.am @@ -31,5 +31,5 @@ am__v_EXTRACT_ = $(am__v_EXTRACT_$(AM_DEFAULT_VERBOSITY)) am__v_EXTRACT_0 = @echo " EXTRACT " $@; am__v_EXTRACT_1 = -vtysh/vtysh_cmd.c: $(vtysh_scan) vtysh/extract.pl - $(AM_V_EXTRACT) vtysh/extract.pl $(vtysh_scan) > vtysh/vtysh_cmd.c +vtysh/vtysh_cmd.c: vtysh/extract.pl $(vtysh_scan) + $(AM_V_EXTRACT) $^ > vtysh/vtysh_cmd.c diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index a5fa686eb5..2ef0347651 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1173,141 +1173,326 @@ static char **new_completion(const char *text, int start, int end) /* Vty node structures. */ static struct cmd_node bgp_node = { - BGP_NODE, "%s(config-router)# ", + .name = "bgp", + .node = BGP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", }; static struct cmd_node rip_node = { - RIP_NODE, "%s(config-router)# ", + .name = "rip", + .node = RIP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", }; static struct cmd_node isis_node = { - ISIS_NODE, "%s(config-router)# ", + .name = "isis", + .node = ISIS_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", }; static struct cmd_node openfabric_node = { - OPENFABRIC_NODE, "%s(config-router)# ", + .name = "openfabric", + .node = OPENFABRIC_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", }; static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", }; static struct cmd_node pw_node = { - PW_NODE, "%s(config-pw)# ", + .name = "pw", + .node = PW_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pw)# ", }; static struct cmd_node vrf_node = { - VRF_NODE, "%s(config-vrf)# ", + .name = "vrf", + .node = VRF_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-vrf)# ", }; static struct cmd_node nh_group_node = { - NH_GROUP_NODE, - "%s(config-nh-group)# ", + .name = "nexthop-group", + .node = NH_GROUP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-nh-group)# ", }; -static struct cmd_node rmap_node = {RMAP_NODE, "%s(config-route-map)# "}; +static struct cmd_node rmap_node = { + .name = "routemap", + .node = RMAP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-route-map)# ", +}; -static struct cmd_node pbr_map_node = {PBRMAP_NODE, "%s(config-pbr-map)# "}; +static struct cmd_node pbr_map_node = { + .name = "pbr-map", + .node = PBRMAP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pbr-map)# ", +}; -static struct cmd_node zebra_node = {ZEBRA_NODE, "%s(config-router)# "}; +static struct cmd_node zebra_node = { + .name = "zebra", + .node = ZEBRA_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node bgp_vpnv4_node = {BGP_VPNV4_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_vpnv4_node = { + .name = "bgp vpnv4", + .node = BGP_VPNV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_vpnv6_node = {BGP_VPNV6_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_vpnv6_node = { + .name = "bgp vpnv6", + .node = BGP_VPNV6_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_flowspecv4_node = {BGP_FLOWSPECV4_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_flowspecv4_node = { + .name = "bgp ipv4 flowspec", + .node = BGP_FLOWSPECV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_flowspecv6_node = {BGP_FLOWSPECV6_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_flowspecv6_node = { + .name = "bgp ipv6 flowspec", + .node = BGP_FLOWSPECV6_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv4_node = {BGP_IPV4_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv4_node = { + .name = "bgp ipv4 unicast", + .node = BGP_IPV4_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv4m_node = {BGP_IPV4M_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv4m_node = { + .name = "bgp ipv4 multicast", + .node = BGP_IPV4M_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv4l_node = {BGP_IPV4L_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv4l_node = { + .name = "bgp ipv4 labeled unicast", + .node = BGP_IPV4L_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv6_node = {BGP_IPV6_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv6_node = { + .name = "bgp ipv6", + .node = BGP_IPV6_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_ipv6m_node = {BGP_IPV6M_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv6m_node = { + .name = "bgp ipv6 multicast", + .node = BGP_IPV6M_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_evpn_node = {BGP_EVPN_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_evpn_node = { + .name = "bgp evpn", + .node = BGP_EVPN_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; -static struct cmd_node bgp_evpn_vni_node = {BGP_EVPN_VNI_NODE, - "%s(config-router-af-vni)# "}; +static struct cmd_node bgp_evpn_vni_node = { + .name = "bgp evpn vni", + .node = BGP_EVPN_VNI_NODE, + .parent_node = BGP_EVPN_NODE, + .prompt = "%s(config-router-af-vni)# ", +}; -static struct cmd_node bgp_ipv6l_node = {BGP_IPV6L_NODE, - "%s(config-router-af)# "}; +static struct cmd_node bgp_ipv6l_node = { + .name = "bgp ipv6 labeled unicast", + .node = BGP_IPV6L_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-af)# ", +}; static struct cmd_node bgp_vnc_defaults_node = { - BGP_VNC_DEFAULTS_NODE, "%s(config-router-vnc-defaults)# "}; + .name = "bgp vnc defaults", + .node = BGP_VNC_DEFAULTS_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vnc-defaults)# ", +}; static struct cmd_node bgp_vnc_nve_group_node = { - BGP_VNC_NVE_GROUP_NODE, "%s(config-router-vnc-nve-group)# "}; + .name = "bgp vnc nve", + .node = BGP_VNC_NVE_GROUP_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vnc-nve-group)# ", +}; -static struct cmd_node bgp_vrf_policy_node = {BGP_VRF_POLICY_NODE, - "%s(config-router-vrf-policy)# "}; +static struct cmd_node bgp_vrf_policy_node = { + .name = "bgp vrf policy", + .node = BGP_VRF_POLICY_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vrf-policy)# ", +}; static struct cmd_node bgp_vnc_l2_group_node = { - BGP_VNC_L2_GROUP_NODE, "%s(config-router-vnc-l2-group)# "}; + .name = "bgp vnc l2", + .node = BGP_VNC_L2_GROUP_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-router-vnc-l2-group)# ", +}; -static struct cmd_node bmp_node = {BMP_NODE, "%s(config-bgp-bmp)# "}; +static struct cmd_node bmp_node = { + .name = "bmp", + .node = BMP_NODE, + .parent_node = BGP_NODE, + .prompt = "%s(config-bgp-bmp)# " +}; -static struct cmd_node ospf_node = {OSPF_NODE, "%s(config-router)# "}; +static struct cmd_node ospf_node = { + .name = "ospf", + .node = OSPF_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node eigrp_node = {EIGRP_NODE, "%s(config-router)# "}; +static struct cmd_node eigrp_node = { + .name = "eigrp", + .node = EIGRP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node babel_node = {BABEL_NODE, "%s(config-router)# "}; +static struct cmd_node babel_node = { + .name = "babel", + .node = BABEL_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node ripng_node = {RIPNG_NODE, "%s(config-router)# "}; +static struct cmd_node ripng_node = { + .name = "ripng", + .node = RIPNG_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-router)# ", +}; -static struct cmd_node ospf6_node = {OSPF6_NODE, "%s(config-ospf6)# "}; +static struct cmd_node ospf6_node = { + .name = "ospf6", + .node = OSPF6_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-ospf6)# ", +}; -static struct cmd_node ldp_node = {LDP_NODE, "%s(config-ldp)# "}; +static struct cmd_node ldp_node = { + .name = "ldp", + .node = LDP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-ldp)# ", +}; -static struct cmd_node ldp_ipv4_node = {LDP_IPV4_NODE, "%s(config-ldp-af)# "}; +static struct cmd_node ldp_ipv4_node = { + .name = "ldp ipv4", + .node = LDP_IPV4_NODE, + .parent_node = LDP_NODE, + .prompt = "%s(config-ldp-af)# ", +}; -static struct cmd_node ldp_ipv6_node = {LDP_IPV6_NODE, "%s(config-ldp-af)# "}; +static struct cmd_node ldp_ipv6_node = { + .name = "ldp ipv6", + .node = LDP_IPV6_NODE, + .parent_node = LDP_NODE, + .prompt = "%s(config-ldp-af)# ", +}; -static struct cmd_node ldp_ipv4_iface_node = {LDP_IPV4_IFACE_NODE, - "%s(config-ldp-af-if)# "}; +static struct cmd_node ldp_ipv4_iface_node = { + .name = "ldp ipv4 interface", + .node = LDP_IPV4_IFACE_NODE, + .parent_node = LDP_IPV4_NODE, + .prompt = "%s(config-ldp-af-if)# ", +}; -static struct cmd_node ldp_ipv6_iface_node = {LDP_IPV6_IFACE_NODE, - "%s(config-ldp-af-if)# "}; +static struct cmd_node ldp_ipv6_iface_node = { + .name = "ldp ipv6 interface", + .node = LDP_IPV6_IFACE_NODE, + .parent_node = LDP_IPV6_NODE, + .prompt = "%s(config-ldp-af-if)# ", +}; -static struct cmd_node ldp_l2vpn_node = {LDP_L2VPN_NODE, "%s(config-l2vpn)# "}; +static struct cmd_node ldp_l2vpn_node = { + .name = "ldp l2vpn", + .node = LDP_L2VPN_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-l2vpn)# ", +}; -static struct cmd_node ldp_pseudowire_node = {LDP_PSEUDOWIRE_NODE, - "%s(config-l2vpn-pw)# "}; +static struct cmd_node ldp_pseudowire_node = { + .name = "ldp", + .node = LDP_PSEUDOWIRE_NODE, + .parent_node = LDP_L2VPN_NODE, + .prompt = "%s(config-l2vpn-pw)# ", +}; -static struct cmd_node keychain_node = {KEYCHAIN_NODE, "%s(config-keychain)# "}; +static struct cmd_node keychain_node = { + .name = "keychain", + .node = KEYCHAIN_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-keychain)# ", +}; -static struct cmd_node keychain_key_node = {KEYCHAIN_KEY_NODE, - "%s(config-keychain-key)# "}; +static struct cmd_node keychain_key_node = { + .name = "keychain key", + .node = KEYCHAIN_KEY_NODE, + .parent_node = KEYCHAIN_NODE, + .prompt = "%s(config-keychain-key)# ", +}; struct cmd_node link_params_node = { - LINK_PARAMS_NODE, "%s(config-link-params)# ", + .name = "link-params", + .node = LINK_PARAMS_NODE, + .parent_node = INTERFACE_NODE, + .prompt = "%s(config-link-params)# ", }; -static struct cmd_node rpki_node = {RPKI_NODE, "%s(config-rpki)# ", 1}; +static struct cmd_node rpki_node = { + .name = "rpki", + .node = RPKI_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-rpki)# ", +}; #if HAVE_BFDD > 0 static struct cmd_node bfd_node = { - BFD_NODE, - "%s(config-bfd)# ", + .name = "bfd", + .node = BFD_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-bfd)# ", }; static struct cmd_node bfd_peer_node = { - BFD_PEER_NODE, - "%s(config-bfd-peer)# ", + .name = "bfd peer", + .node = BFD_PEER_NODE, + .parent_node = BFD_NODE, + .prompt = "%s(config-bfd-peer)# ", }; #endif /* HAVE_BFDD */ @@ -1807,85 +1992,19 @@ DEFUNSH(VTYSH_REALLYALL, vtysh_config_terminal, vtysh_config_terminal_cmd, static int vtysh_exit(struct vty *vty) { - switch (vty->node) { - case VIEW_NODE: - case ENABLE_NODE: + struct cmd_node *cnode = vector_lookup(cmdvec, vty->node); + + if (vty->node == VIEW_NODE || vty->node == ENABLE_NODE) exit(0); - break; - case CONFIG_NODE: - vty->node = ENABLE_NODE; - break; - case INTERFACE_NODE: - case PW_NODE: - case VRF_NODE: - case NH_GROUP_NODE: - case ZEBRA_NODE: - case BGP_NODE: - case RIP_NODE: - case RIPNG_NODE: - case OSPF_NODE: - case OSPF6_NODE: - case EIGRP_NODE: - case BABEL_NODE: - case LDP_NODE: - case LDP_L2VPN_NODE: - case ISIS_NODE: - case OPENFABRIC_NODE: - case RMAP_NODE: - case PBRMAP_NODE: - case VTY_NODE: - case KEYCHAIN_NODE: - case BFD_NODE: - case RPKI_NODE: + if (cnode->node_exit) + cnode->node_exit(vty); + if (cnode->parent_node) + vty->node = cnode->parent_node; + + if (vty->node == CONFIG_NODE) { + /* resync in case one of the daemons is somewhere else */ vtysh_execute("end"); vtysh_execute("configure"); - vty->node = CONFIG_NODE; - break; - case BGP_VPNV4_NODE: - case BGP_VPNV6_NODE: - case BGP_IPV4_NODE: - case BGP_IPV4M_NODE: - case BGP_IPV4L_NODE: - case BGP_IPV6_NODE: - case BGP_IPV6M_NODE: - case BGP_IPV6L_NODE: - case BGP_FLOWSPECV4_NODE: - case BGP_FLOWSPECV6_NODE: - case BGP_VRF_POLICY_NODE: - case BGP_EVPN_NODE: - case BGP_VNC_DEFAULTS_NODE: - case BGP_VNC_NVE_GROUP_NODE: - case BGP_VNC_L2_GROUP_NODE: - case BMP_NODE: - vty->node = BGP_NODE; - break; - case BGP_EVPN_VNI_NODE: - vty->node = BGP_EVPN_NODE; - break; - case LDP_IPV4_NODE: - case LDP_IPV6_NODE: - vty->node = LDP_NODE; - break; - case LDP_IPV4_IFACE_NODE: - vty->node = LDP_IPV4_NODE; - break; - case LDP_IPV6_IFACE_NODE: - vty->node = LDP_IPV6_NODE; - break; - case LDP_PSEUDOWIRE_NODE: - vty->node = LDP_L2VPN_NODE; - break; - case KEYCHAIN_KEY_NODE: - vty->node = KEYCHAIN_NODE; - break; - case LINK_PARAMS_NODE: - vty->node = INTERFACE_NODE; - break; - case BFD_PEER_NODE: - vty->node = BFD_NODE; - break; - default: - break; } return CMD_SUCCESS; } @@ -2710,103 +2829,6 @@ DEFUNSH(VTYSH_ALL, no_vtysh_config_enable_password, return CMD_SUCCESS; } -/* Log filter */ -DEFUN (vtysh_log_filter, - vtysh_log_filter_cmd, - "[no] log-filter WORD ["DAEMONS_LIST"]", - NO_STR - FILTER_LOG_STR - "String to filter by\n" - DAEMONS_STR) -{ - char *filter = NULL; - char *daemon = NULL; - int found = 0; - int idx = 0; - int daemon_idx = 2; - int total_len = 0; - int len = 0; - - char line[ZLOG_FILTER_LENGTH_MAX + 20]; - - found = argv_find(argv, argc, "no", &idx); - if (found == 1) { - len = snprintf(line, sizeof(line), "no log-filter"); - daemon_idx += 1; - } else - len = snprintf(line, sizeof(line), "log-filter"); - - total_len += len; - - idx = 1; - found = argv_find(argv, argc, "WORD", &idx); - if (found != 1) { - vty_out(vty, "%% No filter string given\n"); - return CMD_WARNING; - } - filter = argv[idx]->arg; - - if (strnlen(filter, ZLOG_FILTER_LENGTH_MAX + 1) - > ZLOG_FILTER_LENGTH_MAX) { - vty_out(vty, "%% Filter is too long\n"); - return CMD_WARNING; - } - - len = snprintf(line + total_len, sizeof(line) - total_len, " %s\n", - filter); - - if ((len < 0) || (size_t)(total_len + len) > sizeof(line)) { - vty_out(vty, "%% Error buffering filter to daemons\n"); - return CMD_ERR_INCOMPLETE; - } - - if (argc >= (daemon_idx + 1)) - daemon = argv[daemon_idx]->text; - - if (daemon != NULL) { - vty_out(vty, "Applying log filter change to %s:\n", daemon); - return vtysh_client_execute_name(daemon, line); - } else - return show_per_daemon(line, - "Applying log filter change to %s:\n"); -} - -/* Clear log filters */ -DEFUN (vtysh_log_filter_clear, - vtysh_log_filter_clear_cmd, - "log-filter clear ["DAEMONS_LIST"]", - FILTER_LOG_STR - CLEAR_STR - DAEMONS_STR) -{ - char *daemon = NULL; - int daemon_idx = 2; - - char line[] = "clear log-filter\n"; - - if (argc >= (daemon_idx + 1)) - daemon = argv[daemon_idx]->text; - - if (daemon != NULL) { - vty_out(vty, "Clearing all filters applied to %s:\n", daemon); - return vtysh_client_execute_name(daemon, line); - } else - return show_per_daemon(line, - "Clearing all filters applied to %s:\n"); -} - -/* Show log filter */ -DEFUN (vtysh_show_log_filter, - vtysh_show_log_filter_cmd, - "show log-filter", - SHOW_STR - FILTER_LOG_STR) -{ - char line[] = "do show log-filter\n"; - - return show_per_daemon(line, "Log filters applied to %s:\n"); -} - DEFUN (vtysh_write_terminal, vtysh_write_terminal_cmd, "write terminal ["DAEMONS_LIST"]", @@ -3429,7 +3451,7 @@ DEFUN(find, if (regexec(&exp, cli->string, 0, NULL, 0) == 0) vty_out(vty, " (%s) %s\n", - node_names[node->node], cli->string); + node->name, cli->string); } } @@ -3728,54 +3750,54 @@ void vtysh_init_vty(void) cmd_variable_handler_register(vtysh_var_handler); /* Install nodes. */ - install_node(&bgp_node, NULL); - install_node(&rip_node, NULL); - install_node(&interface_node, NULL); - install_node(&pw_node, NULL); - install_node(&link_params_node, NULL); - install_node(&vrf_node, NULL); - install_node(&nh_group_node, NULL); - install_node(&rmap_node, NULL); - install_node(&pbr_map_node, NULL); - install_node(&zebra_node, NULL); - install_node(&bgp_vpnv4_node, NULL); - install_node(&bgp_vpnv6_node, NULL); - install_node(&bgp_flowspecv4_node, NULL); - install_node(&bgp_flowspecv6_node, NULL); - install_node(&bgp_ipv4_node, NULL); - install_node(&bgp_ipv4m_node, NULL); - install_node(&bgp_ipv4l_node, NULL); - install_node(&bgp_ipv6_node, NULL); - install_node(&bgp_ipv6m_node, NULL); - install_node(&bgp_ipv6l_node, NULL); - install_node(&bgp_vrf_policy_node, NULL); - install_node(&bgp_evpn_node, NULL); - install_node(&bgp_evpn_vni_node, NULL); - install_node(&bgp_vnc_defaults_node, NULL); - install_node(&bgp_vnc_nve_group_node, NULL); - install_node(&bgp_vnc_l2_group_node, NULL); - install_node(&ospf_node, NULL); - install_node(&eigrp_node, NULL); - install_node(&babel_node, NULL); - install_node(&ripng_node, NULL); - install_node(&ospf6_node, NULL); - install_node(&ldp_node, NULL); - install_node(&ldp_ipv4_node, NULL); - install_node(&ldp_ipv6_node, NULL); - install_node(&ldp_ipv4_iface_node, NULL); - install_node(&ldp_ipv6_iface_node, NULL); - install_node(&ldp_l2vpn_node, NULL); - install_node(&ldp_pseudowire_node, NULL); - install_node(&keychain_node, NULL); - install_node(&keychain_key_node, NULL); - install_node(&isis_node, NULL); - install_node(&openfabric_node, NULL); - install_node(&vty_node, NULL); - install_node(&rpki_node, NULL); - install_node(&bmp_node, NULL); + install_node(&bgp_node); + install_node(&rip_node); + install_node(&interface_node); + install_node(&pw_node); + install_node(&link_params_node); + install_node(&vrf_node); + install_node(&nh_group_node); + install_node(&rmap_node); + install_node(&pbr_map_node); + install_node(&zebra_node); + install_node(&bgp_vpnv4_node); + install_node(&bgp_vpnv6_node); + install_node(&bgp_flowspecv4_node); + install_node(&bgp_flowspecv6_node); + install_node(&bgp_ipv4_node); + install_node(&bgp_ipv4m_node); + install_node(&bgp_ipv4l_node); + install_node(&bgp_ipv6_node); + install_node(&bgp_ipv6m_node); + install_node(&bgp_ipv6l_node); + install_node(&bgp_vrf_policy_node); + install_node(&bgp_evpn_node); + install_node(&bgp_evpn_vni_node); + install_node(&bgp_vnc_defaults_node); + install_node(&bgp_vnc_nve_group_node); + install_node(&bgp_vnc_l2_group_node); + install_node(&ospf_node); + install_node(&eigrp_node); + install_node(&babel_node); + install_node(&ripng_node); + install_node(&ospf6_node); + install_node(&ldp_node); + install_node(&ldp_ipv4_node); + install_node(&ldp_ipv6_node); + install_node(&ldp_ipv4_iface_node); + install_node(&ldp_ipv6_iface_node); + install_node(&ldp_l2vpn_node); + install_node(&ldp_pseudowire_node); + install_node(&keychain_node); + install_node(&keychain_key_node); + install_node(&isis_node); + install_node(&openfabric_node); + install_node(&vty_node); + install_node(&rpki_node); + install_node(&bmp_node); #if HAVE_BFDD > 0 - install_node(&bfd_node, NULL); - install_node(&bfd_peer_node, NULL); + install_node(&bfd_node); + install_node(&bfd_peer_node); #endif /* HAVE_BFDD */ struct cmd_node *node; @@ -4106,9 +4128,6 @@ void vtysh_init_vty(void) /* Logging */ install_element(VIEW_NODE, &vtysh_show_logging_cmd); - install_element(VIEW_NODE, &vtysh_show_log_filter_cmd); - install_element(CONFIG_NODE, &vtysh_log_filter_cmd); - install_element(CONFIG_NODE, &vtysh_log_filter_clear_cmd); install_element(CONFIG_NODE, &vtysh_log_stdout_cmd); install_element(CONFIG_NODE, &vtysh_log_stdout_level_cmd); install_element(CONFIG_NODE, &no_vtysh_log_stdout_cmd); diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 9b1f0208e0..abbb111f9d 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -543,7 +543,8 @@ void vtysh_config_write(void) } if (cmd_domainname_get()) { - sprintf(line, "domainname %s", cmd_domainname_get()); + snprintf(line, sizeof(line), "domainname %s", + cmd_domainname_get()); vtysh_config_parse_line(NULL, line); } if (vtysh_write_integrated == WRITE_INTEGRATED_NO) diff --git a/vtysh/vtysh_user.c b/vtysh/vtysh_user.c index a7067984c4..665e6ca90d 100644 --- a/vtysh/vtysh_user.c +++ b/vtysh/vtysh_user.c @@ -115,7 +115,8 @@ void user_config_write(void) for (ALL_LIST_ELEMENTS(userlist, node, nnode, user)) { if (user->nopassword) { - sprintf(line, "username %s nopassword", user->name); + snprintf(line, sizeof(line), "username %s nopassword", + user->name); config_add_line(config_top, line); } } diff --git a/watchfrr/subdir.am b/watchfrr/subdir.am index 36af57cf82..677f85efcb 100644 --- a/watchfrr/subdir.am +++ b/watchfrr/subdir.am @@ -4,7 +4,7 @@ if WATCHFRR sbin_PROGRAMS += watchfrr/watchfrr -vtysh_scan += $(top_srcdir)/watchfrr/watchfrr_vty.c +vtysh_scan += watchfrr/watchfrr_vty.c man8 += $(MANBUILD)/frr-watchfrr.8 endif @@ -20,5 +20,6 @@ watchfrr_watchfrr_SOURCES = \ watchfrr/watchfrr_vty.c \ # end -watchfrr/watchfrr_vty_clippy.c: $(CLIPPY_DEPS) -watchfrr/watchfrr_vty.$(OBJEXT): watchfrr/watchfrr_vty_clippy.c +clippy_scan += \ + watchfrr/watchfrr_vty.c \ + # end diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index 05e6651229..2db612adca 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -27,6 +27,8 @@ #include "command.h" #include "libfrr.h" #include "lib_errors.h" +#include "zlog_targets.h" +#include "network.h" #include <getopt.h> #include <sys/un.h> @@ -42,7 +44,7 @@ #endif /* Macros to help randomize timers. */ -#define JITTER(X) ((random() % ((X)+1))-((X)/2)) +#define JITTER(X) ((frr_weak_random() % ((X)+1))-((X)/2)) #define FUZZY(X) ((X)+JITTER((X)/20)) #define DEFAULT_PERIOD 5 @@ -1369,11 +1371,10 @@ int main(int argc, char **argv) frr_config_fork(); - zlog_set_level(ZLOG_DEST_MONITOR, ZLOG_DISABLED); if (watchfrr_di.daemon_mode) - zlog_set_level(ZLOG_DEST_SYSLOG, MIN(gs.loglevel, LOG_DEBUG)); + zlog_syslog_set_prio_min(MIN(gs.loglevel, LOG_DEBUG)); else - zlog_set_level(ZLOG_DEST_STDOUT, MIN(gs.loglevel, LOG_DEBUG)); + zlog_aux_init(NULL, MIN(gs.loglevel, LOG_DEBUG)); frr_run(master); diff --git a/watchfrr/watchfrr_vty.c b/watchfrr/watchfrr_vty.c index c06cb89382..eda4f5d516 100644 --- a/watchfrr/watchfrr_vty.c +++ b/watchfrr/watchfrr_vty.c @@ -23,6 +23,7 @@ #include "memory.h" #include "log.h" +#include "log_vty.h" #include "vty.h" #include "command.h" @@ -134,6 +135,19 @@ DEFUN (show_watchfrr, return CMD_SUCCESS; } +/* we don't have the other logging commands since watchfrr only accepts + * log config through command line options + */ +DEFUN_NOSH (show_logging, + show_logging_cmd, + "show logging", + SHOW_STR + "Show current logging configuration\n") +{ + log_show_syslog(vty); + return CMD_SUCCESS; +} + #ifndef VTYSH_EXTRACT_PL #include "watchfrr/watchfrr_vty_clippy.c" #endif @@ -190,4 +204,5 @@ void watchfrr_vty_init(void) install_element(CONFIG_NODE, &show_debugging_watchfrr_cmd); install_element(VIEW_NODE, &show_watchfrr_cmd); + install_element(VIEW_NODE, &show_logging_cmd); } diff --git a/yang/frr-igmp.yang b/yang/frr-igmp.yang new file mode 100644 index 0000000000..534fd78480 --- /dev/null +++ b/yang/frr-igmp.yang @@ -0,0 +1,147 @@ +module frr-igmp { + yang-version "1.1"; + namespace "http://frrouting.org/yang/igmp"; + + prefix frr-igmp; + + import frr-routing { + prefix "frr-rt"; + } + + import ietf-routing-types { + prefix "rt-types"; + } + + import ietf-inet-types { + prefix "inet"; + } + + import frr-interface { + prefix frr-interface; + } + + organization + "FRRouting"; + + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + + description + "This module defines a model for managing FRR pimd daemon."; + + revision 2019-11-06 { + description + "Initial revision."; + reference + "RFC 2236: IGMP v2. + RFC 3376: IGMP v3."; + } + + grouping interface-config-attributes { + description + "Configuration attributes applied to the interface level."; + + leaf igmp-enable { + type boolean; + default "false"; + description + "Enable IGMP protocol on the interface."; + } + + leaf version { + type uint8 { + range "2..3"; + } + default "3"; + description + "IGMP version."; + } + + leaf query-interval { + type uint16 { + range "1..1800"; + } + units seconds; + default "125"; + description + "The Query Interval is the interval between General Queries + sent by the Querier."; + } + + leaf query-max-response-time { + type uint8 { + range "10..250"; + } + units deciseconds; + default "100"; + description + "Query maximum response time specifies the maximum time + allowed before sending a responding report."; + } + + leaf last-member-query-interval { + type uint8 { + range "1..255"; + } + units deciseconds; + default "10"; + description + "Last Member Query Interval, which may be tuned to modify + the leave latency of the network."; + } + + leaf robustness-variable { + type uint8 { + range "1..7"; + } + default "2"; + description + "Querier's Robustness Variable allows tuning for the + expected packet loss on a network."; + } + } + + grouping per-af-interface-config-attributes { + description + "Configuration attributes applied to the interface level per address family."; + + list static-group { + key "group-addr source-addr"; + description + "A static multicast route, (*,G) or (S,G). + The version of IGMP must be 3 to support (S,G)."; + + leaf group-addr { + type rt-types:ip-multicast-group-address; + description + "Multicast group address."; + } + leaf source-addr { + type inet:ip-address; + description + "Multicast source address."; + } + } + + } // per-af-interface-config-attributes + + /* + * Per-interface configuration data + */ + augment "/frr-interface:lib/frr-interface:interface" { + container igmp { + description + "IGMP interface parameters."; + uses interface-config-attributes; + list address-family { + key "address-family"; + description + "Each list entry for one address family."; + uses frr-rt:address-family; + uses per-af-interface-config-attributes; + + } //address-family + } + } +} diff --git a/yang/frr-interface.yang b/yang/frr-interface.yang index 1f3eebb2ab..7ebba935a4 100644 --- a/yang/frr-interface.yang +++ b/yang/frr-interface.yang @@ -3,6 +3,18 @@ module frr-interface { namespace "http://frrouting.org/yang/interface"; prefix frr-interface; + import frr-vrf { + prefix frr-vrf; + } + + import ietf-interfaces { + prefix ietf-if; + } + + import ietf-yang-types { + prefix yang; + } + organization "FRRouting"; contact @@ -11,6 +23,10 @@ module frr-interface { description "This module defines a model for managing FRR interfaces."; + revision 2020-02-05 { + description + "Added operational data"; + } revision 2019-09-09 { description "Added interface-ref typedef"; @@ -20,12 +36,236 @@ module frr-interface { "Initial revision."; } + identity other { + base ietf-if:interface-type; + description + "Other type"; + } + + identity unknown { + base ietf-if:interface-type; + description + "Unknown type"; + } + + identity ethernet { + base ietf-if:interface-type; + description + "Ethernet type"; + } + + identity exper-ethernet { + base ietf-if:interface-type; + description + "Experimental Ethernet type"; + } + + identity loopback { + base ietf-if:interface-type; + description + "Loopback type"; + } + + identity pimreg { + base ietf-if:interface-type; + description + "PIMSM Registration."; + } + + identity ipip { + base ietf-if:interface-type; + description + "IPIP Tunnel."; + } + + identity ipip6 { + base ietf-if:interface-type; + description + "IPIP6 Tunnel."; + } + + identity ipgre { + base ietf-if:interface-type; + description + "GRE over IP."; + } + + typedef interface-ref { + type leafref { + path "/frr-interface:lib/frr-interface:interface/frr-interface:name"; + require-instance false; + } + description + "Reference to an interface"; + } + + typedef if-flags-type { + type enumeration { + enum "up" { + value 1; + description + "Active and ready to transfer packets."; + } + enum "broadcast" { + value 2; + description + "Broadcast enabled."; + } + enum "debug" { + value 3; + description + "Debug mode."; + } + enum "loopback" { + value 4; + description + "Loopback interface."; + } + enum "point-to-point" { + value 5; + description + "Point-to-Point link."; + } + enum "notrailers" { + value 6; + description + "This flag is unused in Linux, but it exists for BSD compatibility. + Avoid use of trailers"; + } + enum "running" { + value 7; + description + "Up and Running."; + } + enum "noarp" { + value 8; + description + "Can't perform address resolution protocol."; + } + enum "promisc" { + value 9; + description + "Promiscuous mode. Receive all packets."; + } + enum "allmulti" { + value 10; + description + "Receive all multicast packets."; + } + enum "simplex" { + value 11; + description + "Does not Rx or Tx at the sametime."; + } + enum "link0" { + value 12; + description + "Link0."; + } + enum "link1" { + value 13; + description + "Link1."; + } + enum "link2" { + value 14; + description + "Link2."; + } + enum "multicast" { + value 15; + description + "Supports multicast transmission."; + } + enum "notransmit" { + value 16; + description + "Interface is no transmit mode."; + } + enum "nortexch" { + value 17; + description + "No routing info exchange."; + } + enum "virtual" { + value 18; + description + "Virtual interface."; + } + enum "ipv4" { + value 19; + description + "IPv4 enabled."; + } + enum "ipv6" { + value 20; + description + "IPv6 enabled."; + } + } + } + + grouping if-common-operational { + leaf if-index { + type int32 { + range "0..2147483647"; + } + description + "Interface index."; + } + + leaf mtu { + type uint16; + description + "The size of the largest IPV4 packet that the interface + will send and receive."; + } + + leaf mtu6 { + type uint32; + description + "The size of the largest IPV6 packet that the interface + will send and receive."; + } + + leaf speed { + type uint32; + description + "Interface speed."; + } + + leaf metric { + type uint32; + description + "Interface metric."; + } + + leaf flags { + type if-flags-type; + description + "Interface flags."; + } + + leaf type { + type identityref { + base ietf-if:interface-type; + } + description + "The link type of the interface."; + } + + leaf phy-address { + type yang:mac-address; + description + "The interface's MAC address."; + } + } + container lib { list interface { key "name vrf"; description "Interface."; - leaf name { type string { length "1..16"; @@ -33,27 +273,27 @@ module frr-interface { description "Interface name."; } + leaf vrf { type string { - length "1..36"; + length "1..16"; } + /* yang version 0.16 having issue accessing leafref. */ + /* type frr-vrf:vrf-ref;*/ description "VRF this interface is associated with."; } + leaf description { type string; description "Interface description."; } - } - } - typedef interface-ref { - type leafref { - require-instance false; - path "/frr-interface:lib/frr-interface:interface/frr-interface:name"; + container state { + config false; + uses if-common-operational; + } } - description - "Reference to an interface"; } } diff --git a/yang/frr-nexthop.yang b/yang/frr-nexthop.yang index 3657ecbd75..07e15eb774 100644 --- a/yang/frr-nexthop.yang +++ b/yang/frr-nexthop.yang @@ -10,10 +10,15 @@ module frr-nexthop { import ietf-routing-types { prefix rt-types; } + import frr-interface { prefix frr-interface; } + import frr-vrf { + prefix frr-vrf; + } + organization "FRRouting"; contact @@ -27,10 +32,18 @@ module frr-nexthop { "Initial revision."; } - typedef gateway-address { - type inet:ip-address; + typedef optional-ip-address { + type union { + type inet:ip-address; + type string { + pattern ''; + } + } } + /* + * Nexthop types. + */ typedef nexthop-type { type enumeration { enum "ifindex" { @@ -68,6 +81,9 @@ module frr-nexthop { "Nexthop types."; } + /* + * Blockhole nexthop type. + */ typedef blackhole-type { type enumeration { enum "unspec" { @@ -97,113 +113,148 @@ module frr-nexthop { } /* - * Nexthop object + * Common nexthop attributes grouping. */ - - grouping frr-nexthop { + grouping frr-nexthop-attributes { leaf nh-type { type nexthop-type; mandatory true; description "The nexthop type."; } - - leaf gateway { - type gateway-address; - description - "The nexthop gateway address."; - } - leaf vrf { - type string { - length "1..36"; - } + type frr-vrf:vrf-ref; description "The nexthop vrf name, if different from the route."; } - + leaf gateway { + type frr-nexthop:optional-ip-address; + description + "The nexthop gateway address."; + } leaf interface { type frr-interface:interface-ref; description "The nexthop egress interface."; } - leaf bh-type { + when "../nh-type = 'blackhole'"; type blackhole-type; description "A blackhole sub-type, if the nexthop is a blackhole type."; } - - leaf flags { - type uint32; + leaf onlink { + when "../nh-type = 'ip4-ifindex' or + ../nh-type = 'ip6-ifindex'"; + type boolean; + default "false"; description - "The nexthop's raw flags value."; + "Nexthop is directly connected."; } - leaf is-duplicate { - type empty; + uses rt-types:mpls-label-stack { description - "Duplicate nexthop; will be ignored."; + "Nexthop's MPLS label stack."; } + } - leaf is-recursive { + /* + * operational common attributes for nexthop + */ + grouping frr-nexthop-operational { + leaf duplicate { type empty; + config false; description - "Nexthop must be resolved through another gateway."; + "Duplicate nexthop"; } - leaf is-onlink { + leaf recursive { type empty; + config false; description - "Nexthop is directly connected."; + "Nexthop resolved through another gateway."; } - leaf is-active { + leaf active { type empty; + config false; description "Nexthop is active."; } - uses rt-types:mpls-label-stack { + leaf fib { + type empty; + config false; description - "Nexthop's MPLS label stack."; + "Nexthop is installed in fib."; } - leaf mtu { - type uint32; + leaf weight { + type uint8; + config false; description - "The nexthop's specific MTU."; + "Weight to be used by the nexthop for purposes of ECMP"; } } - // End of nexthop /* - * Nexthop-group container + * Single nexthop grouping. */ - - grouping frr-nexthop-group { - description - "A nexthop-group, represented as a list of nexthop objects."; - leaf name { - type string; + grouping frr-nexthop { + container frr-nexthops { description - "The nexthop-group name."; + "FRR nexthop object."; + list nexthop { + key "nh-type gateway interface"; + description + "A list of nexthop objects."; + uses frr-nexthop-attributes; + } } + } + - list entry { - key "id"; + /* + * Container for FRR nexthop group. + */ + grouping frr-nexthop-grouping { + list nexthop-group { + key "name"; description - "A list of nexthop objects."; - leaf id { - type uint32; + "A group of nexthops."; + + leaf name { + type string; description - "Identifies a nexthop within a nexthop group; the entries - are ordered by id value, and the value has no other meaning."; + "The nexthop-group name."; } uses frr-nexthop; } } - // End of frr-nexthop-group + container frr-nexthop-group { + description + "A nexthop-group, represented as a list of nexthop objects."; + uses frr-nexthop-grouping; + } + + typedef nexthop-group-ref { + type leafref { + require-instance false; + path "/frr-nexthop:frr-nexthop-group/frr-nexthop:nexthop-group/frr-nexthop:name"; + } + } + + /* + * Augment weight attributes to nexthop group. + */ + augment "/frr-nexthop-group/nexthop-group/frr-nexthops/nexthop" { + leaf weight { + type uint8; + description + "Weight to be used by the nexthop for purposes of ECMP"; + } + } } diff --git a/yang/frr-pim-rp.yang b/yang/frr-pim-rp.yang new file mode 100644 index 0000000000..fb0a5aa209 --- /dev/null +++ b/yang/frr-pim-rp.yang @@ -0,0 +1,133 @@ +module frr-pim-rp { + yang-version "1.1"; + namespace "http://frrouting.org/yang/pim-rp"; + + prefix frr-pim-rp; + + import ietf-inet-types { + prefix "inet"; + } + + import ietf-routing-types { + prefix "rt-types"; + } + + import frr-routing { + prefix "frr-rt"; + } + + import frr-pim { + prefix "frr-pim"; + } + + organization + "FRRouting"; + + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + + description + "The module defines a collection of YANG definitions common for + all PIM (Protocol Independent Multicast) RP (Rendezvous Point) model."; + + revision 2017-03-09 { + description + "Initial revision."; + reference + "RFC XXXX: A YANG Data Model for PIM RP"; + } + + typedef ipv4-multicast-group-address-prefix { + type inet:ipv4-prefix{ + pattern '(2((2[4-9])|(3[0-9]))\.)(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(/(([4-9])|([1-2][0-9])|(3[0-2])))'; + } + description + "This type represents an IPv4 multicast group prefix, + which is in the range from 224.0.0.0 to 239.255.255.255."; + } + + typedef ipv6-multicast-group-address-prefix { + type inet:ipv6-prefix { + pattern + '(((FF|ff)[0-9a-fA-F]{2}):)([0-9a-fA-F]{0,4}:){0,5}((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))(/((1[6-9])|([2-9][0-9])|(1[0-1][0-9])|(12[0-8])))'; + pattern + '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)(/.+)'; + } + description + "This type represents an IPv6 multicast group prefix, + which is in the range of FF00::/8."; + } + + typedef ip-multicast-group-address-prefix { + description "The IP-Multicast-Group-Address-Prefix type represents an IP multicast address + prefix and is IP version neutral. The format of the textual representations implies the IP + version. It includes a prefix-length, separated by a '/' sign."; + type union { + type ipv4-multicast-group-address-prefix; + type ipv6-multicast-group-address-prefix; + } + } // typedef ip-multicast-group-address-prefix + + typedef plist-ref { + type string; + } + + /* + * Groupings + */ + grouping static-rp-container { + description + "Grouping of static RP container."; + + container static-rp { + description + "Containing static RP attributes."; + + list rp-list { + key "rp-address"; + description + "A list of RP addresses."; + + leaf rp-address { + type inet:ip-address; + description + "Specifies a static RP address."; + } + + choice group-list-or-prefix-list { + description "Use group-list or prefix-list"; + case group-list { + leaf-list group-list{ + type ip-multicast-group-address-prefix; + description + "List of multicast group address."; + } + } + case prefix-list { + leaf prefix-list { + type plist-ref; + description + "Group prefix-list filter"; + } + } + } + } + } // static-rp + } // static-rp-container + + /* + * Configuration data nodes + */ + augment "/frr-rt:routing/frr-rt:control-plane-protocols/" + + "frr-rt:control-plane-protocol/frr-pim:pim/" + + "frr-pim:address-family" { + description "PIM RP augmentation."; + + container rp { + description + "PIM RP configuration data."; + uses static-rp-container; + } // rp + } // augment +} diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang new file mode 100644 index 0000000000..3b2ebdf6d3 --- /dev/null +++ b/yang/frr-pim.yang @@ -0,0 +1,446 @@ +module frr-pim { + yang-version "1.1"; + namespace "http://frrouting.org/yang/pim"; + + prefix frr-pim; + + import frr-interface { + prefix frr-interface; + } + + import frr-routing { + prefix "frr-rt"; + } + + import ietf-routing-types { + prefix "rt-types"; + } + + import ietf-inet-types { + prefix "inet"; + } + + organization + "FRRouting"; + + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + + description + "The module defines a collection of YANG definitions common for + PIM (Protocol Independent Multicast) model."; + + revision 2017-03-09 { + description + "Initial revision."; + reference + "RFC XXXX: A YANG Data Model for PIM"; + } + + identity pimd { + base frr-rt:routing-protocol; + description + "'Pim' routing pseudo-protocol."; + } + + typedef plist-ref { + type string; + } + + /* + * Groupings + */ + + grouping global-pim-config-attributes { + description + "A grouping defining pim global attributes."; + + leaf ecmp { + type empty; + description + "Enable PIM ECMP."; + } + + leaf ecmp-rebalance { + type empty; + description + "Enable PIM ECMP Rebalance."; + } + + leaf join-prune-interval { + type uint16 { + range "60..600"; + } + default "60"; + description + "Join Prune Send Interval in seconds."; + } + + leaf keep-alive-timer { + type uint16 { + range "31..60000"; + } + default "210"; + description + "Keep alive Timer in seconds."; + } + + leaf rp-keep-alive-timer { + type uint16 { + range "31..60000"; + } + default "210"; + description + "RP keep alive Timer in seconds."; + } + + leaf packets { + type uint8 { + range "1..100"; + } + default "3"; + description + "Number of packets to process at one time per fd."; + } + + leaf register-suppress-time { + type uint16 { + range "5..60000"; + } + default "60"; + description + "Register Suppress Timer."; + } + } + + grouping per-af-global-pim-config-attributes { + description + "A grouping defining per address family pim global attributes"; + + leaf send-v6-secondary { + when "../frr-pim:address-family = 'frr-rt:ipv4'" { + description + "Only applicable to IPv4 address family."; + } + type empty; + description + "Send v6 secondary addresses."; + } + + container spt-switchover { + description + "SPT-Switchover."; + + leaf spt-action { + type enumeration { + enum "PIM_SPT_IMMEDIATE" { + value 0; + description + "Immediate switch to SPT Tree."; + } + enum "PIM_SPT_INFINITY" { + value 1; + description + "Never switch to SPT Tree."; + } + } + default "PIM_SPT_IMMEDIATE"; + description + "SPT-Switchover action"; + } + + leaf spt-infinity-prefix-list { + when "../spt-action = 'PIM_SPT_INFINITY'" { + description + "This leaf is only valid when the spt action + is PIM_SPT_INFINITY."; + } + type plist-ref; + description + "Prefix-List to control which groups to switch."; + } + } + + leaf ssm-prefix-list { + type plist-ref; + description + "Prefix-list used to define Source-Specific Multicast address range."; + } + + leaf-list ssm-pingd-source-ip { + type inet:ip-address; + description + "Enable ssmpingd operation."; + } + + container msdp-mesh-group { + presence + "Configure MSDP mesh-group."; + + leaf mesh-group-name { + type string; + description + "MSDP mesh group name."; + } + + leaf-list member-ip { + type inet:ip-address; + description + "Peer ip address."; + } + + leaf source-ip { + type inet:ip-address; + description + "Source ip address for the TCP connection."; + } + } + + list msdp-peer { + key "peer-ip"; + description + "Configure MSDP peer."; + + leaf peer-ip { + type inet:ip-address; + description + "MSDP peer IP address."; + } + + leaf source-ip { + type inet:ip-address; + description + "MSDP source IP address."; + } + } + + container mlag { + description + "Multi-chassis link aggregation."; + + leaf peerlink-rif { + type frr-interface:interface-ref; + description + "Outgoing interface name."; + } + + leaf reg-address { + type inet:ip-address; + description + "reg address."; + } + + leaf my-role { + type enumeration { + enum "MLAG_ROLE_NONE" { + value 0; + description + "MLAG role none."; + } + enum "MLAG_ROLE_PRIMARY" { + value 1; + description + "MLAG role primary."; + } + + enum "MLAG_ROLE_SECONDARY" { + value 2; + description + "MLAG role secondary."; + } + } + default "MLAG_ROLE_NONE"; + description + "Mlag role."; + } + + leaf peer-state { + type boolean; + default "false"; + description + "Peer state"; + } + } + + leaf register-accept-list { + type plist-ref; + description + "Only accept registers from a specific source prefix list."; + } + } // per-af-global-pim-config-attributes + + grouping interface-pim-config-attributes { + description + "A grouping defining pim interface attributes."; + + leaf pim-enable { + type empty; + description + "Enable PIM flag on the interface."; + } + + leaf dr-priority { + type uint32 { + range "1..4294967295"; + } + default 1; + description + "DR (Designated Router) priority"; + } + + leaf hello-interval { + type uint16 { + range "1..180"; + } + default "30"; + description + "Hello interval"; + } + + leaf hello-holdtime { + type uint16 { + range "1..180"; + } + description + "Hello holdtime"; + } + + container bfd { + presence + "Enable BFD support on the interface."; + + leaf min-rx-interval { + type uint16 { + range "50..60000"; + } + default "300"; + description + "Required min receive interval"; + } + + leaf min-tx-interval { + type uint16 { + range "50..60000"; + } + default "300"; + description + "Desired min transmit interval"; + } + + leaf detect_mult { + type uint8 { + range "2..255"; + } + default "3"; + description + "Detect Multiplier"; + } + } + + leaf bsm { + type empty; + description + "Enables BSM support on the interface."; + } + + leaf unicast-bsm { + type empty; + description + "Accept/Send unicast BSM on the interface."; + } + + leaf active-active { + type empty; + description + "Mark interface as Active-Active for MLAG operations."; + } + } // interface-pim-config-attributes + + grouping per-af-interface-pim-config-attributes { + description + "A grouping defining pim interface attributes per address family."; + + leaf use-source { + type inet:ip-address; + description + "Primary address of the interface set by user."; + } + + leaf multicast-boundary-oil { + type plist-ref; + description + "Prefix-List to define multicast boundary"; + } + + list mroute { + key "source-addr group-addr"; + description + "Add multicast route."; + + leaf oif { + type frr-interface:interface-ref; + description + "Outgoing interface name."; + } + + leaf source-addr { + type inet:ip-address; + description + "Multicast source address."; + } + + leaf group-addr { + type rt-types:ip-multicast-group-address; + description + "Multicast group address."; + } + } + } // per-af-interface-pim-config-attributes + + /* + * Global Configuration data nodes + */ + augment "/frr-rt:routing/frr-rt:control-plane-protocols/" + + "frr-rt:control-plane-protocol" { + container pim { + when "../frr-rt:type = 'frr-pim:pimd'" { + description + "This container is only valid for the 'pim' routing + protocol."; + } + description + "PIM configuration data."; + + uses global-pim-config-attributes; + + list address-family { + key "address-family"; + description + "Each list entry for one address family."; + uses frr-rt:address-family; + uses per-af-global-pim-config-attributes; + + } //address-family + } // pim + } // augment + + /* + * Per-interface configuration data + */ + augment "/frr-interface:lib/frr-interface:interface" { + container pim { + description + "PIM interface parameters."; + uses interface-pim-config-attributes; + list address-family { + key "address-family"; + description + "Each list entry for one address family."; + uses frr-rt:address-family; + uses per-af-interface-pim-config-attributes; + } + } + } +} + diff --git a/yang/frr-routing.yang b/yang/frr-routing.yang new file mode 100644 index 0000000000..ff84954aaf --- /dev/null +++ b/yang/frr-routing.yang @@ -0,0 +1,135 @@ +module frr-routing { + yang-version "1.1"; + namespace "http://frrouting.org/yang/routing"; + prefix "rt"; + + import ietf-yang-types { + prefix "yang"; + } + + import frr-vrf { + prefix frr-vrf; + } + + organization + "FRRouting"; + + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + + description + "This YANG module defines essential components for the management + of a routing subsystem."; + + revision 2019-08-15 { + description + "Initial revision."; + } + + /* Identities */ + + identity address-family { + description + "Base identity from which identities describing address + families are derived."; + } + + identity ipv4 { + base address-family; + description + "This identity represents an IPv4 address family."; + } + + identity ipv6 { + base address-family; + description + "This identity represents an IPv6 address family."; + } + + identity control-plane-protocol { + description + "Base identity from which control-plane protocol identities are + derived."; + } + + identity routing-protocol { + base control-plane-protocol; + description + "Identity from which Layer 3 routing protocol identities are + derived."; + } + + /* Type Definitions */ + + typedef administrative-distance { + type uint8 { + range "1..255"; + } + description + "Admin distance associated with the route."; + } + + /* Groupings */ + + grouping address-family { + description + "This grouping provides a leaf identifying an address + family."; + leaf address-family { + type identityref { + base address-family; + } + mandatory true; + description + "Address family."; + } + } + + grouping router-id { + description + "This grouping provides a router ID."; + leaf router-id { + type yang:dotted-quad; + description + "A 32-bit number in the form of a dotted quad that is used by + some routing protocols identifying a router."; + reference + "RFC 2328: OSPF Version 2"; + } + } + + /* Data nodes */ + + container routing { + description + "Configuration parameters for the routing subsystem."; + container control-plane-protocols { + description + "Support for control-plane protocol instances."; + list control-plane-protocol { + key "type name vrf"; + description + "Each entry contains a control-plane protocol instance."; + leaf type { + type identityref { + base control-plane-protocol; + } + description + "Type of the control-plane protocol"; + } + leaf name { + type string; + description + "An arbitrary name of the control-plane protocol + instance."; + } + leaf vrf { + type frr-vrf:vrf-ref; + description + "vrf for control-plane protocol"; + } + } + } + } +} diff --git a/yang/frr-staticd.yang b/yang/frr-staticd.yang new file mode 100644 index 0000000000..ce8d641de1 --- /dev/null +++ b/yang/frr-staticd.yang @@ -0,0 +1,86 @@ +module frr-staticd { + yang-version "1.1"; + namespace "http://frrouting.org/yang/staticd"; + + prefix frr-staticd; + + import frr-routing { + prefix "frr-rt"; + } + + import frr-nexthop { + prefix frr-nexthop; + } + + import ietf-inet-types { + prefix inet; + } + + organization + "FRRouting"; + + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + + description + "This module defines a model for managing FRR staticd information. + This YANG module augments the ietf-routing with additional + nexthop information"; + + revision 2019-12-03 { + description + "Initial revision."; + } + + identity static { + base frr-rt:routing-protocol; + description + "'Static' routing pseudo-protocol."; + } + + augment "/frr-rt:routing/frr-rt:control-plane-protocols/" + + "frr-rt:control-plane-protocol" { + container staticd { + when "../frr-rt:type = 'frr-staticd:static'" { + description + "This container is only valid for the 'static' routing + protocol."; + } + description + "Support for a 'static' pseudo-protocol instance + consists of a list of routes."; + + list prefix-list { + key "destination-prefix"; + description + "List of static IP routes."; + + leaf destination-prefix { + type inet:ip-address; + description + "IP destination prefix."; + } + + leaf distance { + type frr-rt:administrative-distance; + description + "Admin distance associated with this route."; + } + + leaf tag { + type uint32 { + range "1..4294967295"; + } + description + "Route tag"; + } + container frr-staticd-next-hop { + description + "Augment static route configuration 'nexthop-list'."; + uses frr-nexthop:frr-nexthop; + } + } + } + } +} diff --git a/yang/frr-vrf.yang b/yang/frr-vrf.yang new file mode 100644 index 0000000000..4924a86e89 --- /dev/null +++ b/yang/frr-vrf.yang @@ -0,0 +1,60 @@ +module frr-vrf { + yang-version 1.1; + namespace "http://frrouting.org/yang/vrf"; + prefix frr-vrf; + + organization + "Free Range Routing"; + contact + "FRR Users List: <mailto:frog@lists.frrouting.org> + FRR Development List: <mailto:dev@lists.frrouting.org>"; + description + "This module defines a model for managing FRR VRF."; + + revision 2019-12-06 { + description + "Initial revision."; + } + + typedef vrf-ref { + type leafref { + path "/frr-vrf:lib/frr-vrf:vrf/frr-vrf:name"; + require-instance false; + } + description + "Reference to a VRF"; + } + + container lib { + list vrf { + key "name"; + description + "VRF."; + leaf name { + type string { + length "1..36"; + } + description + "VRF name."; + } + + container state { + config false; + leaf id { + type uint32 { + range "0..4294967295"; + } + description + "VRF Id."; + } + + leaf active { + type boolean; + default "false"; + description + "VRF active in kernel."; + } + } + } + } +} diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index 736bbc2c81..26e30b5fa9 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -27,10 +27,18 @@ module frr-zebra { prefix frr-nh; } + import frr-routing { + prefix frr-rt; + } + import frr-interface { prefix frr-interface; } + import frr-vrf { + prefix frr-vrf; + } + organization "FRRouting"; contact @@ -44,6 +52,35 @@ module frr-zebra { "Initial revision."; } + identity afi-safi-type { + description + "Base identity type (AFI,SAFI) tuples for RIB"; + } + + identity ipv4-unicast { + base afi-safi-type; + description + "This identity represents the IPv4 unicast address family."; + } + + identity ipv6-unicast { + base afi-safi-type; + description + "This identity represents the IPv6 unicast address family."; + } + + identity ipv4-multicast { + base afi-safi-type; + description + "This identity represents the IPv4 multicast address family."; + } + + identity ipv6-multicast { + base afi-safi-type; + description + "This identity represents the IPv6 multicast address family."; + } + typedef unix-timestamp { type uint32; units "seconds"; @@ -51,6 +88,65 @@ module frr-zebra { "An absolute time in seconds since the unix epoch."; } + identity zebra-interface-type { + description + "zebra interface type."; + } + + identity zif-other { + base zebra-interface-type; + description + "Zebra interface type other."; + } + + identity zif-bridge { + base zebra-interface-type; + description + "Zebra interface type bridge."; + } + + identity zif-vlan { + base zebra-interface-type; + description + "Zebra interface type vlan."; + } + + identity zif-vxlan { + base zebra-interface-type; + description + "Zebra interface type vxlan."; + } + + identity zif-vrf { + base zebra-interface-type; + description + "Zebra interface type vrf."; + } + + identity zif-veth { + base zebra-interface-type; + description + "Zebra interface type veth."; + } + + identity zif-bond { + base zebra-interface-type; + description + "Zebra interface type bond."; + } + + identity zif-bond-slave { + base zebra-interface-type; + description + "Zebra interface type bond slave."; + } + + identity zif-macvlan { + base zebra-interface-type; + description + "Zebra interface type macvlan."; + } + /* * Multicast RPF mode configurable type */ @@ -132,13 +228,6 @@ module frr-zebra { grouping route-common { description "Common information about a route."; - leaf vrf { - type string { - length "1..36"; - } - description - "The route's vrf name."; - } leaf distance { type uint8; @@ -160,25 +249,25 @@ module frr-zebra { "Route tag value."; } - leaf is-selected { + leaf selected { type empty; description "Route is the selected or preferred route for the prefix."; } - leaf is-installed { + leaf installed { type empty; description "Route is installed in the FIB."; } - leaf is-failed { + leaf failed { type empty; description "Route installation in FIB has failed."; } - leaf is-queued { + leaf queued { type empty; description "Route has a pending FIB operation that has not completed."; @@ -197,17 +286,12 @@ module frr-zebra { } leaf uptime { - type uint32; - units "seconds"; + type yang:date-and-time; description "Uptime for the route."; } - container nexthop-group { - description - "Nexthop information for the route."; - uses frr-nh:frr-nexthop-group; - } + uses frr-nh:frr-nexthop-grouping; } // End of route-common @@ -257,6 +341,7 @@ module frr-zebra { uses route-common; } + // End of ip6-route /* * Information about EVPN VNIs @@ -343,7 +428,7 @@ module frr-zebra { "The gateway MAC-IP is being advertised."; } - leaf mcase-group { + leaf mcast-group { type rt-types:ipv4-multicast-group-address; description "The VNI multicast group for BUM traffic."; @@ -442,6 +527,7 @@ module frr-zebra { description "Debug kernel messages sent."; } + leaf debug-kernel-msg-recv { type boolean; description @@ -515,6 +601,58 @@ module frr-zebra { } } + grouping ribs { + container ribs { + description + "RIBs supported by FRR."; + list rib { + key "afi-safi-name table-id"; + leaf table-id { + type uint32; + description + "Routing Table id (default id - 254)."; + } + + leaf afi-safi-name { + type identityref { + base afi-safi-type; + } + mandatory true; + description + "AFI, SAFI name."; + } + + list route { + key "prefix"; + config false; + leaf prefix { + type inet:ip-prefix; + description + "The route's prefix."; + } + list route-entry { + key "protocol"; + leaf protocol { + type frr-route-types:frr-route-types-v4; + //TODO: Use unified route types done in PR 5183 when it is merged. + //type frr-route-types:frr-route-types; + description + "The protocol owning the route."; + } + + leaf instance { + type uint16; + must "../protocol = \"ospf\""; + description + "Retrieve routes from a specific OSPF instance."; + } + uses route-common; + } + } + } + } + } + // End of zebra container /* * RPCs @@ -532,6 +670,7 @@ module frr-zebra { description "Retrieve IPv4 routes."; } + leaf prefix-v4 { type inet:ipv4-prefix; description @@ -605,7 +744,7 @@ module frr-zebra { type uint32 { range "1..65535"; } - must '../protocol = "ospf"'; + must "../protocol = \"ospf\""; description "Retrieve routes from a specific OSPF instance."; } @@ -1790,39 +1929,32 @@ module frr-zebra { description "Extends interface model with Zebra-related parameters."; container zebra { - list ip4-addr-list { - key "ip4-prefix"; + list ip-addrs { + key "address-family ip-prefix"; description - "IPv4 prefixes for an interface."; - leaf ip4-prefix { - type inet:ipv4-prefix; + "IP prefixes for an interface."; + uses frr-rt:address-family { description - "IPv4 address prefix."; + "Address family of the RIB."; } - leaf ip4-peer { - type inet:ipv4-prefix; + + leaf ip-prefix { + type inet:ip-prefix; description - "Peer prefix, for peer-to-peer interfaces."; + "IP address prefix."; } + leaf label { type string; description "Optional string label for the address."; } - } - list ip6-addr-list { - key "ip6-prefix"; - description - "IPv6 prefixes for an interface."; - leaf ip6-prefix { - type inet:ipv6-prefix; - description - "IPv6 address prefix."; - } - leaf label { - type string; + + leaf ip4-peer { + when "derived-from-or-self(../address-family, 'ipv4')"; + type inet:ipv4-prefix; description - "Optional string label for the address."; + "Peer prefix, for peer-to-peer interfaces."; } } @@ -1831,16 +1963,19 @@ module frr-zebra { description "Multicast flag for the interface."; } + leaf link-detect { type boolean; description "Link-detection for the interface."; } + leaf shutdown { type boolean; description "Interface admin status."; } + leaf bandwidth { type uint32 { range "1..100000"; @@ -1849,9 +1984,74 @@ module frr-zebra { "Link bandwidth informational parameter, in megabits."; } // TODO -- link-params for (experimental/partial TE use in IGP extensions) + container state { + config false; + description + "Operational data."; + leaf up-count { + type uint16; + description + "Interface Up count."; + } + + leaf down-count { + type uint16; + description + "Interface Down count."; + } + + leaf zif-type { + type identityref { + base zebra-interface-type; + } + description + "zebra interface type."; + } + + leaf ptm-status { + type string; + default "disabled"; + description + "Interface PTM status."; + } + + leaf vlan-id { + type uint16 { + range "1..4094"; + } + description + "A VLAN id."; + } + + leaf vni-id { + type vni-id-type; + } + + leaf remote-vtep { + type inet:ipv4-address; + description + "The remote VTEP IP address."; + } + + leaf mcast-group { + type rt-types:ipv4-multicast-group-address; + description + "The VNI multicast group for BUM traffic."; + } + } } } + augment "/frr-vrf:lib/frr-vrf:vrf" { + description + "Extends VRF model with Zebra-related parameters."; + uses ribs; + } + + augment "/frr-vrf:lib/frr-vrf:vrf/ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop" { + uses frr-nh:frr-nexthop-operational; + } + /* * Main zebra container */ diff --git a/yang/ietf/ietf-interfaces.yang b/yang/ietf/ietf-interfaces.yang new file mode 100644 index 0000000000..f66c205ce0 --- /dev/null +++ b/yang/ietf/ietf-interfaces.yang @@ -0,0 +1,1123 @@ +module ietf-interfaces { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces"; + prefix if; + + import ietf-yang-types { + prefix yang; + } + + organization + "IETF NETMOD (Network Modeling) Working Group"; + + contact + "WG Web: <https://datatracker.ietf.org/wg/netmod/> + WG List: <mailto:netmod@ietf.org> + + Editor: Martin Bjorklund + <mailto:mbj@tail-f.com>"; + + description + "This module contains a collection of YANG definitions for + managing network interfaces. + + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (https://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC 8343; see + the RFC itself for full legal notices."; + + revision 2018-02-20 { + description + "Updated to support NMDA."; + reference + "RFC 8343: A YANG Data Model for Interface Management"; + } + + revision 2014-05-08 { + description + "Initial revision."; + reference + "RFC 7223: A YANG Data Model for Interface Management"; + } + + /* + * Typedefs + */ + + typedef interface-ref { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + description + "This type is used by data models that need to reference + interfaces."; + } + + /* + * Identities + */ + + identity interface-type { + description + "Base identity from which specific interface types are + derived."; + } + + /* + * Features + */ + + feature arbitrary-names { + description + "This feature indicates that the device allows user-controlled + interfaces to be named arbitrarily."; + } + feature pre-provisioning { + description + "This feature indicates that the device supports + pre-provisioning of interface configuration, i.e., it is + possible to configure an interface whose physical interface + hardware is not present on the device."; + } + feature if-mib { + description + "This feature indicates that the device implements + the IF-MIB."; + reference + "RFC 2863: The Interfaces Group MIB"; + } + + /* + * Data nodes + */ + + container interfaces { + description + "Interface parameters."; + + list interface { + key "name"; + + description + "The list of interfaces on the device. + + The status of an interface is available in this list in the + operational state. If the configuration of a + system-controlled interface cannot be used by the system + (e.g., the interface hardware present does not match the + interface type), then the configuration is not applied to + the system-controlled interface shown in the operational + state. If the configuration of a user-controlled interface + cannot be used by the system, the configured interface is + not instantiated in the operational state. + + System-controlled interfaces created by the system are + always present in this list in the operational state, + whether or not they are configured."; + + leaf name { + type string; + description + "The name of the interface. + + A device MAY restrict the allowed values for this leaf, + possibly depending on the type of the interface. + For system-controlled interfaces, this leaf is the + device-specific name of the interface. + + If a client tries to create configuration for a + system-controlled interface that is not present in the + operational state, the server MAY reject the request if + the implementation does not support pre-provisioning of + interfaces or if the name refers to an interface that can + never exist in the system. A Network Configuration + Protocol (NETCONF) server MUST reply with an rpc-error + with the error-tag 'invalid-value' in this case. + + If the device supports pre-provisioning of interface + configuration, the 'pre-provisioning' feature is + advertised. + + If the device allows arbitrarily named user-controlled + interfaces, the 'arbitrary-names' feature is advertised. + + When a configured user-controlled interface is created by + the system, it is instantiated with the same name in the + operational state. + + A server implementation MAY map this leaf to the ifName + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifName. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 2863: The Interfaces Group MIB - ifName"; + } + + leaf description { + type string; + description + "A textual description of the interface. + + A server implementation MAY map this leaf to the ifAlias + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifAlias. The definition of + such a mechanism is outside the scope of this document. + + Since ifAlias is defined to be stored in non-volatile + storage, the MIB implementation MUST map ifAlias to the + value of 'description' in the persistently stored + configuration."; + reference + "RFC 2863: The Interfaces Group MIB - ifAlias"; + } + + leaf type { + type identityref { + base interface-type; + } + mandatory true; + description + "The type of the interface. + + When an interface entry is created, a server MAY + initialize the type leaf with a valid value, e.g., if it + is possible to derive the type from the name of the + interface. + + If a client tries to set the type of an interface to a + value that can never be used by the system, e.g., if the + type is not supported or if the type does not match the + name of the interface, the server MUST reject the request. + A NETCONF server MUST reply with an rpc-error with the + error-tag 'invalid-value' in this case."; + reference + "RFC 2863: The Interfaces Group MIB - ifType"; + } + + leaf enabled { + type boolean; + default "true"; + description + "This leaf contains the configured, desired state of the + interface. + + Systems that implement the IF-MIB use the value of this + leaf in the intended configuration to set + IF-MIB.ifAdminStatus to 'up' or 'down' after an ifEntry + has been initialized, as described in RFC 2863. + + Changes in this leaf in the intended configuration are + reflected in ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf link-up-down-trap-enable { + if-feature if-mib; + type enumeration { + enum enabled { + value 1; + description + "The device will generate linkUp/linkDown SNMP + notifications for this interface."; + } + enum disabled { + value 2; + description + "The device will not generate linkUp/linkDown SNMP + notifications for this interface."; + } + } + description + "Controls whether linkUp/linkDown SNMP notifications + should be generated for this interface. + + If this node is not configured, the value 'enabled' is + operationally used by the server for interfaces that do + not operate on top of any other interface (i.e., there are + no 'lower-layer-if' entries), and 'disabled' otherwise."; + reference + "RFC 2863: The Interfaces Group MIB - + ifLinkUpDownTrapEnable"; + } + + leaf admin-status { + if-feature if-mib; + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "Not ready to pass packets and not in some test mode."; + } + enum testing { + value 3; + description + "In some test mode."; + } + } + config false; + mandatory true; + description + "The desired state of the interface. + + This leaf has the same read semantics as ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf oper-status { + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + + description + "The interface does not pass any packets."; + } + enum testing { + value 3; + description + "In some test mode. No operational packets can + be passed."; + } + enum unknown { + value 4; + description + "Status cannot be determined for some reason."; + } + enum dormant { + value 5; + description + "Waiting for some external event."; + } + enum not-present { + value 6; + description + "Some component (typically hardware) is missing."; + } + enum lower-layer-down { + value 7; + description + "Down due to state of lower-layer interface(s)."; + } + } + config false; + mandatory true; + description + "The current operational state of the interface. + + This leaf has the same semantics as ifOperStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifOperStatus"; + } + + leaf last-change { + type yang:date-and-time; + config false; + description + "The time the interface entered its current operational + state. If the current state was entered prior to the + last re-initialization of the local network management + subsystem, then this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifLastChange"; + } + + leaf if-index { + if-feature if-mib; + type int32 { + range "1..2147483647"; + } + config false; + mandatory true; + description + "The ifIndex value for the ifEntry represented by this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifIndex"; + } + + leaf phys-address { + type yang:phys-address; + config false; + description + "The interface's address at its protocol sub-layer. For + example, for an 802.x interface, this object normally + contains a Media Access Control (MAC) address. The + interface's media-specific modules must define the bit + and byte ordering and the format of the value of this + object. For interfaces that do not have such an address + (e.g., a serial line), this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifPhysAddress"; + } + + leaf-list higher-layer-if { + type interface-ref; + config false; + description + "A list of references to interfaces layered on top of this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf-list lower-layer-if { + type interface-ref; + config false; + + description + "A list of references to interfaces layered underneath this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf speed { + type yang:gauge64; + units "bits/second"; + config false; + description + "An estimate of the interface's current bandwidth in bits + per second. For interfaces that do not vary in + bandwidth or for those where no accurate estimation can + be made, this node should contain the nominal bandwidth. + For interfaces that have no concept of bandwidth, this + node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - + ifSpeed, ifHighSpeed"; + } + + container statistics { + config false; + description + "A collection of interface-related statistics objects."; + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + description + "The time on the most recent occasion at which any one or + more of this interface's counters suffered a + discontinuity. If no such discontinuities have occurred + since the last re-initialization of the local management + subsystem, then this node contains the time the local + management subsystem re-initialized itself."; + } + + leaf in-octets { + type yang:counter64; + description + "The total number of octets received on the interface, + including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInOctets"; + } + + leaf in-unicast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were not addressed to a + multicast or broadcast address at this sub-layer. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts"; + } + + leaf in-broadcast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a broadcast + address at this sub-layer. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInBroadcastPkts"; + } + + leaf in-multicast-pkts { + type yang:counter64; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a multicast + address at this sub-layer. For a MAC-layer protocol, + this includes both Group and Functional addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInMulticastPkts"; + } + + leaf in-discards { + type yang:counter32; + description + "The number of inbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being deliverable to a higher-layer + protocol. One possible reason for discarding such a + packet could be to free up buffer space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInDiscards"; + } + + leaf in-errors { + type yang:counter32; + description + "For packet-oriented interfaces, the number of inbound + packets that contained errors preventing them from being + deliverable to a higher-layer protocol. For character- + oriented or fixed-length interfaces, the number of + inbound transmission units that contained errors + preventing them from being deliverable to a higher-layer + protocol. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInErrors"; + } + + leaf in-unknown-protos { + type yang:counter32; + + description + "For packet-oriented interfaces, the number of packets + received via the interface that were discarded because + of an unknown or unsupported protocol. For + character-oriented or fixed-length interfaces that + support protocol multiplexing, the number of + transmission units received via the interface that were + discarded because of an unknown or unsupported protocol. + For any interface that does not support protocol + multiplexing, this counter is not present. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos"; + } + + leaf out-octets { + type yang:counter64; + description + "The total number of octets transmitted out of the + interface, including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutOctets"; + } + + leaf out-unicast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were not addressed + to a multicast or broadcast address at this sub-layer, + including those that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts"; + } + + leaf out-broadcast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + broadcast address at this sub-layer, including those + that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutBroadcastPkts"; + } + + leaf out-multicast-pkts { + type yang:counter64; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + multicast address at this sub-layer, including those + that were discarded or not sent. For a MAC-layer + protocol, this includes both Group and Functional + addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutMulticastPkts"; + } + + leaf out-discards { + type yang:counter32; + description + "The number of outbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being transmitted. One possible reason + for discarding such a packet could be to free up buffer + space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutDiscards"; + } + + leaf out-errors { + type yang:counter32; + description + "For packet-oriented interfaces, the number of outbound + packets that could not be transmitted because of errors. + For character-oriented or fixed-length interfaces, the + number of outbound transmission units that could not be + transmitted because of errors. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutErrors"; + } + } + + } + } + + /* + * Legacy typedefs + */ + + typedef interface-state-ref { + type leafref { + path "/if:interfaces-state/if:interface/if:name"; + } + status deprecated; + description + "This type is used by data models that need to reference + the operationally present interfaces."; + } + + /* + * Legacy operational state data nodes + */ + + container interfaces-state { + config false; + status deprecated; + description + "Data nodes for the operational state of interfaces."; + + list interface { + key "name"; + status deprecated; + + description + "The list of interfaces on the device. + + System-controlled interfaces created by the system are + always present in this list, whether or not they are + configured."; + + leaf name { + type string; + status deprecated; + description + "The name of the interface. + + A server implementation MAY map this leaf to the ifName + MIB object. Such an implementation needs to use some + mechanism to handle the differences in size and characters + allowed between this leaf and ifName. The definition of + such a mechanism is outside the scope of this document."; + reference + "RFC 2863: The Interfaces Group MIB - ifName"; + } + + leaf type { + type identityref { + base interface-type; + } + mandatory true; + status deprecated; + description + "The type of the interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifType"; + } + + leaf admin-status { + if-feature if-mib; + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "Not ready to pass packets and not in some test mode."; + } + enum testing { + value 3; + description + "In some test mode."; + } + } + mandatory true; + status deprecated; + description + "The desired state of the interface. + + This leaf has the same read semantics as ifAdminStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifAdminStatus"; + } + + leaf oper-status { + type enumeration { + enum up { + value 1; + description + "Ready to pass packets."; + } + enum down { + value 2; + description + "The interface does not pass any packets."; + } + enum testing { + value 3; + description + "In some test mode. No operational packets can + be passed."; + } + enum unknown { + value 4; + description + "Status cannot be determined for some reason."; + } + enum dormant { + value 5; + description + "Waiting for some external event."; + } + enum not-present { + value 6; + description + "Some component (typically hardware) is missing."; + } + enum lower-layer-down { + value 7; + description + "Down due to state of lower-layer interface(s)."; + } + } + mandatory true; + status deprecated; + description + "The current operational state of the interface. + + This leaf has the same semantics as ifOperStatus."; + reference + "RFC 2863: The Interfaces Group MIB - ifOperStatus"; + } + + leaf last-change { + type yang:date-and-time; + status deprecated; + description + "The time the interface entered its current operational + state. If the current state was entered prior to the + last re-initialization of the local network management + subsystem, then this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifLastChange"; + } + + leaf if-index { + if-feature if-mib; + type int32 { + range "1..2147483647"; + } + mandatory true; + status deprecated; + description + "The ifIndex value for the ifEntry represented by this + interface."; + + reference + "RFC 2863: The Interfaces Group MIB - ifIndex"; + } + + leaf phys-address { + type yang:phys-address; + status deprecated; + description + "The interface's address at its protocol sub-layer. For + example, for an 802.x interface, this object normally + contains a Media Access Control (MAC) address. The + interface's media-specific modules must define the bit + and byte ordering and the format of the value of this + object. For interfaces that do not have such an address + (e.g., a serial line), this node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - ifPhysAddress"; + } + + leaf-list higher-layer-if { + type interface-state-ref; + status deprecated; + description + "A list of references to interfaces layered on top of this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf-list lower-layer-if { + type interface-state-ref; + status deprecated; + description + "A list of references to interfaces layered underneath this + interface."; + reference + "RFC 2863: The Interfaces Group MIB - ifStackTable"; + } + + leaf speed { + type yang:gauge64; + units "bits/second"; + status deprecated; + description + "An estimate of the interface's current bandwidth in bits + per second. For interfaces that do not vary in + bandwidth or for those where no accurate estimation can + + be made, this node should contain the nominal bandwidth. + For interfaces that have no concept of bandwidth, this + node is not present."; + reference + "RFC 2863: The Interfaces Group MIB - + ifSpeed, ifHighSpeed"; + } + + container statistics { + status deprecated; + description + "A collection of interface-related statistics objects."; + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + status deprecated; + description + "The time on the most recent occasion at which any one or + more of this interface's counters suffered a + discontinuity. If no such discontinuities have occurred + since the last re-initialization of the local management + subsystem, then this node contains the time the local + management subsystem re-initialized itself."; + } + + leaf in-octets { + type yang:counter64; + status deprecated; + description + "The total number of octets received on the interface, + including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInOctets"; + } + + leaf in-unicast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were not addressed to a + multicast or broadcast address at this sub-layer. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts"; + } + + leaf in-broadcast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a broadcast + address at this sub-layer. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInBroadcastPkts"; + } + + leaf in-multicast-pkts { + type yang:counter64; + status deprecated; + description + "The number of packets, delivered by this sub-layer to a + higher (sub-)layer, that were addressed to a multicast + address at this sub-layer. For a MAC-layer protocol, + this includes both Group and Functional addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCInMulticastPkts"; + } + + leaf in-discards { + type yang:counter32; + status deprecated; + + description + "The number of inbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being deliverable to a higher-layer + protocol. One possible reason for discarding such a + packet could be to free up buffer space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInDiscards"; + } + + leaf in-errors { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of inbound + packets that contained errors preventing them from being + deliverable to a higher-layer protocol. For character- + oriented or fixed-length interfaces, the number of + inbound transmission units that contained errors + preventing them from being deliverable to a higher-layer + protocol. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInErrors"; + } + + leaf in-unknown-protos { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of packets + received via the interface that were discarded because + of an unknown or unsupported protocol. For + character-oriented or fixed-length interfaces that + support protocol multiplexing, the number of + transmission units received via the interface that were + discarded because of an unknown or unsupported protocol. + For any interface that does not support protocol + multiplexing, this counter is not present. + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos"; + } + + leaf out-octets { + type yang:counter64; + status deprecated; + description + "The total number of octets transmitted out of the + interface, including framing characters. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutOctets"; + } + + leaf out-unicast-pkts { + type yang:counter64; + status deprecated; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were not addressed + to a multicast or broadcast address at this sub-layer, + including those that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts"; + } + + leaf out-broadcast-pkts { + type yang:counter64; + status deprecated; + + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + broadcast address at this sub-layer, including those + that were discarded or not sent. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutBroadcastPkts"; + } + + leaf out-multicast-pkts { + type yang:counter64; + status deprecated; + description + "The total number of packets that higher-level protocols + requested be transmitted and that were addressed to a + multicast address at this sub-layer, including those + that were discarded or not sent. For a MAC-layer + protocol, this includes both Group and Functional + addresses. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - + ifHCOutMulticastPkts"; + } + + leaf out-discards { + type yang:counter32; + status deprecated; + description + "The number of outbound packets that were chosen to be + discarded even though no errors had been detected to + prevent their being transmitted. One possible reason + for discarding such a packet could be to free up buffer + space. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutDiscards"; + } + + leaf out-errors { + type yang:counter32; + status deprecated; + description + "For packet-oriented interfaces, the number of outbound + packets that could not be transmitted because of errors. + For character-oriented or fixed-length interfaces, the + number of outbound transmission units that could not be + transmitted because of errors. + + Discontinuities in the value of this counter can occur + at re-initialization of the management system and at + other times as indicated by the value of + 'discontinuity-time'."; + reference + "RFC 2863: The Interfaces Group MIB - ifOutErrors"; + } + } + } + } +} diff --git a/yang/subdir.am b/yang/subdir.am index 0e124c5ab0..6caf9fc5f3 100644 --- a/yang/subdir.am +++ b/yang/subdir.am @@ -25,9 +25,14 @@ dist_yangmodels_DATA += yang/frr-nexthop.yang dist_yangmodels_DATA += yang/frr-test-module.yang dist_yangmodels_DATA += yang/frr-interface.yang dist_yangmodels_DATA += yang/frr-route-map.yang +dist_yangmodels_DATA += yang/frr-vrf.yang dist_yangmodels_DATA += yang/frr-route-types.yang -dist_yangmodels_DATA += yang/frr-zebra.yang +dist_yangmodels_DATA += yang/frr-routing.yang dist_yangmodels_DATA += yang/ietf/ietf-routing-types.yang +dist_yangmodels_DATA += yang/frr-igmp.yang +dist_yangmodels_DATA += yang/ietf/ietf-interfaces.yang +dist_yangmodels_DATA += yang/frr-pim.yang +dist_yangmodels_DATA += yang/frr-pim-rp.yang if BFDD dist_yangmodels_DATA += yang/frr-bfdd.yang @@ -52,3 +57,11 @@ endif if VRRPD dist_yangmodels_DATA += yang/frr-vrrpd.yang endif + +if STATICD +dist_yangmodels_DATA += yang/frr-staticd.yang +endif + +if ZEBRA +dist_yangmodels_DATA += yang/frr-zebra.yang +endif diff --git a/zebra/debug.c b/zebra/debug.c index 68f6b69305..c920fca5ff 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -471,8 +471,13 @@ DEFPY (debug_zebra_nexthop, } /* Debug node. */ -struct cmd_node debug_node = {DEBUG_NODE, "", /* Debug node has no interface. */ - 1}; +static int config_write_debug(struct vty *vty); +struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = config_write_debug, +}; static int config_write_debug(struct vty *vty) { @@ -587,7 +592,7 @@ void zebra_debug_init(void) zebra_debug_nht = 0; zebra_debug_nexthop = 0; - install_node(&debug_node, config_write_debug); + install_node(&debug_node); install_element(VIEW_NODE, &show_debugging_zebra_cmd); diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index a697a306bf..32b7faaad7 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -19,6 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef HAVE_CONFIG_H +#include "config.h" /* Include this explicitly */ +#endif + #include <arpa/inet.h> #include <sys/types.h> @@ -27,7 +31,6 @@ #include <errno.h> #include <string.h> -#include "config.h" /* Include this explicitly */ #include "lib/zebra.h" #include "lib/json.h" #include "lib/libfrr.h" @@ -368,10 +371,11 @@ static int fpm_write_config(struct vty *vty) return written; } -struct cmd_node fpm_node = { - .node = VTY_NODE, +static struct cmd_node fpm_node = { + .name = "fpm", + .node = FPM_NODE, .prompt = "", - .vtysh = 1, + .config_write = fpm_write_config, }; /* @@ -1026,18 +1030,52 @@ static int fpm_nl_start(struct zebra_dplane_provider *prov) return 0; } -static int fpm_nl_finish(struct zebra_dplane_provider *prov, bool early) +static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc) { - struct fpm_nl_ctx *fnc; + /* Disable all events and close socket. */ + THREAD_OFF(fnc->t_ribreset); + THREAD_OFF(fnc->t_ribwalk); + THREAD_OFF(fnc->t_rmacreset); + THREAD_OFF(fnc->t_rmacwalk); + thread_cancel_async(fnc->fthread->master, &fnc->t_read, NULL); + thread_cancel_async(fnc->fthread->master, &fnc->t_write, NULL); + thread_cancel_async(fnc->fthread->master, &fnc->t_connect, NULL); - fnc = dplane_provider_get_data(prov); + if (fnc->socket != -1) { + close(fnc->socket); + fnc->socket = -1; + } + + return 0; +} + +static int fpm_nl_finish_late(struct fpm_nl_ctx *fnc) +{ + /* Stop the running thread. */ + frr_pthread_stop(fnc->fthread, NULL); + + /* Free all allocated resources. */ + pthread_mutex_destroy(&fnc->obuf_mutex); + pthread_mutex_destroy(&fnc->ctxqueue_mutex); stream_free(fnc->ibuf); stream_free(fnc->obuf); - close(fnc->socket); + free(gfnc); + gfnc = NULL; return 0; } +static int fpm_nl_finish(struct zebra_dplane_provider *prov, bool early) +{ + struct fpm_nl_ctx *fnc; + + fnc = dplane_provider_get_data(prov); + if (early) + return fpm_nl_finish_early(fnc); + + return fpm_nl_finish_late(fnc); +} + static int fpm_nl_process(struct zebra_dplane_provider *prov) { struct zebra_dplane_ctx *ctx; @@ -1103,7 +1141,7 @@ static int fpm_nl_new(struct thread_master *tm) if (IS_ZEBRA_DEBUG_DPLANE) zlog_debug("%s register status: %d", prov_name, rv); - install_node(&fpm_node, fpm_write_config); + install_node(&fpm_node); install_element(ENABLE_NODE, &fpm_show_counters_cmd); install_element(ENABLE_NODE, &fpm_show_counters_json_cmd); install_element(ENABLE_NODE, &fpm_reset_counters_cmd); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 78155b1455..17b6edfed0 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -275,7 +275,7 @@ static void netlink_determine_zebra_iftype(const char *kind, netlink_parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)) static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, - const char *name) + uint32_t ns_id, const char *name) { struct ifinfomsg *ifi; struct rtattr *linkinfo[IFLA_INFO_MAX + 1]; @@ -310,10 +310,22 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, nl_table_id = *(uint32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]); if (h->nlmsg_type == RTM_NEWLINK) { + vrf_id_t exist_id; + if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("RTM_NEWLINK for VRF %s(%u) table %u", name, ifi->ifi_index, nl_table_id); + exist_id = vrf_lookup_by_table(nl_table_id, ns_id); + if (exist_id != VRF_DEFAULT) { + vrf = vrf_lookup_by_id(exist_id); + + flog_err( + EC_ZEBRA_VRF_MISCONFIGURED, + "VRF %s id %u table id overlaps existing vrf %s, misconfiguration exiting", + name, ifi->ifi_index, vrf->name); + exit(-1); + } /* * vrf_get is implied creation if it does not exist */ @@ -664,7 +676,7 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) /* If VRF, create the VRF structure itself. */ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) { - netlink_vrf_change(h, tb[IFLA_LINKINFO], name); + netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name); vrf_id = (vrf_id_t)ifi->ifi_index; } @@ -1226,7 +1238,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) /* If VRF, create or update the VRF structure itself. */ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) { - netlink_vrf_change(h, tb[IFLA_LINKINFO], name); + netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name); vrf_id = (vrf_id_t)ifi->ifi_index; } diff --git a/zebra/interface.c b/zebra/interface.c index 59cbfc6854..9a248ba5d1 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -153,7 +153,7 @@ static int if_zebra_new_hook(struct interface *ifp) rtadv->AdvLinkMTU = 0; rtadv->AdvReachableTime = 0; rtadv->AdvRetransTimer = 0; - rtadv->AdvCurHopLimit = 0; + rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */ rtadv->HomeAgentPreference = 0; @@ -500,7 +500,7 @@ void if_flags_update(struct interface *ifp, uint64_t newflags) /* Wake up configured address if it is not in current kernel address. */ -static void if_addr_wakeup(struct interface *ifp) +void if_addr_wakeup(struct interface *ifp) { struct listnode *node, *nnode; struct connected *ifc; @@ -1664,7 +1664,14 @@ static void interface_update_stats(void) #endif /* HAVE_NET_RT_IFLIST */ } -struct cmd_node interface_node = {INTERFACE_NODE, "%s(config-if)# ", 1}; +static int if_config_write(struct vty *vty); +struct cmd_node interface_node = { + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = if_config_write, +}; #ifndef VTYSH_EXTRACT_PL #include "zebra/interface_clippy.c" @@ -1881,6 +1888,24 @@ DEFUN (show_interface_desc_vrf_all, return CMD_SUCCESS; } +int if_multicast_set(struct interface *ifp) +{ + struct zebra_if *if_data; + + if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { + if (if_set_flags(ifp, IFF_MULTICAST) < 0) { + zlog_debug("Can't set multicast flag on interface %s", + ifp->name); + return -1; + } + if_refresh(ifp); + } + if_data = ifp->info; + if_data->multicast = IF_ZEBRA_MULTICAST_ON; + + return 0; +} + DEFUN (multicast, multicast_cmd, "multicast", @@ -1904,6 +1929,24 @@ DEFUN (multicast, return CMD_SUCCESS; } +int if_multicast_unset(struct interface *ifp) +{ + struct zebra_if *if_data; + + if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { + if (if_unset_flags(ifp, IFF_MULTICAST) < 0) { + zlog_debug("Can't unset multicast flag on interface %s", + ifp->name); + return -1; + } + if_refresh(ifp); + } + if_data = ifp->info; + if_data->multicast = IF_ZEBRA_MULTICAST_OFF; + + return 0; +} + DEFUN (no_multicast, no_multicast_cmd, "no multicast", @@ -1928,23 +1971,35 @@ DEFUN (no_multicast, return CMD_SUCCESS; } -DEFUN (linkdetect, - linkdetect_cmd, - "link-detect", - "Enable link detection on interface\n") +int if_linkdetect(struct interface *ifp, bool detect) { - VTY_DECLVAR_CONTEXT(interface, ifp); int if_was_operative; if_was_operative = if_is_no_ptm_operative(ifp); - SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); + if (detect) { + SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); - /* When linkdetection is enabled, if might come down */ - if (!if_is_no_ptm_operative(ifp) && if_was_operative) - if_down(ifp); + /* When linkdetection is enabled, if might come down */ + if (!if_is_no_ptm_operative(ifp) && if_was_operative) + if_down(ifp); + } else { + UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); + /* Interface may come up after disabling link detection */ + if (if_is_operative(ifp) && !if_was_operative) + if_up(ifp); + } /* FIXME: Will defer status change forwarding if interface does not come down! */ + return 0; +} + +DEFUN(linkdetect, linkdetect_cmd, "link-detect", + "Enable link detection on interface\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + + if_linkdetect(ifp, true); return CMD_SUCCESS; } @@ -1957,18 +2012,29 @@ DEFUN (no_linkdetect, "Disable link detection on interface\n") { VTY_DECLVAR_CONTEXT(interface, ifp); - int if_was_operative; - if_was_operative = if_is_no_ptm_operative(ifp); - UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION); + if_linkdetect(ifp, false); + + return CMD_SUCCESS; +} - /* Interface may come up after disabling link detection */ - if (if_is_operative(ifp) && !if_was_operative) - if_up(ifp); +int if_shutdown(struct interface *ifp) +{ + struct zebra_if *if_data; - /* FIXME: see linkdetect_cmd */ + if (ifp->ifindex != IFINDEX_INTERNAL) { + /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */ + rtadv_stop_ra(ifp); + if (if_unset_flags(ifp, IFF_UP) < 0) { + zlog_debug("Can't shutdown interface %s", ifp->name); + return -1; + } + if_refresh(ifp); + } + if_data = ifp->info; + if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON; - return CMD_SUCCESS; + return 0; } DEFUN (shutdown_if, @@ -1996,6 +2062,30 @@ DEFUN (shutdown_if, return CMD_SUCCESS; } +int if_no_shutdown(struct interface *ifp) +{ + struct zebra_if *if_data; + + if (ifp->ifindex != IFINDEX_INTERNAL) { + if (if_set_flags(ifp, IFF_UP | IFF_RUNNING) < 0) { + zlog_debug("Can't up interface %s", ifp->name); + return -1; + } + if_refresh(ifp); + + /* Some addresses (in particular, IPv6 addresses on Linux) get + * removed when the interface goes down. They need to be + * readded. + */ + if_addr_wakeup(ifp); + } + + if_data = ifp->info; + if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF; + + return 0; +} + DEFUN (no_shutdown_if, no_shutdown_if_cmd, "no shutdown", @@ -2074,7 +2164,10 @@ DEFUN (no_bandwidth_if, struct cmd_node link_params_node = { - LINK_PARAMS_NODE, "%s(config-link-params)# ", 1, + .name = "link-params", + .node = LINK_PARAMS_NODE, + .parent_node = INTERFACE_NODE, + .prompt = "%s(config-link-params)# ", }; static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field, @@ -2748,6 +2841,79 @@ DEFUN (no_link_params_use_bw, return CMD_SUCCESS; } +int if_ip_address_install(struct interface *ifp, struct prefix *prefix, + const char *label, struct prefix *pp) +{ + struct zebra_if *if_data; + struct prefix_ipv4 lp; + struct prefix_ipv4 *p; + struct connected *ifc; + enum zebra_dplane_result dplane_res; + + if_data = ifp->info; + + lp.family = prefix->family; + lp.prefix = prefix->u.prefix4; + lp.prefixlen = prefix->prefixlen; + apply_mask_ipv4(&lp); + + ifc = connected_check_ptp(ifp, &lp, pp ? pp : NULL); + if (!ifc) { + ifc = connected_new(); + ifc->ifp = ifp; + + /* Address. */ + p = prefix_ipv4_new(); + *p = lp; + ifc->address = (struct prefix *)p; + + if (pp) { + SET_FLAG(ifc->flags, ZEBRA_IFA_PEER); + p = prefix_ipv4_new(); + *p = *(struct prefix_ipv4 *)pp; + ifc->destination = (struct prefix *)p; + } + + /* Label. */ + if (label) + ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); + + /* Add to linked list. */ + listnode_add(ifp->connected, ifc); + } + + /* This address is configured from zebra. */ + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) + SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + + /* In case of this route need to install kernel. */ + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) + && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) + && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { + /* Some system need to up the interface to set IP address. */ + if (!if_is_up(ifp)) { + if_set_flags(ifp, IFF_UP | IFF_RUNNING); + if_refresh(ifp); + } + + dplane_res = dplane_intf_addr_set(ifp, ifc); + if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { + zlog_debug( + "dplane can't set interface IP address: %s.\n", + dplane_res2str(dplane_res)); + return NB_ERR; + } + + SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); + /* The address will be advertised to zebra clients when the + * notification + * from the kernel has been received. + * It will also be added to the subnet chain list, then. */ + } + + return 0; +} + static int ip_address_install(struct vty *vty, struct interface *ifp, const char *addr_str, const char *peer_str, const char *label) @@ -2842,6 +3008,51 @@ static int ip_address_install(struct vty *vty, struct interface *ifp, return CMD_SUCCESS; } +int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix) +{ + struct connected *ifc = NULL; + enum zebra_dplane_result dplane_res; + + if (prefix->family == AF_INET) { + /* Check current interface address. */ + ifc = connected_check_ptp(ifp, prefix, NULL); + if (!ifc) { + zlog_debug("interface %s Can't find address\n", + ifp->name); + return -1; + } + + } else if (prefix->family == AF_INET6) { + /* Check current interface address. */ + ifc = connected_check(ifp, prefix); + } + + if (!ifc) { + zlog_debug("interface %s Can't find address\n", ifp->name); + return -1; + } + UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + + /* This is not real address or interface is not active. */ + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) + || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { + listnode_delete(ifp->connected, ifc); + connected_free(&ifc); + return CMD_WARNING_CONFIG_FAILED; + } + + /* This is real route. */ + dplane_res = dplane_intf_addr_unset(ifp, ifc); + if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { + zlog_debug("Can't unset interface IP address: %s.\n", + dplane_res2str(dplane_res)); + return -1; + } + UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); + + return 0; +} + static int ip_address_uninstall(struct vty *vty, struct interface *ifp, const char *addr_str, const char *peer_str, const char *label) @@ -2995,6 +3206,71 @@ DEFUN (no_ip_address_label, } #endif /* HAVE_NETLINK */ +int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix, + const char *label) +{ + struct zebra_if *if_data; + struct prefix_ipv6 cp; + struct connected *ifc; + struct prefix_ipv6 *p; + enum zebra_dplane_result dplane_res; + + if_data = ifp->info; + + cp.family = prefix->family; + cp.prefixlen = prefix->prefixlen; + cp.prefix = prefix->u.prefix6; + apply_mask_ipv6(&cp); + + ifc = connected_check(ifp, (struct prefix *)&cp); + if (!ifc) { + ifc = connected_new(); + ifc->ifp = ifp; + + /* Address. */ + p = prefix_ipv6_new(); + *p = cp; + ifc->address = (struct prefix *)p; + + /* Label. */ + if (label) + ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); + + /* Add to linked list. */ + listnode_add(ifp->connected, ifc); + } + + /* This address is configured from zebra. */ + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) + SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); + + /* In case of this route need to install kernel. */ + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) + && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) + && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { + /* Some system need to up the interface to set IP address. */ + if (!if_is_up(ifp)) { + if_set_flags(ifp, IFF_UP | IFF_RUNNING); + if_refresh(ifp); + } + + dplane_res = dplane_intf_addr_set(ifp, ifc); + if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) { + zlog_debug( + "dplane can't set interface IP address: %s.\n", + dplane_res2str(dplane_res)); + return NB_ERR; + } + + SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED); + /* The address will be advertised to zebra clients when the + * notification + * from the kernel has been received. */ + } + + return 0; +} + static int ipv6_address_install(struct vty *vty, struct interface *ifp, const char *addr_str, const char *peer_str, const char *label) @@ -3311,8 +3587,8 @@ void zebra_if_init(void) hook_register_prio(if_del, 0, if_zebra_delete_hook); /* Install configuration write function. */ - install_node(&interface_node, if_config_write); - install_node(&link_params_node, NULL); + install_node(&interface_node); + install_node(&link_params_node); if_cmd_init(); /* * This is *intentionally* setting this to NULL, signaling diff --git a/zebra/interface.h b/zebra/interface.h index b7e90a0c31..2dad0c3bb2 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -117,6 +117,7 @@ struct rtadvconf { Default: The value specified in the "Assigned Numbers" RFC [ASSIGNED] that was in effect at the time of implementation. */ int AdvCurHopLimit; +#define RTADV_DEFAULT_HOPLIMIT 64 /* 64 hops */ /* The value to be placed in the Router Lifetime field of Router Advertisements sent from the interface, in seconds. MUST be @@ -440,6 +441,17 @@ extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex, ns_id_t ns_id); extern void zebra_if_update_all_links(void); extern void zebra_if_set_protodown(struct interface *ifp, bool down); +extern int if_ip_address_install(struct interface *ifp, struct prefix *prefix, + const char *label, struct prefix *pp); +extern int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix, + const char *label); +extern int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix); +extern int if_shutdown(struct interface *ifp); +extern int if_no_shutdown(struct interface *ifp); +extern int if_multicast_set(struct interface *ifp); +extern int if_multicast_unset(struct interface *ifp); +extern int if_linkdetect(struct interface *ifp, bool detect); +extern void if_addr_wakeup(struct interface *ifp); /* Nexthop group connected functions */ extern void if_nhg_dependents_add(struct interface *ifp, diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 8e1ca122d3..87a1f5fdc7 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -53,6 +53,7 @@ #include "if.h" #include "sockunion.h" #include "log.h" +#include "network.h" extern int irdp_sock; @@ -267,7 +268,7 @@ static void irdp_if_start(struct interface *ifp, int multicast, } srandom(seed); - timer = (random() % IRDP_DEFAULT_INTERVAL) + 1; + timer = (frr_weak_random() % IRDP_DEFAULT_INTERVAL) + 1; irdp->AdvPrefList = list_new(); irdp->AdvPrefList->del = (void (*)(void *))Adv_free; /* Destructor */ diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index a1e6e8248e..b868d23a94 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -66,6 +66,7 @@ #include "if.h" #include "sockunion.h" #include "log.h" +#include "network.h" /* GLOBAL VARS */ @@ -233,7 +234,7 @@ int irdp_send_thread(struct thread *t_advert) } tmp = irdp->MaxAdvertInterval - irdp->MinAdvertInterval; - timer = random() % (tmp + 1); + timer = frr_weak_random() % (tmp + 1); timer = irdp->MinAdvertInterval + timer; if (irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS @@ -303,7 +304,7 @@ void process_solicit(struct interface *ifp) thread_cancel(irdp->t_advertise); irdp->t_advertise = NULL; - timer = (random() % MAX_RESPONSE_DELAY) + 1; + timer = (frr_weak_random() % MAX_RESPONSE_DELAY) + 1; irdp->t_advertise = NULL; thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer, diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 5f2128a09c..93736e672a 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -52,48 +52,45 @@ DEFINE_MTYPE_STATIC(LBL_MGR, LM_CHUNK, "Label Manager Chunk"); * externally */ -DEFINE_HOOK(lm_client_connect, - (uint8_t proto, uint16_t instance, vrf_id_t vrf_id), - (proto, instance, vrf_id)); -DEFINE_HOOK(lm_client_disconnect, (uint8_t proto, uint16_t instance), - (proto, instance)); +DEFINE_HOOK(lm_client_connect, (struct zserv *client, vrf_id_t vrf_id), + (client, vrf_id)); +DEFINE_HOOK(lm_client_disconnect, (struct zserv *client), (client)); DEFINE_HOOK(lm_get_chunk, - (struct label_manager_chunk * *lmc, uint8_t proto, - uint16_t instance, uint8_t keep, uint32_t size, uint32_t base, - vrf_id_t vrf_id), - (lmc, proto, instance, keep, size, base, vrf_id)); + (struct label_manager_chunk * *lmc, struct zserv *client, + uint8_t keep, uint32_t size, uint32_t base, vrf_id_t vrf_id), + (lmc, client, keep, size, base, vrf_id)); DEFINE_HOOK(lm_release_chunk, - (uint8_t proto, uint16_t instance, uint32_t start, uint32_t end), - (proto, instance, start, end)); + (struct zserv *client, uint32_t start, uint32_t end), + (client, start, end)); DEFINE_HOOK(lm_cbs_inited, (), ()); /* define wrappers to be called in zapi_msg.c (as hooks must be called in * source file where they were defined) */ -void lm_client_connect_call(uint8_t proto, uint16_t instance, vrf_id_t vrf_id) +void lm_client_connect_call(struct zserv *client, vrf_id_t vrf_id) { - hook_call(lm_client_connect, proto, instance, vrf_id); + hook_call(lm_client_connect, client, vrf_id); } -void lm_get_chunk_call(struct label_manager_chunk **lmc, uint8_t proto, - uint16_t instance, uint8_t keep, uint32_t size, - uint32_t base, vrf_id_t vrf_id) +void lm_get_chunk_call(struct label_manager_chunk **lmc, struct zserv *client, + uint8_t keep, uint32_t size, uint32_t base, + vrf_id_t vrf_id) { - hook_call(lm_get_chunk, lmc, proto, instance, keep, size, base, vrf_id); + hook_call(lm_get_chunk, lmc, client, keep, size, base, vrf_id); } -void lm_release_chunk_call(uint8_t proto, uint16_t instance, uint32_t start, - uint32_t end) +void lm_release_chunk_call(struct zserv *client, uint32_t start, uint32_t end) { - hook_call(lm_release_chunk, proto, instance, start, end); + hook_call(lm_release_chunk, client, start, end); } /* forward declarations of the static functions to be used for some hooks */ -static int label_manager_connect(uint8_t proto, uint16_t instance, - vrf_id_t vrf_id); -static int label_manager_disconnect(uint8_t proto, uint16_t instance); +static int label_manager_connect(struct zserv *client, vrf_id_t vrf_id); +static int label_manager_disconnect(struct zserv *client); static int label_manager_get_chunk(struct label_manager_chunk **lmc, - uint8_t proto, uint16_t instance, - uint8_t keep, uint32_t size, uint32_t base, + struct zserv *client, uint8_t keep, + uint32_t size, uint32_t base, vrf_id_t vrf_id); +static int label_manager_release_label_chunk(struct zserv *client, + uint32_t start, uint32_t end); void delete_label_chunk(void *val) { @@ -110,7 +107,7 @@ void delete_label_chunk(void *val) * @param instance Instance, to identify the owner * @return Number of chunks released */ -int release_daemon_label_chunks(uint8_t proto, unsigned short instance) +int release_daemon_label_chunks(struct zserv *client) { struct listnode *node; struct label_manager_chunk *lmc; @@ -118,13 +115,16 @@ int release_daemon_label_chunks(uint8_t proto, unsigned short instance) int ret; if (IS_ZEBRA_DEBUG_PACKET) - zlog_debug("%s: Releasing chunks for client proto %s, instance %d", - __func__, zebra_route_string(proto), instance); + zlog_debug("%s: Releasing chunks for client proto %s, instance %d, session %u", + __func__, zebra_route_string(client->proto), + client->instance, client->session_id); for (ALL_LIST_ELEMENTS_RO(lbl_mgr.lc_list, node, lmc)) { - if (lmc->proto == proto && lmc->instance == instance - && lmc->keep == 0) { + if (lmc->proto == client->proto && + lmc->instance == client->instance && + lmc->session_id == client->session_id && lmc->keep == 0) { ret = release_label_chunk(lmc->proto, lmc->instance, + lmc->session_id, lmc->start, lmc->end); if (ret == 0) count++; @@ -139,10 +139,7 @@ int release_daemon_label_chunks(uint8_t proto, unsigned short instance) int lm_client_disconnect_cb(struct zserv *client) { - uint8_t proto = client->proto; - uint16_t instance = client->instance; - - hook_call(lm_client_disconnect, proto, instance); + hook_call(lm_client_disconnect, client); return 0; } @@ -151,14 +148,14 @@ void lm_hooks_register(void) hook_register(lm_client_connect, label_manager_connect); hook_register(lm_client_disconnect, label_manager_disconnect); hook_register(lm_get_chunk, label_manager_get_chunk); - hook_register(lm_release_chunk, release_label_chunk); + hook_register(lm_release_chunk, label_manager_release_label_chunk); } void lm_hooks_unregister(void) { hook_unregister(lm_client_connect, label_manager_connect); hook_unregister(lm_client_disconnect, label_manager_disconnect); hook_unregister(lm_get_chunk, label_manager_get_chunk); - hook_unregister(lm_release_chunk, release_label_chunk); + hook_unregister(lm_release_chunk, label_manager_release_label_chunk); } /** @@ -180,6 +177,7 @@ void label_manager_init(void) /* alloc and fill a label chunk */ struct label_manager_chunk *create_label_chunk(uint8_t proto, unsigned short instance, + uint32_t session_id, uint8_t keep, uint32_t start, uint32_t end) { @@ -191,6 +189,7 @@ struct label_manager_chunk *create_label_chunk(uint8_t proto, lmc->end = end; lmc->proto = proto; lmc->instance = instance; + lmc->session_id = session_id; lmc->keep = keep; return lmc; @@ -199,7 +198,8 @@ struct label_manager_chunk *create_label_chunk(uint8_t proto, /* attempt to get a specific label chunk */ static struct label_manager_chunk * assign_specific_label_chunk(uint8_t proto, unsigned short instance, - uint8_t keep, uint32_t size, uint32_t base) + uint32_t session_id, uint8_t keep, uint32_t size, + uint32_t base) { struct label_manager_chunk *lmc; struct listnode *node, *next = NULL; @@ -248,7 +248,8 @@ assign_specific_label_chunk(uint8_t proto, unsigned short instance, /* insert chunk between existing chunks */ if (insert_node) { - lmc = create_label_chunk(proto, instance, keep, base, end); + lmc = create_label_chunk(proto, instance, session_id, keep, + base, end); listnode_add_before(lbl_mgr.lc_list, insert_node, lmc); return lmc; } @@ -270,7 +271,8 @@ assign_specific_label_chunk(uint8_t proto, unsigned short instance, delete_label_chunk(death); } - lmc = create_label_chunk(proto, instance, keep, base, end); + lmc = create_label_chunk(proto, instance, session_id, keep, + base, end); if (last_node) listnode_add_before(lbl_mgr.lc_list, last_node, lmc); else @@ -280,7 +282,8 @@ assign_specific_label_chunk(uint8_t proto, unsigned short instance, } else { /* create a new chunk past all the existing ones and link at * tail */ - lmc = create_label_chunk(proto, instance, keep, base, end); + lmc = create_label_chunk(proto, instance, session_id, keep, + base, end); listnode_add(lbl_mgr.lc_list, lmc); return lmc; } @@ -301,6 +304,7 @@ assign_specific_label_chunk(uint8_t proto, unsigned short instance, */ struct label_manager_chunk *assign_label_chunk(uint8_t proto, unsigned short instance, + uint32_t session_id, uint8_t keep, uint32_t size, uint32_t base) { @@ -310,8 +314,8 @@ struct label_manager_chunk *assign_label_chunk(uint8_t proto, /* handle chunks request with a specific base label */ if (base != MPLS_LABEL_BASE_ANY) - return assign_specific_label_chunk(proto, instance, keep, size, - base); + return assign_specific_label_chunk(proto, instance, session_id, + keep, size, base); /* appease scan-build, who gets confused by the use of macros */ assert(lbl_mgr.lc_list); @@ -322,6 +326,7 @@ struct label_manager_chunk *assign_label_chunk(uint8_t proto, && lmc->end - lmc->start + 1 == size) { lmc->proto = proto; lmc->instance = instance; + lmc->session_id = session_id; lmc->keep = keep; return lmc; } @@ -329,8 +334,9 @@ struct label_manager_chunk *assign_label_chunk(uint8_t proto, */ if ((lmc->start > prev_end) && (lmc->start - prev_end >= size)) { - lmc = create_label_chunk(proto, instance, keep, - prev_end + 1, prev_end + size); + lmc = create_label_chunk(proto, instance, session_id, + keep, prev_end + 1, + prev_end + size); listnode_add_before(lbl_mgr.lc_list, node, lmc); return lmc; } @@ -355,13 +361,31 @@ struct label_manager_chunk *assign_label_chunk(uint8_t proto, } /* create chunk and link at tail */ - lmc = create_label_chunk(proto, instance, keep, start_free, + lmc = create_label_chunk(proto, instance, session_id, keep, start_free, start_free + size - 1); listnode_add(lbl_mgr.lc_list, lmc); return lmc; } /** + * Release label chunks from a client. + * + * Called on client disconnection or reconnection. It only releases chunks + * with empty keep value. + * + * @param client Client zapi session + * @param start First label of the chunk + * @param end Last label of the chunk + * @return 0 on success + */ +static int label_manager_release_label_chunk(struct zserv *client, + uint32_t start, uint32_t end) +{ + return release_label_chunk(client->proto, client->instance, + client->session_id, start, end); +} + +/** * Core function, release no longer used label chunks * * @param proto Daemon protocol of client, to identify the owner @@ -370,8 +394,8 @@ struct label_manager_chunk *assign_label_chunk(uint8_t proto, * @param end Last label of the chunk * @return 0 on success, -1 otherwise */ -int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, - uint32_t end) +int release_label_chunk(uint8_t proto, unsigned short instance, + uint32_t session_id, uint32_t start, uint32_t end) { struct listnode *node; struct label_manager_chunk *lmc; @@ -386,13 +410,15 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, continue; if (lmc->end != end) continue; - if (lmc->proto != proto || lmc->instance != instance) { + if (lmc->proto != proto || lmc->instance != instance || + lmc->session_id != session_id) { flog_err(EC_ZEBRA_LM_DAEMON_MISMATCH, "%s: Daemon mismatch!!", __func__); continue; } lmc->proto = NO_PROTO; lmc->instance = 0; + lmc->session_id = 0; lmc->keep = 0; ret = 0; break; @@ -405,64 +431,60 @@ int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, } /* default functions to be called on hooks */ -static int label_manager_connect(uint8_t proto, uint16_t instance, - vrf_id_t vrf_id) +static int label_manager_connect(struct zserv *client, vrf_id_t vrf_id) { /* * Release previous labels of same protocol and instance. * This is done in case it restarted from an unexpected shutdown. */ - release_daemon_label_chunks(proto, instance); - return lm_client_connect_response(proto, instance, vrf_id, 0); + release_daemon_label_chunks(client); + return zsend_label_manager_connect_response(client, vrf_id, 0); } -static int label_manager_disconnect(uint8_t proto, uint16_t instance) +static int label_manager_disconnect(struct zserv *client) { - release_daemon_label_chunks(proto, instance); + release_daemon_label_chunks(client); return 0; } static int label_manager_get_chunk(struct label_manager_chunk **lmc, - uint8_t proto, uint16_t instance, - uint8_t keep, uint32_t size, uint32_t base, + struct zserv *client, uint8_t keep, + uint32_t size, uint32_t base, vrf_id_t vrf_id) { - *lmc = assign_label_chunk(proto, instance, keep, size, base); - return lm_get_chunk_response(*lmc, proto, instance, vrf_id); + *lmc = assign_label_chunk(client->proto, client->instance, + client->session_id, keep, size, base); + return lm_get_chunk_response(*lmc, client, vrf_id); } /* Respond to a connect request */ int lm_client_connect_response(uint8_t proto, uint16_t instance, - vrf_id_t vrf_id, uint8_t result) + uint32_t session_id, vrf_id_t vrf_id, + uint8_t result) { - struct zserv *client = zserv_find_client(proto, instance); + struct zserv *client = zserv_find_client_session(proto, instance, + session_id); if (!client) { - zlog_err("%s: could not find client for daemon %s instance %u", - __func__, zebra_route_string(proto), instance); + zlog_err("%s: could not find client for daemon %s instance %u session %u", + __func__, zebra_route_string(proto), instance, + session_id); return 1; } return zsend_label_manager_connect_response(client, vrf_id, result); } /* Respond to a get_chunk request */ -int lm_get_chunk_response(struct label_manager_chunk *lmc, uint8_t proto, - uint16_t instance, vrf_id_t vrf_id) +int lm_get_chunk_response(struct label_manager_chunk *lmc, struct zserv *client, + vrf_id_t vrf_id) { if (!lmc) flog_err(EC_ZEBRA_LM_CANNOT_ASSIGN_CHUNK, "Unable to assign Label Chunk to %s instance %u", - zebra_route_string(proto), instance); + zebra_route_string(client->proto), client->instance); else if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("Assigned Label Chunk %u - %u to %s instance %u", - lmc->start, lmc->end, zebra_route_string(proto), - instance); + lmc->start, lmc->end, + zebra_route_string(client->proto), client->instance); - struct zserv *client = zserv_find_client(proto, instance); - if (!client) { - zlog_err("%s: could not find client for daemon %s instance %u", - __func__, zebra_route_string(proto), instance); - return 1; - } - return zsend_assign_label_chunk_response(client, vrf_id, proto, - instance, lmc); + return zsend_assign_label_chunk_response(client, vrf_id, lmc); } void label_manager_close(void) diff --git a/zebra/label_manager.h b/zebra/label_manager.h index 4fee34d301..82154982c2 100644 --- a/zebra/label_manager.h +++ b/zebra/label_manager.h @@ -40,19 +40,20 @@ extern "C" { /* * Label chunk struct - * Client daemon which the chunk belongs to can be identified by either - * proto (daemon protocol) + instance. + * Client daemon which the chunk belongs to can be identified by a tuple of: + * proto (daemon protocol) + instance + zapi session_id * If the client then passes a non-empty value to keep field when it requests * for chunks, the chunks won't be garbage collected and the client will be - * responsible of its release. + * responsible for releasing them. * Otherwise, if the keep field is not set (value 0) for the chunk, it will be * automatically released when the client disconnects or when it reconnects * (in case it died unexpectedly, we can know it's the same because it will have - * the same proto and instance values) + * the same proto+instance+session values) */ struct label_manager_chunk { uint8_t proto; unsigned short instance; + uint32_t session_id; uint8_t keep; uint32_t start; /* First label of the chunk */ uint32_t end; /* Last label of the chunk */ @@ -63,41 +64,40 @@ struct label_manager_chunk { * so that any external module wanting to replace those can react */ -DECLARE_HOOK(lm_client_connect, - (uint8_t proto, uint16_t instance, vrf_id_t vrf_id), - (proto, instance, vrf_id)); -DECLARE_HOOK(lm_client_disconnect, (uint8_t proto, uint16_t instance), - (proto, instance)); +DECLARE_HOOK(lm_client_connect, (struct zserv *client, vrf_id_t vrf_id), + (client, vrf_id)); +DECLARE_HOOK(lm_client_disconnect, (struct zserv *client), (client)); DECLARE_HOOK(lm_get_chunk, - (struct label_manager_chunk * *lmc, uint8_t proto, - uint16_t instance, uint8_t keep, uint32_t size, uint32_t base, - vrf_id_t vrf_id), - (lmc, proto, instance, keep, size, base, vrf_id)); + (struct label_manager_chunk * *lmc, struct zserv *client, + uint8_t keep, uint32_t size, uint32_t base, vrf_id_t vrf_id), + (lmc, client, keep, size, base, vrf_id)); DECLARE_HOOK(lm_release_chunk, - (uint8_t proto, uint16_t instance, uint32_t start, uint32_t end), - (proto, instance, start, end)); + (struct zserv *client, uint32_t start, uint32_t end), + (client, start, end)); DECLARE_HOOK(lm_cbs_inited, (), ()); /* declare wrappers to be called in zapi_msg.c (as hooks must be called in * source file where they were defined) */ -void lm_client_connect_call(uint8_t proto, uint16_t instance, vrf_id_t vrf_id); -void lm_get_chunk_call(struct label_manager_chunk **lmc, uint8_t proto, - uint16_t instance, uint8_t keep, uint32_t size, - uint32_t base, vrf_id_t vrf_id); -void lm_release_chunk_call(uint8_t proto, uint16_t instance, uint32_t start, +void lm_client_connect_call(struct zserv *client, vrf_id_t vrf_id); +void lm_get_chunk_call(struct label_manager_chunk **lmc, struct zserv *client, + uint8_t keep, uint32_t size, uint32_t base, + vrf_id_t vrf_id); +void lm_release_chunk_call(struct zserv *client, uint32_t start, uint32_t end); /* API for an external LM to return responses for requests */ int lm_client_connect_response(uint8_t proto, uint16_t instance, - vrf_id_t vrf_id, uint8_t result); -int lm_get_chunk_response(struct label_manager_chunk *lmc, uint8_t proto, - uint16_t instance, vrf_id_t vrf_id); + uint32_t session_id, vrf_id_t vrf_id, + uint8_t result); +int lm_get_chunk_response(struct label_manager_chunk *lmc, struct zserv *client, + vrf_id_t vrf_id); /* convenience function to allocate an lmc to be consumed by the above API */ struct label_manager_chunk *create_label_chunk(uint8_t proto, unsigned short instance, + uint32_t session_id, uint8_t keep, uint32_t start, uint32_t end); void delete_label_chunk(void *val); @@ -117,12 +117,13 @@ struct label_manager { void label_manager_init(void); struct label_manager_chunk *assign_label_chunk(uint8_t proto, unsigned short instance, + uint32_t session_id, uint8_t keep, uint32_t size, uint32_t base); -int release_label_chunk(uint8_t proto, unsigned short instance, uint32_t start, - uint32_t end); +int release_label_chunk(uint8_t proto, unsigned short instance, + uint32_t session_id, uint32_t start, uint32_t end); int lm_client_disconnect_cb(struct zserv *client); -int release_daemon_label_chunks(uint8_t proto, unsigned short instance); +int release_daemon_label_chunks(struct zserv *client); void label_manager_close(void); #ifdef __cplusplus diff --git a/zebra/main.c b/zebra/main.c index fb7e926c5c..e230a744f6 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -54,6 +54,7 @@ #include "zebra/zebra_pbr.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_routemap.h" +#include "zebra/zebra_nb.h" #if defined(HANDLE_NETLINK_FUZZING) #include "zebra/kernel_netlink.h" @@ -247,6 +248,7 @@ static const struct frr_yang_module_info *const zebra_yang_modules[] = { &frr_interface_info, &frr_route_map_info, &frr_zebra_info, + &frr_vrf_info, }; FRR_DAEMON_INFO( diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 5c9d2f69a6..4630b8a8e9 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -290,7 +290,7 @@ static inline int proto2zebra(int proto, int family, bool is_nexthop) /* Pending: create an efficient table_id (in a tree/hash) based lookup) */ -static vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) +vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) { struct vrf *vrf; struct zebra_vrf *zvrf; @@ -904,8 +904,8 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, ifp = if_lookup_by_index(oif[count], vrf); char temp[256]; - sprintf(temp, "%s(%d) ", ifp ? ifp->name : "Unknown", - oif[count]); + snprintf(temp, sizeof(temp), "%s(%d) ", + ifp ? ifp->name : "Unknown", oif[count]); strlcat(oif_list, temp, sizeof(oif_list)); } zvrf = zebra_vrf_lookup_by_id(vrf); @@ -1087,7 +1087,8 @@ static int build_label_stack(struct mpls_label_stack *nh_label, sprintf(label_buf, "label %u", nh_label->label[i]); else { - sprintf(label_buf1, "/%u", nh_label->label[i]); + snprintf(label_buf1, sizeof(label_buf1), "/%u", + nh_label->label[i]); strlcat(label_buf, label_buf1, label_buf_size); } } @@ -2686,7 +2687,7 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if ((NDA_VLAN <= NDA_MAX) && tb[NDA_VLAN]) { vid_present = 1; vid = *(uint16_t *)RTA_DATA(tb[NDA_VLAN]); - sprintf(vid_buf, " VLAN %u", vid); + snprintf(vid_buf, sizeof(vid_buf), " VLAN %u", vid); } if (tb[NDA_DST]) { @@ -2694,7 +2695,8 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) dst_present = 1; memcpy(&vtep_ip.s_addr, RTA_DATA(tb[NDA_DST]), IPV4_MAX_BYTELEN); - sprintf(dst_buf, " dst %s", inet_ntoa(vtep_ip)); + snprintf(dst_buf, sizeof(dst_buf), " dst %s", + inet_ntoa(vtep_ip)); } if (IS_ZEBRA_DEBUG_KERNEL) diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index d6a993e78a..a364d305c5 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -92,6 +92,7 @@ extern int netlink_macfdb_read_specific_mac(struct zebra_ns *zns, struct ethaddr *mac, uint16_t vid); extern int netlink_neigh_read_specific_ip(struct ipaddr *ip, struct interface *vlan_if); +extern vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id); #ifdef __cplusplus } diff --git a/zebra/rtadv.c b/zebra/rtadv.c index a22e39dc48..11434edfcf 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -46,6 +46,10 @@ #include "zebra/zebra_errors.h" #include "zebra/zebra_router.h" +#ifndef VTYSH_EXTRACT_PL +#include "zebra/rtadv_clippy.c" +#endif + extern struct zebra_privs_t zserv_privs; #if defined(HAVE_RTADV) @@ -230,7 +234,7 @@ static void rtadv_send_packet(int sock, struct interface *ifp, rtadv->nd_ra_code = 0; rtadv->nd_ra_cksum = 0; - rtadv->nd_ra_curhoplimit = 64; + rtadv->nd_ra_curhoplimit = zif->rtadv.AdvCurHopLimit; /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */ rtadv->nd_ra_flags_reserved = zif->rtadv.AdvDefaultLifetime == 0 @@ -1231,6 +1235,53 @@ DEFUN (no_ipv6_nd_ra_fast_retrans, return CMD_SUCCESS; } +DEFPY (ipv6_nd_ra_hop_limit, + ipv6_nd_ra_hop_limit_cmd, + "ipv6 nd ra-hop-limit (0-255)$hopcount", + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertisement Hop Limit\n" + "Advertisement Hop Limit in hops (default:64)\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *zif = ifp->info; + + if (if_is_loopback(ifp) + || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { + vty_out(vty, + "Cannot configure IPv6 Router Advertisements on this interface\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + zif->rtadv.AdvCurHopLimit = hopcount; + + return CMD_SUCCESS; +} + +DEFPY (no_ipv6_nd_ra_hop_limit, + no_ipv6_nd_ra_hop_limit_cmd, + "no ipv6 nd ra-hop-limit [(0-255)]", + NO_STR + "Interface IPv6 config commands\n" + "Neighbor discovery\n" + "Advertisement Hop Limit\n" + "Advertisement Hop Limit in hops\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *zif = ifp->info; + + if (if_is_loopback(ifp) + || CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)) { + vty_out(vty, + "Cannot configure IPv6 Router Advertisements on this interface\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + zif->rtadv.AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT; + + return CMD_SUCCESS; +} + DEFUN (ipv6_nd_suppress_ra, ipv6_nd_suppress_ra_cmd, "ipv6 nd suppress-ra", @@ -2178,6 +2229,8 @@ static int nd_dump_vty(struct vty *vty, struct interface *ifp) vty_out(vty, " ND advertised retransmit interval is %d milliseconds\n", rtadv->AdvRetransTimer); + vty_out(vty, " ND advertised hop-count limit is %d hops\n", + rtadv->AdvCurHopLimit); vty_out(vty, " ND router advertisements sent: %d rcvd: %d\n", zif->ra_sent, zif->ra_rcvd); interval = rtadv->MaxRtrAdvInterval; @@ -2269,6 +2322,10 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp) if (!zif->rtadv.UseFastRexmit) vty_out(vty, " no ipv6 nd ra-fast-retrans\n"); + if (zif->rtadv.AdvCurHopLimit != RTADV_DEFAULT_HOPLIMIT) + vty_out(vty, " ipv6 nd ra-hop-limit %d\n", + zif->rtadv.AdvCurHopLimit); + if (zif->rtadv.AdvDefaultLifetime != -1) vty_out(vty, " ipv6 nd ra-lifetime %d\n", zif->rtadv.AdvDefaultLifetime); @@ -2437,6 +2494,8 @@ void rtadv_cmd_init(void) install_element(INTERFACE_NODE, &ipv6_nd_ra_fast_retrans_cmd); install_element(INTERFACE_NODE, &no_ipv6_nd_ra_fast_retrans_cmd); + install_element(INTERFACE_NODE, &ipv6_nd_ra_hop_limit_cmd); + install_element(INTERFACE_NODE, &no_ipv6_nd_ra_hop_limit_cmd); install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd); install_element(INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd); install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd); diff --git a/zebra/subdir.am b/zebra/subdir.am index 71094cb52c..5601b4c379 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -6,23 +6,23 @@ if ZEBRA sbin_PROGRAMS += zebra/zebra dist_examples_DATA += zebra/zebra.conf.sample vtysh_scan += \ - $(top_srcdir)/zebra/debug.c \ - $(top_srcdir)/zebra/interface.c \ - $(top_srcdir)/zebra/router-id.c \ - $(top_srcdir)/zebra/rtadv.c \ - $(top_srcdir)/zebra/zebra_mlag_vty.c \ - $(top_srcdir)/zebra/zebra_mpls_vty.c \ - $(top_srcdir)/zebra/zebra_ptm.c \ - $(top_srcdir)/zebra/zebra_pw.c \ - $(top_srcdir)/zebra/zebra_routemap.c \ - $(top_srcdir)/zebra/zebra_vty.c \ - $(top_srcdir)/zebra/zserv.c \ - $(top_srcdir)/zebra/zebra_gr.c \ + zebra/debug.c \ + zebra/interface.c \ + zebra/router-id.c \ + zebra/rtadv.c \ + zebra/zebra_mlag_vty.c \ + zebra/zebra_mpls_vty.c \ + zebra/zebra_ptm.c \ + zebra/zebra_pw.c \ + zebra/zebra_routemap.c \ + zebra/zebra_vty.c \ + zebra/zserv.c \ + zebra/zebra_gr.c \ # end # can be loaded as DSO - always include for vtysh -vtysh_scan += $(top_srcdir)/zebra/irdp_interface.c -vtysh_scan += $(top_srcdir)/zebra/zebra_fpm.c +vtysh_scan += zebra/irdp_interface.c +vtysh_scan += zebra/zebra_fpm.c if IRDP module_LTLIBRARIES += zebra/zebra_irdp.la @@ -75,7 +75,6 @@ zebra_zebra_SOURCES = \ zebra/zebra_mlag.c \ zebra/zebra_mlag_vty.c \ zebra/zebra_l2.c \ - zebra/zebra_northbound.c \ zebra/zebra_memory.c \ zebra/zebra_dplane.c \ zebra/zebra_mpls.c \ @@ -102,23 +101,22 @@ zebra_zebra_SOURCES = \ zebra/zebra_netns_notify.c \ zebra/table_manager.c \ zebra/zapi_msg.c \ + zebra/zebra_nb.c \ + zebra/zebra_nb_config.c \ + zebra/zebra_nb_rpcs.c \ + zebra/zebra_nb_state.c \ zebra/zebra_errors.c \ zebra/zebra_gr.c \ # end -zebra/debug_clippy.c: $(CLIPPY_DEPS) -zebra/debug.$(OBJEXT): zebra/debug_clippy.c - -zebra/zebra_mlag_vty_clippy.c: $(CLIPPY_DEPS) -zebra/zebra_mlag_vty.$(OBJEXT): zebra/zebra_mlag_vty_clippy.c - -zebra/zebra_vty_clippy.c: $(CLIPPY_DEPS) -zebra/interface_clippy.c: $(CLIPPY_DEPS) -zebra/interface.$(OBJEXT): zebra/interface_clippy.c -zebra/zebra_vty.$(OBJEXT): zebra/zebra_vty_clippy.c - -zebra/zebra_routemap_clippy.c: $(CLIPPY_DEPS) -zebra/zebra_routemap.$(OBJEXT): zebra/zebra_routemap_clippy.c +clippy_scan += \ + zebra/debug.c \ + zebra/interface.c \ + zebra/rtadv.c \ + zebra/zebra_mlag_vty.c \ + zebra/zebra_routemap.c \ + zebra/zebra_vty.c \ + # end noinst_HEADERS += \ zebra/connected.h \ @@ -165,6 +163,7 @@ noinst_HEADERS += \ zebra/zebra_netns_notify.h \ zebra/table_manager.h \ zebra/zapi_msg.h \ + zebra/zebra_nb.h \ zebra/zebra_errors.h \ # end @@ -193,7 +192,6 @@ endif endif nodist_zebra_zebra_SOURCES = \ - yang/frr-nexthop.yang.c \ yang/frr-zebra.yang.c \ # end diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index a58df82698..092b5dd3c2 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -957,7 +957,6 @@ int zsend_pw_update(struct zserv *client, struct zebra_pw *pw) /* Send response to a get label chunk request to client */ int zsend_assign_label_chunk_response(struct zserv *client, vrf_id_t vrf_id, - uint8_t proto, uint16_t instance, struct label_manager_chunk *lmc) { int ret; @@ -965,9 +964,9 @@ int zsend_assign_label_chunk_response(struct zserv *client, vrf_id_t vrf_id, zclient_create_header(s, ZEBRA_GET_LABEL_CHUNK, vrf_id); /* proto */ - stream_putc(s, proto); + stream_putc(s, client->proto); /* instance */ - stream_putw(s, instance); + stream_putw(s, client->instance); if (lmc) { /* keep */ @@ -1931,9 +1930,11 @@ static void zread_hello(ZAPI_HANDLER_ARGS) unsigned short instance; uint8_t notify; uint8_t synchronous; + uint32_t session_id; STREAM_GETC(msg, proto); STREAM_GETW(msg, instance); + STREAM_GETL(msg, session_id); STREAM_GETC(msg, notify); STREAM_GETC(msg, synchronous); if (notify) @@ -1953,6 +1954,7 @@ static void zread_hello(ZAPI_HANDLER_ARGS) client->proto = proto; client->instance = instance; + client->session_id = session_id; /* Graceful restart processing for client connect */ zebra_gr_client_reconnect(client); @@ -2196,7 +2198,7 @@ static void zread_label_manager_connect(struct zserv *client, client->instance = instance; /* call hook for connection using wrapper */ - lm_client_connect_call(proto, instance, vrf_id); + lm_client_connect_call(client, vrf_id); stream_failure: return; @@ -2222,8 +2224,10 @@ static void zread_get_label_chunk(struct zserv *client, struct stream *msg, STREAM_GETL(s, size); STREAM_GETL(s, base); + assert(proto == client->proto && instance == client->instance); + /* call hook to get a chunk using wrapper */ - lm_get_chunk_call(&lmc, proto, instance, keep, size, base, vrf_id); + lm_get_chunk_call(&lmc, client, keep, size, base, vrf_id); stream_failure: return; @@ -2245,8 +2249,10 @@ static void zread_release_label_chunk(struct zserv *client, struct stream *msg) STREAM_GETL(s, start); STREAM_GETL(s, end); + assert(proto == client->proto && instance == client->instance); + /* call hook to release a chunk using wrapper */ - lm_release_chunk_call(proto, instance, start, end); + lm_release_chunk_call(client, start, end); stream_failure: return; diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 996a255ff4..a4f5e74e4d 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -94,8 +94,7 @@ extern void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, extern void zsend_capabilities_all_clients(void); extern int zsend_assign_label_chunk_response(struct zserv *client, - vrf_id_t vrf_id, uint8_t proto, - uint16_t instance, + vrf_id_t vrf_id, struct label_manager_chunk *lmc); extern int zsend_label_manager_connect_response(struct zserv *client, vrf_id_t vrf_id, diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 76447c260b..143354b166 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -3557,12 +3557,20 @@ bool dplane_is_in_shutdown(void) */ void zebra_dplane_pre_finish(void) { + struct zebra_dplane_provider *dp; + if (IS_ZEBRA_DEBUG_DPLANE) zlog_debug("Zebra dataplane pre-fini called"); zdplane_info.dg_is_shutdown = true; - /* TODO -- Notify provider(s) of pending shutdown */ + /* Notify provider(s) of pending shutdown. */ + TAILQ_FOREACH(dp, &zdplane_info.dg_providers_q, dp_prov_link) { + if (dp->dp_fini == NULL) + continue; + + dp->dp_fini(dp, true); + } } /* @@ -3863,6 +3871,8 @@ done: */ void zebra_dplane_shutdown(void) { + struct zebra_dplane_provider *dp; + if (IS_ZEBRA_DEBUG_DPLANE) zlog_debug("Zebra dataplane shutdown called"); @@ -3881,7 +3891,13 @@ void zebra_dplane_shutdown(void) zdplane_info.dg_pthread = NULL; zdplane_info.dg_master = NULL; - /* TODO -- Notify provider(s) of final shutdown */ + /* Notify provider(s) of final shutdown. */ + TAILQ_FOREACH(dp, &zdplane_info.dg_providers_q, dp_prov_link) { + if (dp->dp_fini == NULL) + continue; + + dp->dp_fini(dp, false); + } /* TODO -- Clean-up provider objects */ diff --git a/zebra/zebra_errors.c b/zebra/zebra_errors.c index ef792d14c2..b75708031e 100644 --- a/zebra/zebra_errors.c +++ b/zebra/zebra_errors.c @@ -786,6 +786,12 @@ static struct log_ref ferr_zebra_err[] = { "See if the nexthop you are trying to add is already present in the fib." }, { + .code = EC_ZEBRA_VRF_MISCONFIGURED, + .title = "Duplicate VRF table id detected", + .description = "Zebra has detected a situation where there are two vrf devices with the exact same tableid. This is considered a complete misconfiguration of VRF devices and breaks a fundamental assumption in FRR about how VRF's work", + .suggestion = "Use different table id's for the VRF's in question" + }, + { .code = END_FERR, } }; diff --git a/zebra/zebra_errors.h b/zebra/zebra_errors.h index 4625a03ae6..395004d0bb 100644 --- a/zebra/zebra_errors.h +++ b/zebra/zebra_errors.h @@ -132,6 +132,7 @@ enum zebra_log_refs { EC_ZEBRA_DUP_IP_DETECTED, EC_ZEBRA_BAD_NHG_MESSAGE, EC_ZEBRA_DUPLICATE_NHG_MESSAGE, + EC_ZEBRA_VRF_MISCONFIGURED, }; void zebra_error_init(void); diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c index 10cdf49d12..8f97c8cf47 100644 --- a/zebra/zebra_fpm.c +++ b/zebra/zebra_fpm.c @@ -760,8 +760,9 @@ static int zfpm_read_cb(struct thread *thread) if (nbyte == -1) { char buffer[1024]; - sprintf(buffer, "closed socket in read(%d): %s", - errno, safe_strerror(errno)); + snprintf(buffer, sizeof(buffer), + "closed socket in read(%d): %s", errno, + safe_strerror(errno)); zfpm_connection_down(buffer); } else zfpm_connection_down("closed socket in read"); @@ -797,8 +798,9 @@ static int zfpm_read_cb(struct thread *thread) if (nbyte == -1) { char buffer[1024]; - sprintf(buffer, "failed to read message(%d) %s", - errno, safe_strerror(errno)); + snprintf(buffer, sizeof(buffer), + "failed to read message(%d) %s", errno, + safe_strerror(errno)); zfpm_connection_down(buffer); } else zfpm_connection_down("failed to read message"); @@ -1938,8 +1940,15 @@ static int fpm_remote_srv_write(struct vty *vty) } +static int fpm_remote_srv_write(struct vty *vty); /* Zebra node */ -static struct cmd_node zebra_node = {ZEBRA_NODE, "", 1}; +static struct cmd_node zebra_node = { + .name = "zebra", + .node = ZEBRA_NODE, + .parent_node = CONFIG_NODE, + .prompt = "", + .config_write = fpm_remote_srv_write, +}; /** @@ -1976,7 +1985,7 @@ static int zfpm_init(struct thread_master *master) zfpm_stats_init(&zfpm_g->last_ivl_stats); zfpm_stats_init(&zfpm_g->cumulative_stats); - install_node(&zebra_node, fpm_remote_srv_write); + install_node(&zebra_node); install_element(ENABLE_NODE, &show_zebra_fpm_stats_cmd); install_element(ENABLE_NODE, &clear_zebra_fpm_stats_cmd); install_element(CONFIG_NODE, &fpm_remote_ip_cmd); diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 0d6428026a..00909df1db 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -431,23 +431,18 @@ static int netlink_route_info_encode(netlink_route_info_t *ri, char *in_buf, } encap = nhi->encap_info.encap_type; - if (encap > FPM_NH_ENCAP_NONE) { + switch (encap) { + case FPM_NH_ENCAP_NONE: + case FPM_NH_ENCAP_MAX: + break; + case FPM_NH_ENCAP_VXLAN: addattr_l(&req->n, in_buf_len, RTA_ENCAP_TYPE, &encap, sizeof(uint16_t)); - switch (encap) { - case FPM_NH_ENCAP_NONE: - break; - case FPM_NH_ENCAP_VXLAN: - vxlan = &nhi->encap_info.vxlan_encap; - nest = addattr_nest(&req->n, in_buf_len, - RTA_ENCAP); - addattr32(&req->n, in_buf_len, VXLAN_VNI, - vxlan->vni); - addattr_nest_end(&req->n, nest); - break; - case FPM_NH_ENCAP_MAX: - break; - } + vxlan = &nhi->encap_info.vxlan_encap; + nest = addattr_nest(&req->n, in_buf_len, RTA_ENCAP); + addattr32(&req->n, in_buf_len, VXLAN_VNI, vxlan->vni); + addattr_nest_end(&req->n, nest); + break; } goto done; @@ -484,25 +479,22 @@ static int netlink_route_info_encode(netlink_route_info_t *ri, char *in_buf, } encap = nhi->encap_info.encap_type; - if (encap > FPM_NH_ENCAP_NONE) { + switch (encap) { + case FPM_NH_ENCAP_NONE: + case FPM_NH_ENCAP_MAX: + break; + case FPM_NH_ENCAP_VXLAN: rta_addattr_l(rta, sizeof(buf), RTA_ENCAP_TYPE, &encap, sizeof(uint16_t)); rtnh->rtnh_len += sizeof(struct rtattr) + sizeof(uint16_t); - switch (encap) { - case FPM_NH_ENCAP_NONE: - break; - case FPM_NH_ENCAP_VXLAN: - vxlan = &nhi->encap_info.vxlan_encap; - nest = rta_nest(rta, sizeof(buf), RTA_ENCAP); - rta_addattr_l(rta, sizeof(buf), VXLAN_VNI, - &vxlan->vni, sizeof(uint32_t)); - nest_len = rta_nest_end(rta, nest); - rtnh->rtnh_len += nest_len; - break; - case FPM_NH_ENCAP_MAX: - break; - } + vxlan = &nhi->encap_info.vxlan_encap; + nest = rta_nest(rta, sizeof(buf), RTA_ENCAP); + rta_addattr_l(rta, sizeof(buf), VXLAN_VNI, &vxlan->vni, + sizeof(uint32_t)); + nest_len = rta_nest_end(rta, nest); + rtnh->rtnh_len += nest_len; + break; } rtnh = RTNH_NEXT(rtnh); diff --git a/zebra/zebra_mlag.h b/zebra/zebra_mlag.h index d44a400666..66f5c4c67e 100644 --- a/zebra/zebra_mlag.h +++ b/zebra/zebra_mlag.h @@ -30,6 +30,10 @@ #include "mlag/mlag.pb-c.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + #define ZEBRA_MLAG_BUF_LIMIT 2048 #define ZEBRA_MLAG_LEN_SIZE 4 @@ -73,4 +77,8 @@ int zebra_mlag_protobuf_encode_client_data(struct stream *s, uint32_t *msg_type); int zebra_mlag_protobuf_decode_message(struct stream *s, uint8_t *data, uint32_t len); +#ifdef __cplusplus +} +#endif + #endif diff --git a/zebra/zebra_mlag_vty.h b/zebra/zebra_mlag_vty.h index c3dfdf74e0..789154d684 100644 --- a/zebra/zebra_mlag_vty.h +++ b/zebra/zebra_mlag_vty.h @@ -22,10 +22,18 @@ #ifndef __ZEBRA_MLAG_VTY_CODE__ #define __ZEBRA_MLAG_VTY_CODE__ +#ifdef __cplusplus +extern "C" { +#endif + extern int32_t zebra_mlag_test_mlag_internal(const char *none, const char *primary, const char *secondary); extern void zebra_mlag_vty_init(void); +#ifdef __cplusplus +} +#endif + #endif diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 999e91486d..0aaede4507 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -3335,7 +3335,8 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf) strlcpy(lstr, "implicit-null", sizeof(lstr)); break; default: - sprintf(lstr, "%u", snhlfe->out_label); + snprintf(lstr, sizeof(lstr), "%u", + snhlfe->out_label); break; } diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 796aa3f666..d789f20071 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -449,15 +449,21 @@ DEFUN (no_mpls_label_global_block, return zebra_mpls_global_block(vty, 0, NULL, NULL); } +static int zebra_mpls_config(struct vty *vty); /* MPLS node for MPLS LSP. */ -static struct cmd_node mpls_node = {MPLS_NODE, "", 1}; +static struct cmd_node mpls_node = { + .name = "mpls", + .node = MPLS_NODE, + .prompt = "", + .config_write = zebra_mpls_config, +}; /* MPLS VTY. */ void zebra_mpls_vty_init(void) { install_element(VIEW_NODE, &show_mpls_status_cmd); - install_node(&mpls_node, zebra_mpls_config); + install_node(&mpls_node); install_element(CONFIG_NODE, &mpls_transit_lsp_cmd); install_element(CONFIG_NODE, &no_mpls_transit_lsp_cmd); diff --git a/zebra/zebra_nb.c b/zebra/zebra_nb.c new file mode 100644 index 0000000000..1f3468d6dc --- /dev/null +++ b/zebra/zebra_nb.c @@ -0,0 +1,692 @@ +/* + * Copyright (C) 2020 Cumulus Networks, Inc. + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> +#include "northbound.h" +#include "libfrr.h" +#include "zebra_nb.h" + +/* clang-format off */ +const struct frr_yang_module_info frr_zebra_info = { + .name = "frr-zebra", + .nodes = { + { + .xpath = "/frr-zebra:zebra/mcast-rpf-lookup", + .cbs = { + .modify = zebra_mcast_rpf_lookup_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/ip-forwarding", + .cbs = { + .modify = zebra_ip_forwarding_modify, + .destroy = zebra_ip_forwarding_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/ipv6-forwarding", + .cbs = { + .modify = zebra_ipv6_forwarding_modify, + .destroy = zebra_ipv6_forwarding_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/workqueue-hold-timer", + .cbs = { + .modify = zebra_workqueue_hold_timer_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/zapi-packets", + .cbs = { + .modify = zebra_zapi_packets_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/import-kernel-table/table-id", + .cbs = { + .modify = zebra_import_kernel_table_table_id_modify, + .destroy = zebra_import_kernel_table_table_id_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/import-kernel-table/distance", + .cbs = { + .modify = zebra_import_kernel_table_distance_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/import-kernel-table/route-map", + .cbs = { + .modify = zebra_import_kernel_table_route_map_modify, + .destroy = zebra_import_kernel_table_route_map_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/allow-external-route-update", + .cbs = { + .create = zebra_allow_external_route_update_create, + .destroy = zebra_allow_external_route_update_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/dplane-queue-limit", + .cbs = { + .modify = zebra_dplane_queue_limit_modify, + } + }, + { + .xpath = "/frr-zebra:zebra/vrf-vni-mapping", + .cbs = { + .create = zebra_vrf_vni_mapping_create, + .destroy = zebra_vrf_vni_mapping_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/vrf-vni-mapping/vni-id", + .cbs = { + .modify = zebra_vrf_vni_mapping_vni_id_modify, + .destroy = zebra_vrf_vni_mapping_vni_id_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/vrf-vni-mapping/prefix-only", + .cbs = { + .create = zebra_vrf_vni_mapping_prefix_only_create, + .destroy = zebra_vrf_vni_mapping_prefix_only_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-events", + .cbs = { + .modify = zebra_debugs_debug_events_modify, + .destroy = zebra_debugs_debug_events_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-zapi-send", + .cbs = { + .modify = zebra_debugs_debug_zapi_send_modify, + .destroy = zebra_debugs_debug_zapi_send_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-zapi-recv", + .cbs = { + .modify = zebra_debugs_debug_zapi_recv_modify, + .destroy = zebra_debugs_debug_zapi_recv_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-zapi-detail", + .cbs = { + .modify = zebra_debugs_debug_zapi_detail_modify, + .destroy = zebra_debugs_debug_zapi_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-kernel", + .cbs = { + .modify = zebra_debugs_debug_kernel_modify, + .destroy = zebra_debugs_debug_kernel_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-kernel-msg-send", + .cbs = { + .modify = zebra_debugs_debug_kernel_msg_send_modify, + .destroy = zebra_debugs_debug_kernel_msg_send_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-kernel-msg-recv", + .cbs = { + .modify = zebra_debugs_debug_kernel_msg_recv_modify, + .destroy = zebra_debugs_debug_kernel_msg_recv_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-rib", + .cbs = { + .modify = zebra_debugs_debug_rib_modify, + .destroy = zebra_debugs_debug_rib_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-rib-detail", + .cbs = { + .modify = zebra_debugs_debug_rib_detail_modify, + .destroy = zebra_debugs_debug_rib_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-fpm", + .cbs = { + .modify = zebra_debugs_debug_fpm_modify, + .destroy = zebra_debugs_debug_fpm_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-nht", + .cbs = { + .modify = zebra_debugs_debug_nht_modify, + .destroy = zebra_debugs_debug_nht_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-nht-detail", + .cbs = { + .modify = zebra_debugs_debug_nht_detail_modify, + .destroy = zebra_debugs_debug_nht_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-mpls", + .cbs = { + .modify = zebra_debugs_debug_mpls_modify, + .destroy = zebra_debugs_debug_mpls_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-vxlan", + .cbs = { + .modify = zebra_debugs_debug_vxlan_modify, + .destroy = zebra_debugs_debug_vxlan_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-pw", + .cbs = { + .modify = zebra_debugs_debug_pw_modify, + .destroy = zebra_debugs_debug_pw_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-dplane", + .cbs = { + .modify = zebra_debugs_debug_dplane_modify, + .destroy = zebra_debugs_debug_dplane_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-dplane-detail", + .cbs = { + .modify = zebra_debugs_debug_dplane_detail_modify, + .destroy = zebra_debugs_debug_dplane_detail_destroy, + } + }, + { + .xpath = "/frr-zebra:zebra/debugs/debug-mlag", + .cbs = { + .modify = zebra_debugs_debug_mlag_modify, + .destroy = zebra_debugs_debug_mlag_destroy, + } + }, + { + .xpath = "/frr-zebra:get-route-information", + .cbs = { + .rpc = get_route_information_rpc, + } + }, + { + .xpath = "/frr-zebra:get-v6-mroute-info", + .cbs = { + .rpc = get_v6_mroute_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-vrf-info", + .cbs = { + .rpc = get_vrf_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-vrf-vni-info", + .cbs = { + .rpc = get_vrf_vni_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-info", + .cbs = { + .rpc = get_evpn_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-vni-info", + .cbs = { + .rpc = get_vni_info_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-vni-rmac", + .cbs = { + .rpc = get_evpn_vni_rmac_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-vni-nexthops", + .cbs = { + .rpc = get_evpn_vni_nexthops_rpc, + } + }, + { + .xpath = "/frr-zebra:clear-evpn-dup-addr", + .cbs = { + .rpc = clear_evpn_dup_addr_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-macs", + .cbs = { + .rpc = get_evpn_macs_rpc, + } + }, + { + .xpath = "/frr-zebra:get-evpn-arp-cache", + .cbs = { + .rpc = get_evpn_arp_cache_rpc, + } + }, + { + .xpath = "/frr-zebra:get-pbr-ipset", + .cbs = { + .rpc = get_pbr_ipset_rpc, + } + }, + { + .xpath = "/frr-zebra:get-pbr-iptable", + .cbs = { + .rpc = get_pbr_iptable_rpc, + } + }, + { + .xpath = "/frr-zebra:get-debugs", + .cbs = { + .rpc = get_debugs_rpc, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip-addrs", + .cbs = { + .create = lib_interface_zebra_ip_addrs_create, + .destroy = lib_interface_zebra_ip_addrs_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/label", + .cbs = { + .modify = lib_interface_zebra_ip_addrs_label_modify, + .destroy = lib_interface_zebra_ip_addrs_label_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/ip4-peer", + .cbs = { + .modify = lib_interface_zebra_ip_addrs_ip4_peer_modify, + .destroy = lib_interface_zebra_ip_addrs_ip4_peer_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/multicast", + .cbs = { + .modify = lib_interface_zebra_multicast_modify, + .destroy = lib_interface_zebra_multicast_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-detect", + .cbs = { + .modify = lib_interface_zebra_link_detect_modify, + .destroy = lib_interface_zebra_link_detect_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/shutdown", + .cbs = { + .modify = lib_interface_zebra_shutdown_modify, + .destroy = lib_interface_zebra_shutdown_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/bandwidth", + .cbs = { + .modify = lib_interface_zebra_bandwidth_modify, + .destroy = lib_interface_zebra_bandwidth_destroy, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/up-count", + .cbs = { + .get_elem = lib_interface_zebra_state_up_count_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/down-count", + .cbs = { + .get_elem = lib_interface_zebra_state_down_count_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/zif-type", + .cbs = { + .get_elem = lib_interface_zebra_state_zif_type_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/ptm-status", + .cbs = { + .get_elem = lib_interface_zebra_state_ptm_status_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/vlan-id", + .cbs = { + .get_elem = lib_interface_zebra_state_vlan_id_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/vni-id", + .cbs = { + .get_elem = lib_interface_zebra_state_vni_id_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/remote-vtep", + .cbs = { + .get_elem = lib_interface_zebra_state_remote_vtep_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/state/mcast-group", + .cbs = { + .get_elem = lib_interface_zebra_state_mcast_group_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib", + .cbs = { + .create = lib_vrf_ribs_rib_create, + .destroy = lib_vrf_ribs_rib_destroy, + .get_next = lib_vrf_ribs_rib_get_next, + .get_keys = lib_vrf_ribs_rib_get_keys, + .lookup_entry = lib_vrf_ribs_rib_lookup_entry, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route", + .cbs = { + .get_next = lib_vrf_ribs_rib_route_get_next, + .get_keys = lib_vrf_ribs_rib_route_get_keys, + .lookup_entry = lib_vrf_ribs_rib_route_lookup_entry, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/prefix", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_prefix_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry", + .cbs = { + .get_next = lib_vrf_ribs_rib_route_route_entry_get_next, + .get_keys = lib_vrf_ribs_rib_route_route_entry_get_keys, + .lookup_entry = lib_vrf_ribs_rib_route_route_entry_lookup_entry, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/protocol", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_protocol_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/instance", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_instance_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/distance", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_distance_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/metric", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_metric_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/tag", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_tag_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/selected", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_selected_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/installed", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_installed_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/failed", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_failed_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/queued", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_queued_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/internal-flags", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_internal_flags_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/internal-status", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_internal_status_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/uptime", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_uptime_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group", + .cbs = { + .get_next = lib_vrf_ribs_rib_route_route_entry_nexthop_group_get_next, + .get_keys = lib_vrf_ribs_rib_route_route_entry_nexthop_group_get_keys, + .lookup_entry = lib_vrf_ribs_rib_route_route_entry_nexthop_group_lookup_entry, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/name", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_name_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop", + .cbs = { + .get_next = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_next, + .get_keys = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_keys, + .lookup_entry = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_lookup_entry, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/nh-type", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_nh_type_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/vrf", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_vrf_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/gateway", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_gateway_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/interface", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_interface_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/bh-type", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_bh_type_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/onlink", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_onlink_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry", + .cbs = { + .get_next = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_get_next, + .get_keys = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_get_keys, + .lookup_entry = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_lookup_entry, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/id", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_id_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/label", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_label_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/ttl", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/duplicate", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_duplicate_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/recursive", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_recursive_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/active", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_active_get_elem, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/fib", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_fib_get_elem, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length", + .cbs = { + .modify = lib_route_map_entry_match_condition_ipv4_prefix_length_modify, + .destroy = lib_route_map_entry_match_condition_ipv4_prefix_length_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv6-prefix-length", + .cbs = { + .modify = lib_route_map_entry_match_condition_ipv6_prefix_length_modify, + .destroy = lib_route_map_entry_match_condition_ipv6_prefix_length_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-protocol", + .cbs = { + .modify = lib_route_map_entry_match_condition_source_protocol_modify, + .destroy = lib_route_map_entry_match_condition_source_protocol_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-instance", + .cbs = { + .modify = lib_route_map_entry_match_condition_source_instance_modify, + .destroy = lib_route_map_entry_match_condition_source_instance_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v4", + .cbs = { + .modify = lib_route_map_entry_set_action_source_v4_modify, + .destroy = lib_route_map_entry_set_action_source_v4_destroy, + } + }, + { + .xpath = "/frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v6", + .cbs = { + .modify = lib_route_map_entry_set_action_source_v6_modify, + .destroy = lib_route_map_entry_set_action_source_v6_destroy, + } + }, + { + .xpath = "/frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/weight", + .cbs = { + .get_elem = lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_weight_get_elem, + } + }, + { + .xpath = NULL, + }, + } +}; diff --git a/zebra/zebra_nb.h b/zebra/zebra_nb.h new file mode 100644 index 0000000000..09a9edff99 --- /dev/null +++ b/zebra/zebra_nb.h @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2020 Cumulus Networks, Inc. + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ZEBRA_ZEBRA_NB_H_ +#define ZEBRA_ZEBRA_NB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern const struct frr_yang_module_info frr_zebra_info; + +/* prototypes */ +int get_route_information_rpc(struct nb_cb_rpc_args *args); +int get_v6_mroute_info_rpc(struct nb_cb_rpc_args *args); +int get_vrf_info_rpc(struct nb_cb_rpc_args *args); +int get_vrf_vni_info_rpc(struct nb_cb_rpc_args *args); +int get_evpn_info_rpc(struct nb_cb_rpc_args *args); +int get_vni_info_rpc(struct nb_cb_rpc_args *args); +int get_evpn_vni_rmac_rpc(struct nb_cb_rpc_args *args); +int get_evpn_vni_nexthops_rpc(struct nb_cb_rpc_args *args); +int clear_evpn_dup_addr_rpc(struct nb_cb_rpc_args *args); +int get_evpn_macs_rpc(struct nb_cb_rpc_args *args); +int get_evpn_arp_cache_rpc(struct nb_cb_rpc_args *args); +int get_pbr_ipset_rpc(struct nb_cb_rpc_args *args); +int get_pbr_iptable_rpc(struct nb_cb_rpc_args *args); +int get_debugs_rpc(struct nb_cb_rpc_args *args); +int zebra_mcast_rpf_lookup_modify(struct nb_cb_modify_args *args); +int zebra_ip_forwarding_modify(struct nb_cb_modify_args *args); +int zebra_ip_forwarding_destroy(struct nb_cb_destroy_args *args); +int zebra_ipv6_forwarding_modify(struct nb_cb_modify_args *args); +int zebra_ipv6_forwarding_destroy(struct nb_cb_destroy_args *args); +int zebra_workqueue_hold_timer_modify(struct nb_cb_modify_args *args); +int zebra_zapi_packets_modify(struct nb_cb_modify_args *args); +int zebra_import_kernel_table_table_id_modify(struct nb_cb_modify_args *args); +int zebra_import_kernel_table_table_id_destroy(struct nb_cb_destroy_args *args); +int zebra_import_kernel_table_distance_modify(struct nb_cb_modify_args *args); +int zebra_import_kernel_table_route_map_modify(struct nb_cb_modify_args *args); +int zebra_import_kernel_table_route_map_destroy( + struct nb_cb_destroy_args *args); +int zebra_allow_external_route_update_create(struct nb_cb_create_args *args); +int zebra_allow_external_route_update_destroy(struct nb_cb_destroy_args *args); +int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args); +int zebra_vrf_vni_mapping_create(struct nb_cb_create_args *args); +int zebra_vrf_vni_mapping_destroy(struct nb_cb_destroy_args *args); +int zebra_vrf_vni_mapping_vni_id_modify(struct nb_cb_modify_args *args); +int zebra_vrf_vni_mapping_vni_id_destroy(struct nb_cb_destroy_args *args); +int zebra_vrf_vni_mapping_prefix_only_create(struct nb_cb_create_args *args); +int zebra_vrf_vni_mapping_prefix_only_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_events_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_events_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_zapi_send_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_zapi_send_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_zapi_recv_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_zapi_recv_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_zapi_detail_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_zapi_detail_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_kernel_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_kernel_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_kernel_msg_send_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_kernel_msg_send_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_kernel_msg_recv_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_kernel_msg_recv_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_rib_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_rib_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_rib_detail_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_rib_detail_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_fpm_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_fpm_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_nht_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_nht_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_nht_detail_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_nht_detail_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_mpls_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_mpls_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_vxlan_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_vxlan_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_pw_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_pw_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_dplane_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_dplane_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_dplane_detail_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_dplane_detail_destroy(struct nb_cb_destroy_args *args); +int zebra_debugs_debug_mlag_modify(struct nb_cb_modify_args *args); +int zebra_debugs_debug_mlag_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args); +int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_ip_addrs_label_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_ip_addrs_ip4_peer_modify( + struct nb_cb_modify_args *args); +int lib_interface_zebra_ip_addrs_ip4_peer_destroy( + struct nb_cb_destroy_args *args); +int lib_interface_zebra_multicast_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_multicast_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_link_detect_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_shutdown_destroy(struct nb_cb_destroy_args *args); +int lib_interface_zebra_bandwidth_modify(struct nb_cb_modify_args *args); +int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args); +int lib_route_map_entry_match_condition_ipv4_prefix_length_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_ipv4_prefix_length_destroy( + struct nb_cb_destroy_args *args); +int lib_route_map_entry_match_condition_ipv6_prefix_length_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_ipv6_prefix_length_destroy( + struct nb_cb_destroy_args *args); +int lib_route_map_entry_match_condition_source_protocol_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_source_protocol_destroy( + struct nb_cb_destroy_args *args); +int lib_route_map_entry_match_condition_source_instance_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_match_condition_source_instance_destroy( + struct nb_cb_destroy_args *args); +int lib_route_map_entry_set_action_source_v4_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_set_action_source_v4_destroy( + struct nb_cb_destroy_args *args); +int lib_route_map_entry_set_action_source_v6_modify( + struct nb_cb_modify_args *args); +int lib_route_map_entry_set_action_source_v6_destroy( + struct nb_cb_destroy_args *args); +struct yang_data * +lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_zebra_state_down_count_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_zebra_state_zif_type_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_zebra_state_ptm_status_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_zebra_state_vlan_id_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_zebra_state_vni_id_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data *lib_interface_zebra_state_remote_vtep_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_interface_zebra_state_mcast_group_get_elem( + struct nb_cb_get_elem_args *args); +int lib_vrf_ribs_rib_create(struct nb_cb_create_args *args); +int lib_vrf_ribs_rib_destroy(struct nb_cb_destroy_args *args); +const void *lib_vrf_ribs_rib_get_next(struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_get_keys(struct nb_cb_get_keys_args *args); +const void *lib_vrf_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args); +const void *lib_vrf_ribs_rib_route_get_next(struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args); +const void * +lib_vrf_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_protocol_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_protocol_v6_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_vrf_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_distance_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_metric_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_tag_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_selected_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_installed_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_failed_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_queued_get_elem(struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_internal_flags_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_internal_status_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_uptime_get_elem(struct nb_cb_get_elem_args *args); +const void * +lib_vrf_ribs_rib_route_nexthop_group_get_next(struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_nexthop_group_get_keys( + struct nb_cb_get_keys_args *args); +const void *lib_vrf_ribs_rib_route_nexthop_group_lookup_entry( + struct nb_cb_lookup_entry_args *args); +struct yang_data *lib_vrf_ribs_rib_route_nexthop_group_name_get_elem( + struct nb_cb_get_elem_args *args); +const void *lib_vrf_ribs_rib_route_nexthop_group_frr_nexthops_nexthop_get_next( + struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_nexthop_group_frr_nexthops_nexthop_get_keys( + struct nb_cb_get_keys_args *args); +int lib_vrf_ribs_rib_create(struct nb_cb_create_args *args); +int lib_vrf_ribs_rib_destroy(struct nb_cb_destroy_args *args); +const void *lib_vrf_ribs_rib_get_next(struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_get_keys(struct nb_cb_get_keys_args *args); +const void *lib_vrf_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args); +const void *lib_vrf_ribs_rib_route_get_next(struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args); +const void * +lib_vrf_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args); +const void * +lib_vrf_ribs_rib_route_route_entry_get_next(struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_route_entry_get_keys( + struct nb_cb_get_keys_args *args); +const void *lib_vrf_ribs_rib_route_route_entry_lookup_entry( + struct nb_cb_lookup_entry_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_protocol_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_instance_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_distance_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_metric_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_tag_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_selected_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_installed_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_failed_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_queued_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_internal_flags_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_internal_status_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data *lib_vrf_ribs_rib_route_route_entry_uptime_get_elem( + struct nb_cb_get_elem_args *args); +const void *lib_vrf_ribs_rib_route_route_entry_nexthop_group_get_next( + struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_route_entry_nexthop_group_get_keys( + struct nb_cb_get_keys_args *args); +const void *lib_vrf_ribs_rib_route_route_entry_nexthop_group_lookup_entry( + struct nb_cb_lookup_entry_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_name_get_elem( + struct nb_cb_get_elem_args *args); +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_next( + struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_keys( + struct nb_cb_get_keys_args *args); +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_lookup_entry( + struct nb_cb_lookup_entry_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_nh_type_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_vrf_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_gateway_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_interface_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_bh_type_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_onlink_get_elem( + struct nb_cb_get_elem_args *args); +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_get_next( + struct nb_cb_get_next_args *args); +int lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_get_keys( + struct nb_cb_get_keys_args *args); +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_lookup_entry( + struct nb_cb_lookup_entry_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_id_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_label_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_duplicate_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_recursive_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_active_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_fib_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_weight_get_elem( + struct nb_cb_get_elem_args *args); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c new file mode 100644 index 0000000000..dbe265da8c --- /dev/null +++ b/zebra/zebra_nb_config.c @@ -0,0 +1,1559 @@ +/* + * Copyright (C) 2019 Cumulus Networks, Inc. + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> + +#include "lib/log.h" +#include "lib/northbound.h" +#include "libfrr.h" +#include "lib/command.h" +#include "lib/routemap.h" +#include "zebra/zebra_nb.h" +#include "zebra/rib.h" +#include "zebra_nb.h" +#include "zebra/interface.h" +#include "zebra/connected.h" + +/* + * XPath: /frr-zebra:zebra/mcast-rpf-lookup + */ +int zebra_mcast_rpf_lookup_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/ip-forwarding + */ +int zebra_ip_forwarding_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_ip_forwarding_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/ipv6-forwarding + */ +int zebra_ipv6_forwarding_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_ipv6_forwarding_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/workqueue-hold-timer + */ +int zebra_workqueue_hold_timer_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/zapi-packets + */ +int zebra_zapi_packets_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/import-kernel-table/table-id + */ +int zebra_import_kernel_table_table_id_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_import_kernel_table_table_id_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/import-kernel-table/distance + */ +int zebra_import_kernel_table_distance_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/import-kernel-table/route-map + */ +int zebra_import_kernel_table_route_map_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_import_kernel_table_route_map_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/allow-external-route-update + */ +int zebra_allow_external_route_update_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_allow_external_route_update_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/dplane-queue-limit + */ +int zebra_dplane_queue_limit_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/vrf-vni-mapping + */ +int zebra_vrf_vni_mapping_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_vrf_vni_mapping_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/vrf-vni-mapping/vni-id + */ +int zebra_vrf_vni_mapping_vni_id_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_vrf_vni_mapping_vni_id_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/vrf-vni-mapping/prefix-only + */ +int zebra_vrf_vni_mapping_prefix_only_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_vrf_vni_mapping_prefix_only_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-events + */ +int zebra_debugs_debug_events_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_events_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-zapi-send + */ +int zebra_debugs_debug_zapi_send_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_zapi_send_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-zapi-recv + */ +int zebra_debugs_debug_zapi_recv_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_zapi_recv_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-zapi-detail + */ +int zebra_debugs_debug_zapi_detail_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_zapi_detail_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-kernel + */ +int zebra_debugs_debug_kernel_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_kernel_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-send + */ +int zebra_debugs_debug_kernel_msg_send_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_kernel_msg_send_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-recv + */ +int zebra_debugs_debug_kernel_msg_recv_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_kernel_msg_recv_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-rib + */ +int zebra_debugs_debug_rib_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_rib_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-rib-detail + */ +int zebra_debugs_debug_rib_detail_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_rib_detail_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-fpm + */ +int zebra_debugs_debug_fpm_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_fpm_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-nht + */ +int zebra_debugs_debug_nht_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_nht_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-nht-detail + */ +int zebra_debugs_debug_nht_detail_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_nht_detail_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-mpls + */ +int zebra_debugs_debug_mpls_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_mpls_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-vxlan + */ +int zebra_debugs_debug_vxlan_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_vxlan_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-pw + */ +int zebra_debugs_debug_pw_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_pw_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-dplane + */ +int zebra_debugs_debug_dplane_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_dplane_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-dplane-detail + */ +int zebra_debugs_debug_dplane_detail_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_dplane_detail_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-zebra:zebra/debugs/debug-mlag + */ +int zebra_debugs_debug_mlag_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int zebra_debugs_debug_mlag_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs + */ +int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args) +{ + struct interface *ifp; + struct prefix prefix; + char buf[PREFIX_STRLEN] = {0}; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + // addr_family = yang_dnode_get_enum(dnode, "./address-family"); + yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix"); + apply_mask(&prefix); + + switch (args->event) { + case NB_EV_VALIDATE: + if (prefix.family == AF_INET + && ipv4_martian(&prefix.u.prefix4)) { + zlog_debug("invalid address %s", + prefix2str(&prefix, buf, sizeof(buf))); + return NB_ERR_VALIDATION; + } else if (prefix.family == AF_INET6 + && ipv6_martian(&prefix.u.prefix6)) { + zlog_debug("invalid address %s", + prefix2str(&prefix, buf, sizeof(buf))); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if (prefix.family == AF_INET) + if_ip_address_install(ifp, &prefix, NULL, NULL); + else if (prefix.family == AF_INET6) + if_ipv6_address_install(ifp, &prefix, NULL); + + break; + } + + return NB_OK; +} + +int lib_interface_zebra_ip_addrs_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + struct prefix prefix; + struct connected *ifc; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + yang_dnode_get_prefix(&prefix, args->dnode, "./ip-prefix"); + apply_mask(&prefix); + + switch (args->event) { + case NB_EV_VALIDATE: + if (prefix.family == AF_INET) { + /* Check current interface address. */ + ifc = connected_check_ptp(ifp, &prefix, NULL); + if (!ifc) { + zlog_debug("interface %s Can't find address\n", + ifp->name); + return NB_ERR_VALIDATION; + } + } else if (prefix.family == AF_INET6) { + /* Check current interface address. */ + ifc = connected_check(ifp, &prefix); + if (!ifc) { + zlog_debug("interface can't find address %s", + ifp->name); + return NB_ERR_VALIDATION; + } + } else + return NB_ERR_VALIDATION; + + /* This is not configured address. */ + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) { + zlog_debug("interface %s not configured", ifp->name); + return NB_ERR_VALIDATION; + } + + /* This is not real address or interface is not active. */ + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) + || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { + listnode_delete(ifp->connected, ifc); + connected_free(&ifc); + return NB_ERR_VALIDATION; + } + break; + case NB_EV_PREPARE: + case NB_EV_ABORT: + break; + case NB_EV_APPLY: + if_ip_address_uinstall(ifp, &prefix); + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/label + */ +int lib_interface_zebra_ip_addrs_label_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int lib_interface_zebra_ip_addrs_label_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip-addrs/ip4-peer + */ +int lib_interface_zebra_ip_addrs_ip4_peer_modify(struct nb_cb_modify_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int lib_interface_zebra_ip_addrs_ip4_peer_destroy( + struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/multicast + */ +int lib_interface_zebra_multicast_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct interface *ifp; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + if_multicast_set(ifp); + + return NB_OK; +} + +int lib_interface_zebra_multicast_destroy(struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct interface *ifp; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + if_multicast_unset(ifp); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-detect + */ +int lib_interface_zebra_link_detect_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct interface *ifp; + bool link_detect; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + link_detect = yang_dnode_get_bool(args->dnode, "./link-detect"); + + if_linkdetect(ifp, link_detect); + + return NB_OK; +} + +int lib_interface_zebra_link_detect_destroy(struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct interface *ifp; + bool link_detect; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + link_detect = yang_dnode_get_bool(args->dnode, "./link-detect"); + + if_linkdetect(ifp, link_detect); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/shutdown + */ +int lib_interface_zebra_shutdown_modify(struct nb_cb_modify_args *args) +{ + struct interface *ifp; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + if_shutdown(ifp); + + return NB_OK; +} + +int lib_interface_zebra_shutdown_destroy(struct nb_cb_destroy_args *args) +{ + struct interface *ifp; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + if_no_shutdown(ifp); + + return NB_OK; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/bandwidth + */ +int lib_interface_zebra_bandwidth_modify(struct nb_cb_modify_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct interface *ifp; + uint32_t bandwidth; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + bandwidth = yang_dnode_get_uint32(args->dnode, "./bandwidth"); + + ifp->bandwidth = bandwidth; + + /* force protocols to recalculate routes due to cost change */ + if (if_is_operative(ifp)) + zebra_interface_up_update(ifp); + + return NB_OK; +} + +int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args) +{ + if (args->event != NB_EV_APPLY) + return NB_OK; + + struct interface *ifp; + + ifp = nb_running_get_entry(args->dnode, NULL, true); + + ifp->bandwidth = 0; + + /* force protocols to recalculate routes due to cost change */ + if (if_is_operative(ifp)) + zebra_interface_up_update(ifp); + + return NB_OK; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib + */ +int lib_vrf_ribs_rib_create(struct nb_cb_create_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + +int lib_vrf_ribs_rib_destroy(struct nb_cb_destroy_args *args) +{ + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + case NB_EV_APPLY: + /* TODO: implement me. */ + break; + } + + return NB_OK; +} + + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length + */ +int lib_route_map_entry_match_condition_ipv4_prefix_length_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *length; + int condition, rv; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + length = yang_dnode_get_string(args->dnode, NULL); + condition = + yang_dnode_get_enum(args->dnode, "../frr-route-map:condition"); + + /* Set destroy information. */ + switch (condition) { + case 100: /* ipv4-prefix-length */ + rhc->rhc_rule = "ip address prefix-len"; + break; + + case 102: /* ipv4-next-hop-prefix-length */ + rhc->rhc_rule = "ip next-hop prefix-len"; + break; + } + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, rhc->rhc_rule, length, + RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_ipv4_prefix_length_destroy( + struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_match_destroy(args); +} + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv6-prefix-length + */ +int lib_route_map_entry_match_condition_ipv6_prefix_length_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *length; + int rv; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + length = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_rule = "ipv6 address prefix-len"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, "ipv6 address prefix-len", + length, RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_ipv6_prefix_length_destroy( + struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_match_destroy(args); +} + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-protocol + */ +int lib_route_map_entry_match_condition_source_protocol_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *type; + int rv; + + switch (args->event) { + case NB_EV_VALIDATE: + type = yang_dnode_get_string(args->dnode, NULL); + if (proto_name2num(type) == -1) { + zlog_warn("%s: invalid protocol: %s", __func__, type); + return NB_ERR_VALIDATION; + } + return NB_OK; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + /* NOTHING */ + break; + } + + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_rule = "source-protocol"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, "source-protocol", type, + RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_source_protocol_destroy( + struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_match_destroy(args); +} + +/* + * XPath: + * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-instance + */ +int lib_route_map_entry_match_condition_source_instance_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + const char *type; + int rv; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + type = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_mhook = generic_match_delete; + rhc->rhc_rule = "source-instance"; + rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; + + rv = generic_match_add(NULL, rhc->rhc_rmi, "source-instance", type, + RMAP_EVENT_MATCH_ADDED); + if (rv != CMD_SUCCESS) { + rhc->rhc_mhook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +int lib_route_map_entry_match_condition_source_instance_destroy( + struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_match_destroy(args); +} + +/* + * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v4 + */ +int lib_route_map_entry_set_action_source_v4_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + struct interface *pif = NULL; + const char *source; + struct vrf *vrf; + struct prefix p; + int rv; + + switch (args->event) { + case NB_EV_VALIDATE: + memset(&p, 0, sizeof(p)); + yang_dnode_get_ipv4p(&p, args->dnode, NULL); + if (zebra_check_addr(&p) == 0) { + zlog_warn("%s: invalid IPv4 address: %s", __func__, + yang_dnode_get_string(args->dnode, NULL)); + return NB_ERR_VALIDATION; + } + + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { + pif = if_lookup_exact_address(&p.u.prefix4, AF_INET, + vrf->vrf_id); + if (pif != NULL) + break; + } + if (pif == NULL) { + zlog_warn("%s: is not a local adddress: %s", __func__, + yang_dnode_get_string(args->dnode, NULL)); + return NB_ERR_VALIDATION; + } + return NB_OK; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + /* NOTHING */ + break; + } + + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + source = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_shook = generic_set_delete; + rhc->rhc_rule = "src"; + + rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source); + if (rv != CMD_SUCCESS) { + rhc->rhc_shook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +int lib_route_map_entry_set_action_source_v4_destroy( + struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_set_destroy(args); +} + +/* + * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v6 + */ +int lib_route_map_entry_set_action_source_v6_modify( + struct nb_cb_modify_args *args) +{ + struct routemap_hook_context *rhc; + struct interface *pif = NULL; + const char *source; + struct vrf *vrf; + struct prefix p; + int rv; + + switch (args->event) { + case NB_EV_VALIDATE: + memset(&p, 0, sizeof(p)); + yang_dnode_get_ipv6p(&p, args->dnode, NULL); + if (zebra_check_addr(&p) == 0) { + zlog_warn("%s: invalid IPv6 address: %s", __func__, + yang_dnode_get_string(args->dnode, NULL)); + return NB_ERR_VALIDATION; + } + + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { + pif = if_lookup_exact_address(&p.u.prefix6, AF_INET6, + vrf->vrf_id); + if (pif != NULL) + break; + } + if (pif == NULL) { + zlog_warn("%s: is not a local adddress: %s", __func__, + yang_dnode_get_string(args->dnode, NULL)); + return NB_ERR_VALIDATION; + } + return NB_OK; + case NB_EV_PREPARE: + case NB_EV_ABORT: + return NB_OK; + case NB_EV_APPLY: + /* NOTHING */ + break; + } + + /* Add configuration. */ + rhc = nb_running_get_entry(args->dnode, NULL, true); + source = yang_dnode_get_string(args->dnode, NULL); + + /* Set destroy information. */ + rhc->rhc_shook = generic_set_delete; + rhc->rhc_rule = "src"; + + rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source); + if (rv != CMD_SUCCESS) { + rhc->rhc_shook = NULL; + return NB_ERR_INCONSISTENCY; + } + + return NB_OK; +} + +int lib_route_map_entry_set_action_source_v6_destroy( + struct nb_cb_destroy_args *args) +{ + return lib_route_map_entry_set_destroy(args); +} diff --git a/zebra/zebra_nb_rpcs.c b/zebra/zebra_nb_rpcs.c new file mode 100644 index 0000000000..204cc5da6d --- /dev/null +++ b/zebra/zebra_nb_rpcs.c @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2020 Cumulus Networks, Inc. + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> +#include "northbound.h" +#include "libfrr.h" + +#include "zebra/zebra_nb.h" +#include "zebra/zebra_router.h" +#include "zebra/zebra_vrf.h" +#include "zebra/zebra_vxlan.h" + +/* + * XPath: /frr-zebra:clear-evpn-dup-addr + */ +int clear_evpn_dup_addr_rpc(struct nb_cb_rpc_args *args) +{ + struct zebra_vrf *zvrf; + int ret = NB_OK; + struct yang_data *yang_dup_choice = NULL, *yang_dup_vni = NULL, + *yang_dup_ip = NULL, *yang_dup_mac = NULL; + + yang_dup_choice = yang_data_list_find(args->input, "%s/%s", args->xpath, + "input/clear-dup-choice"); + + zvrf = zebra_vrf_get_evpn(); + + if (yang_dup_choice + && strcmp(yang_dup_choice->value, "all-case") == 0) { + zebra_vxlan_clear_dup_detect_vni_all(zvrf); + } else { + vni_t vni; + struct ipaddr host_ip = {.ipa_type = IPADDR_NONE}; + struct ethaddr mac; + + yang_dup_vni = yang_data_list_find( + args->input, "%s/%s", args->xpath, + "input/clear-dup-choice/single-case/vni-id"); + if (yang_dup_vni) { + vni = yang_str2uint32(yang_dup_vni->value); + + yang_dup_mac = yang_data_list_find( + args->input, "%s/%s", args->xpath, + "input/clear-dup-choice/single-case/vni-id/mac-addr"); + yang_dup_ip = yang_data_list_find( + args->input, "%s/%s", args->xpath, + "input/clear-dup-choice/single-case/vni-id/vni-ipaddr"); + + if (yang_dup_mac) { + yang_str2mac(yang_dup_mac->value, &mac); + ret = zebra_vxlan_clear_dup_detect_vni_mac( + zvrf, vni, &mac); + } else if (yang_dup_ip) { + yang_str2ip(yang_dup_ip->value, &host_ip); + ret = zebra_vxlan_clear_dup_detect_vni_ip( + zvrf, vni, &host_ip); + } else + ret = zebra_vxlan_clear_dup_detect_vni(zvrf, + vni); + } + } + ret = (ret != CMD_SUCCESS) ? NB_ERR : NB_OK; + + return ret; +} + +/* + * XPath: /frr-zebra:get-route-information + */ +int get_route_information_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-v6-mroute-info + */ +int get_v6_mroute_info_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-vrf-info + */ +int get_vrf_info_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-vrf-vni-info + */ +int get_vrf_vni_info_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-info + */ +int get_evpn_info_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-vni-info + */ +int get_vni_info_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-vni-rmac + */ +int get_evpn_vni_rmac_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-vni-nexthops + */ +int get_evpn_vni_nexthops_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-macs + */ +int get_evpn_macs_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-evpn-arp-cache + */ +int get_evpn_arp_cache_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-pbr-ipset + */ +int get_pbr_ipset_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-pbr-iptable + */ +int get_pbr_iptable_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} + +/* + * XPath: /frr-zebra:get-debugs + */ +int get_debugs_rpc(struct nb_cb_rpc_args *args) +{ + /* TODO: implement me. */ + return NB_ERR_NOT_FOUND; +} diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c new file mode 100644 index 0000000000..09c76e6022 --- /dev/null +++ b/zebra/zebra_nb_state.c @@ -0,0 +1,612 @@ +/* + * Copyright (C) 2020 Cumulus Networks, Inc. + * Chirag Shah + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <zebra.h> +#include "northbound.h" +#include "libfrr.h" +#include "zebra_nb.h" +#include "zebra/interface.h" + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count + */ +struct yang_data * +lib_interface_zebra_state_up_count_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + struct zebra_if *zebra_if; + + zebra_if = ifp->info; + + return yang_data_new_uint16(args->xpath, zebra_if->up_count); +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/down-count + */ +struct yang_data * +lib_interface_zebra_state_down_count_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + struct zebra_if *zebra_if; + + zebra_if = ifp->info; + + return yang_data_new_uint16(args->xpath, zebra_if->down_count); +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/zif-type + */ +struct yang_data * +lib_interface_zebra_state_zif_type_get_elem(struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/ptm-status + */ +struct yang_data * +lib_interface_zebra_state_ptm_status_get_elem(struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vlan-id + */ +struct yang_data * +lib_interface_zebra_state_vlan_id_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + struct zebra_if *zebra_if; + struct zebra_l2info_vlan *vlan_info; + + if (!IS_ZEBRA_IF_VLAN(ifp)) + return NULL; + + zebra_if = ifp->info; + vlan_info = &zebra_if->l2info.vl; + + return yang_data_new_uint16(args->xpath, vlan_info->vid); +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/vni-id + */ +struct yang_data * +lib_interface_zebra_state_vni_id_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + struct zebra_if *zebra_if; + struct zebra_l2info_vxlan *vxlan_info; + + if (!IS_ZEBRA_IF_VXLAN(ifp)) + return NULL; + + zebra_if = ifp->info; + vxlan_info = &zebra_if->l2info.vxl; + + return yang_data_new_uint32(args->xpath, vxlan_info->vni); +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/remote-vtep + */ +struct yang_data * +lib_interface_zebra_state_remote_vtep_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + struct zebra_if *zebra_if; + struct zebra_l2info_vxlan *vxlan_info; + + if (!IS_ZEBRA_IF_VXLAN(ifp)) + return NULL; + + zebra_if = ifp->info; + vxlan_info = &zebra_if->l2info.vxl; + + return yang_data_new_ipv4(args->xpath, &vxlan_info->vtep_ip); +} + +/* + * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/mcast-group + */ +struct yang_data * +lib_interface_zebra_state_mcast_group_get_elem(struct nb_cb_get_elem_args *args) +{ + const struct interface *ifp = args->list_entry; + struct zebra_if *zebra_if; + struct zebra_l2info_vxlan *vxlan_info; + + if (!IS_ZEBRA_IF_VXLAN(ifp)) + return NULL; + + zebra_if = ifp->info; + vxlan_info = &zebra_if->l2info.vxl; + + return yang_data_new_ipv4(args->xpath, &vxlan_info->mcast_grp); +} + +const void *lib_vrf_ribs_rib_get_next(struct nb_cb_get_next_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +int lib_vrf_ribs_rib_get_keys(struct nb_cb_get_keys_args *args) +{ + /* TODO: implement me. */ + return NB_OK; +} + +const void *lib_vrf_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route + */ +const void *lib_vrf_ribs_rib_route_get_next(struct nb_cb_get_next_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +int lib_vrf_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args) +{ + /* TODO: implement me. */ + return NB_OK; +} + +const void * +lib_vrf_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/prefix + */ +struct yang_data * +lib_vrf_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry + */ +const void * +lib_vrf_ribs_rib_route_route_entry_get_next(struct nb_cb_get_next_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +int lib_vrf_ribs_rib_route_route_entry_get_keys( + struct nb_cb_get_keys_args *args) +{ + /* TODO: implement me. */ + return NB_OK; +} + +const void *lib_vrf_ribs_rib_route_route_entry_lookup_entry( + struct nb_cb_lookup_entry_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/protocol + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_protocol_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/instance + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_instance_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/distance + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_distance_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/metric + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_metric_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/tag + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_tag_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/selected + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_selected_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/installed + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_installed_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/failed + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_failed_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/queued + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_queued_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/internal-flags + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_internal_flags_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/internal-status + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_internal_status_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/uptime + */ +struct yang_data *lib_vrf_ribs_rib_route_route_entry_uptime_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group + */ +const void *lib_vrf_ribs_rib_route_route_entry_nexthop_group_get_next( + struct nb_cb_get_next_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +int lib_vrf_ribs_rib_route_route_entry_nexthop_group_get_keys( + struct nb_cb_get_keys_args *args) +{ + /* TODO: implement me. */ + return NB_OK; +} + +const void *lib_vrf_ribs_rib_route_route_entry_nexthop_group_lookup_entry( + struct nb_cb_lookup_entry_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/name + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_name_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop + */ +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_next( + struct nb_cb_get_next_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +int lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_keys( + struct nb_cb_get_keys_args *args) +{ + /* TODO: implement me. */ + return NB_OK; +} + +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_lookup_entry( + struct nb_cb_lookup_entry_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/nh-type + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_nh_type_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/vrf + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_vrf_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/gateway + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_gateway_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/interface + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_interface_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/bh-type + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_bh_type_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/onlink + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_onlink_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry + */ +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_get_next( + struct nb_cb_get_next_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +int lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_get_keys( + struct nb_cb_get_keys_args *args) +{ + /* TODO: implement me. */ + return NB_OK; +} + +const void * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_lookup_entry( + struct nb_cb_lookup_entry_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/id + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_id_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/label + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_label_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/ttl + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/duplicate + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_duplicate_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/recursive + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_recursive_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/active + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_active_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/fib + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_fib_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} + +/* + * XPath: + * /frr-vrf:lib/vrf/frr-zebra:ribs/rib/route/route-entry/nexthop-group/frr-nexthops/nexthop/weight + */ +struct yang_data * +lib_vrf_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_weight_get_elem( + struct nb_cb_get_elem_args *args) +{ + /* TODO: implement me. */ + return NULL; +} diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index d42cf3d60a..c5d11f1837 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -153,10 +153,10 @@ static int zebra_ns_delete(char *name) static int zebra_ns_notify_self_identify(struct stat *netst) { - char net_path[64]; + char net_path[PATH_MAX]; int netns; - sprintf(net_path, "/proc/self/ns/net"); + snprintf(net_path, sizeof(net_path), "/proc/self/ns/net"); netns = open(net_path, O_RDONLY); if (netns < 0) return -1; @@ -178,7 +178,7 @@ static bool zebra_ns_notify_is_default_netns(const char *name) return false; memset(&st, 0, sizeof(struct stat)); - snprintf(netnspath, 64, "%s/%s", NS_RUN_DIR, name); + snprintf(netnspath, sizeof(netnspath), "%s/%s", NS_RUN_DIR, name); /* compare with local stat */ if (stat(netnspath, &st) == 0 && (st.st_dev == default_netns_stat.st_dev) && diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h index 0a9e97ab48..5792584d0f 100644 --- a/zebra/zebra_nhg.h +++ b/zebra/zebra_nhg.h @@ -26,6 +26,10 @@ #include "lib/nexthop.h" #include "lib/nexthop_group.h" +#ifdef __cplusplus +extern "C" { +#endif + /* This struct is used exclusively for dataplane * interaction via a dataplane context. * @@ -269,4 +273,8 @@ extern void zebra_nhg_sweep_table(struct hash *hash); struct route_entry; /* Forward ref to avoid circular includes */ extern int nexthop_active_update(struct route_node *rn, struct route_entry *re); +#ifdef __cplusplus +} +#endif + #endif /* __ZEBRA_NHG_H__ */ diff --git a/zebra/zebra_nhg_private.h b/zebra/zebra_nhg_private.h index 92f438fcec..25048258d5 100644 --- a/zebra/zebra_nhg_private.h +++ b/zebra/zebra_nhg_private.h @@ -30,6 +30,10 @@ #include "zebra/zebra_nhg.h" +#ifdef __cplusplus +extern "C" { +#endif + /* Abstraction for connected trees */ struct nhg_connected { struct nhg_connected_tree_item tree_item; @@ -70,4 +74,8 @@ extern struct nhg_hash_entry * nhg_connected_tree_add_nhe(struct nhg_connected_tree_head *head, struct nhg_hash_entry *nhe); +#ifdef __cplusplus +} +#endif + #endif /* __ZEBRA_NHG_PRIVATE_H__ */ diff --git a/zebra/zebra_northbound.c b/zebra/zebra_northbound.c deleted file mode 100644 index 9f6514e12f..0000000000 --- a/zebra/zebra_northbound.c +++ /dev/null @@ -1,2212 +0,0 @@ -/* - * Zebra northbound implementation. - * - * Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF") - * Rafael Zalamena - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301 USA. - */ - -#include <zebra.h> - -#include "lib/command.h" -#include "lib/log.h" -#include "lib/northbound.h" -#include "lib/routemap.h" - -#include "zebra/rib.h" - -/* - * XPath: /frr-zebra:zebra/mcast-rpf-lookup - */ -static int zebra_mcast_rpf_lookup_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/ip-forwarding - */ -static int zebra_ip_forwarding_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_ip_forwarding_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/ipv6-forwarding - */ -static int zebra_ipv6_forwarding_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_ipv6_forwarding_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/workqueue-hold-timer - */ -static int zebra_workqueue_hold_timer_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/zapi-packets - */ -static int zebra_zapi_packets_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/import-kernel-table/table-id - */ -static int -zebra_import_kernel_table_table_id_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -zebra_import_kernel_table_table_id_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/import-kernel-table/distance - */ -static int -zebra_import_kernel_table_distance_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/import-kernel-table/route-map - */ -static int -zebra_import_kernel_table_route_map_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -zebra_import_kernel_table_route_map_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/allow-external-route-update - */ -static int -zebra_allow_external_route_update_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -zebra_allow_external_route_update_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/dplane-queue-limit - */ -static int zebra_dplane_queue_limit_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/vrf-vni-mapping - */ -static int zebra_vrf_vni_mapping_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_vrf_vni_mapping_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/vrf-vni-mapping/vni-id - */ -static int zebra_vrf_vni_mapping_vni_id_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_vrf_vni_mapping_vni_id_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/vrf-vni-mapping/prefix-only - */ -static int -zebra_vrf_vni_mapping_prefix_only_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -zebra_vrf_vni_mapping_prefix_only_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-events - */ -static int zebra_debugs_debug_events_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_events_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-zapi-send - */ -static int zebra_debugs_debug_zapi_send_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_zapi_send_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-zapi-recv - */ -static int zebra_debugs_debug_zapi_recv_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_zapi_recv_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-zapi-detail - */ -static int zebra_debugs_debug_zapi_detail_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_zapi_detail_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-kernel - */ -static int zebra_debugs_debug_kernel_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_kernel_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-send - */ -static int -zebra_debugs_debug_kernel_msg_send_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -zebra_debugs_debug_kernel_msg_send_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-kernel-msg-recv - */ -static int -zebra_debugs_debug_kernel_msg_recv_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -zebra_debugs_debug_kernel_msg_recv_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-rib - */ -static int zebra_debugs_debug_rib_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_rib_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-rib-detail - */ -static int zebra_debugs_debug_rib_detail_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_rib_detail_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-fpm - */ -static int zebra_debugs_debug_fpm_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_fpm_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-nht - */ -static int zebra_debugs_debug_nht_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_nht_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-nht-detail - */ -static int zebra_debugs_debug_nht_detail_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_nht_detail_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-mpls - */ -static int zebra_debugs_debug_mpls_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_mpls_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-vxlan - */ -static int zebra_debugs_debug_vxlan_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_vxlan_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-pw - */ -static int zebra_debugs_debug_pw_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_pw_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-dplane - */ -static int zebra_debugs_debug_dplane_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_dplane_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-dplane-detail - */ -static int zebra_debugs_debug_dplane_detail_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -zebra_debugs_debug_dplane_detail_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:zebra/debugs/debug-mlag - */ -static int zebra_debugs_debug_mlag_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int zebra_debugs_debug_mlag_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-route-information - */ -static int get_route_information_rpc(const char *xpath, - const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-v6-mroute-info - */ -static int get_v6_mroute_info_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-vrf-info - */ -static int get_vrf_info_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-vrf-vni-info - */ -static int get_vrf_vni_info_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-evpn-info - */ -static int get_evpn_info_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-vni-info - */ -static int get_vni_info_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-evpn-vni-rmac - */ -static int get_evpn_vni_rmac_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-evpn-vni-nexthops - */ -static int get_evpn_vni_nexthops_rpc(const char *xpath, - const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:clear-evpn-dup-addr - */ -static int clear_evpn_dup_addr_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-evpn-macs - */ -static int get_evpn_macs_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-evpn-arp-cache - */ -static int get_evpn_arp_cache_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-pbr-ipset - */ -static int get_pbr_ipset_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-pbr-iptable - */ -static int get_pbr_iptable_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-zebra:get-debugs - */ -static int get_debugs_rpc(const char *xpath, const struct list *input, - struct list *output) -{ - /* TODO: implement me. */ - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list - */ -static int -lib_interface_zebra_ip4_addr_list_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -lib_interface_zebra_ip4_addr_list_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/ip4-peer - */ -static int -lib_interface_zebra_ip4_addr_list_ip4_peer_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -lib_interface_zebra_ip4_addr_list_ip4_peer_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/label - */ -static int -lib_interface_zebra_ip4_addr_list_label_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -lib_interface_zebra_ip4_addr_list_label_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list - */ -static int -lib_interface_zebra_ip6_addr_list_create(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -lib_interface_zebra_ip6_addr_list_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list/label - */ -static int -lib_interface_zebra_ip6_addr_list_label_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int -lib_interface_zebra_ip6_addr_list_label_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/multicast - */ -static int lib_interface_zebra_multicast_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int lib_interface_zebra_multicast_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-detect - */ -static int lib_interface_zebra_link_detect_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int lib_interface_zebra_link_detect_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/shutdown - */ -static int lib_interface_zebra_shutdown_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int lib_interface_zebra_shutdown_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: /frr-interface:lib/interface/frr-zebra:zebra/bandwidth - */ -static int lib_interface_zebra_bandwidth_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -static int lib_interface_zebra_bandwidth_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - switch (event) { - case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: - case NB_EV_APPLY: - /* TODO: implement me. */ - break; - } - - return NB_ERR_NOT_FOUND; -} - -/* - * XPath: - * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length - */ -static int lib_route_map_entry_match_condition_ipv4_prefix_length_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) -{ - struct routemap_hook_context *rhc; - const char *length; - int condition, rv; - - if (event != NB_EV_APPLY) - return NB_OK; - - /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - length = yang_dnode_get_string(dnode, NULL); - condition = yang_dnode_get_enum(dnode, "../frr-route-map:condition"); - - /* Set destroy information. */ - switch (condition) { - case 100: /* ipv4-prefix-length */ - rhc->rhc_rule = "ip address prefix-len"; - break; - - case 102: /* ipv4-next-hop-prefix-length */ - rhc->rhc_rule = "ip next-hop prefix-len"; - break; - } - rhc->rhc_mhook = generic_match_delete; - rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; - - rv = generic_match_add(NULL, rhc->rhc_rmi, rhc->rhc_rule, length, - RMAP_EVENT_MATCH_ADDED); - if (rv != CMD_SUCCESS) { - rhc->rhc_mhook = NULL; - return NB_ERR_INCONSISTENCY; - } - - return NB_OK; -} - -static int lib_route_map_entry_match_condition_ipv4_prefix_length_destroy( - enum nb_event event, const struct lyd_node *dnode) -{ - return lib_route_map_entry_match_destroy(event, dnode); -} - -/* - * XPath: - * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv6-prefix-length - */ -static int lib_route_map_entry_match_condition_ipv6_prefix_length_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) -{ - struct routemap_hook_context *rhc; - const char *length; - int rv; - - if (event != NB_EV_APPLY) - return NB_OK; - - /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - length = yang_dnode_get_string(dnode, NULL); - - /* Set destroy information. */ - rhc->rhc_mhook = generic_match_delete; - rhc->rhc_rule = "ipv6 address prefix-len"; - rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; - - rv = generic_match_add(NULL, rhc->rhc_rmi, "ipv6 address prefix-len", - length, RMAP_EVENT_MATCH_ADDED); - if (rv != CMD_SUCCESS) { - rhc->rhc_mhook = NULL; - return NB_ERR_INCONSISTENCY; - } - - return NB_OK; -} - -static int lib_route_map_entry_match_condition_ipv6_prefix_length_destroy( - enum nb_event event, const struct lyd_node *dnode) -{ - return lib_route_map_entry_match_destroy(event, dnode); -} - -/* - * XPath: - * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-protocol - */ -static int lib_route_map_entry_match_condition_source_protocol_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) -{ - struct routemap_hook_context *rhc; - const char *type; - int rv; - - switch (event) { - case NB_EV_VALIDATE: - type = yang_dnode_get_string(dnode, NULL); - if (proto_name2num(type) == -1) { - zlog_warn("%s: invalid protocol: %s", __func__, type); - return NB_ERR_VALIDATION; - } - return NB_OK; - case NB_EV_PREPARE: - case NB_EV_ABORT: - return NB_OK; - case NB_EV_APPLY: - /* NOTHING */ - break; - } - - /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_string(dnode, NULL); - - /* Set destroy information. */ - rhc->rhc_mhook = generic_match_delete; - rhc->rhc_rule = "source-protocol"; - rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; - - rv = generic_match_add(NULL, rhc->rhc_rmi, "source-protocol", type, - RMAP_EVENT_MATCH_ADDED); - if (rv != CMD_SUCCESS) { - rhc->rhc_mhook = NULL; - return NB_ERR_INCONSISTENCY; - } - - return NB_OK; -} - -static int lib_route_map_entry_match_condition_source_protocol_destroy( - enum nb_event event, const struct lyd_node *dnode) -{ - return lib_route_map_entry_match_destroy(event, dnode); -} - -/* - * XPath: - * /frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-instance - */ -static int lib_route_map_entry_match_condition_source_instance_modify( - enum nb_event event, const struct lyd_node *dnode, - union nb_resource *resource) -{ - struct routemap_hook_context *rhc; - const char *type; - int rv; - - if (event != NB_EV_APPLY) - return NB_OK; - - /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - type = yang_dnode_get_string(dnode, NULL); - - /* Set destroy information. */ - rhc->rhc_mhook = generic_match_delete; - rhc->rhc_rule = "source-instance"; - rhc->rhc_event = RMAP_EVENT_MATCH_DELETED; - - rv = generic_match_add(NULL, rhc->rhc_rmi, "source-instance", type, - RMAP_EVENT_MATCH_ADDED); - if (rv != CMD_SUCCESS) { - rhc->rhc_mhook = NULL; - return NB_ERR_INCONSISTENCY; - } - - return NB_OK; -} - -static int lib_route_map_entry_match_condition_source_instance_destroy( - enum nb_event event, const struct lyd_node *dnode) -{ - return lib_route_map_entry_match_destroy(event, dnode); -} - -/* - * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v4 - */ -static int -lib_route_map_entry_set_action_source_v4_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - struct routemap_hook_context *rhc; - struct interface *pif = NULL; - const char *source; - struct vrf *vrf; - struct prefix p; - int rv; - - switch (event) { - case NB_EV_VALIDATE: - memset(&p, 0, sizeof(p)); - yang_dnode_get_ipv4p(&p, dnode, NULL); - if (zebra_check_addr(&p) == 0) { - zlog_warn("%s: invalid IPv4 address: %s", __func__, - yang_dnode_get_string(dnode, NULL)); - return NB_ERR_VALIDATION; - } - - RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) { - pif = if_lookup_exact_address(&p.u.prefix4, AF_INET, - vrf->vrf_id); - if (pif != NULL) - break; - } - if (pif == NULL) { - zlog_warn("%s: is not a local adddress: %s", __func__, - yang_dnode_get_string(dnode, NULL)); - return NB_ERR_VALIDATION; - } - return NB_OK; - case NB_EV_PREPARE: - case NB_EV_ABORT: - return NB_OK; - case NB_EV_APPLY: - /* NOTHING */ - break; - } - - /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - source = yang_dnode_get_string(dnode, NULL); - - /* Set destroy information. */ - rhc->rhc_shook = generic_set_delete; - rhc->rhc_rule = "src"; - - rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source); - if (rv != CMD_SUCCESS) { - rhc->rhc_shook = NULL; - return NB_ERR_INCONSISTENCY; - } - - return NB_OK; -} - -static int -lib_route_map_entry_set_action_source_v4_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - return lib_route_map_entry_set_destroy(event, dnode); -} - -/* - * XPath: /frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v6 - */ -static int -lib_route_map_entry_set_action_source_v6_modify(enum nb_event event, - const struct lyd_node *dnode, - union nb_resource *resource) -{ - struct routemap_hook_context *rhc; - struct interface *pif = NULL; - const char *source; - struct vrf *vrf; - struct prefix p; - int rv; - - switch (event) { - case NB_EV_VALIDATE: - memset(&p, 0, sizeof(p)); - yang_dnode_get_ipv6p(&p, dnode, NULL); - if (zebra_check_addr(&p) == 0) { - zlog_warn("%s: invalid IPv6 address: %s", __func__, - yang_dnode_get_string(dnode, NULL)); - return NB_ERR_VALIDATION; - } - - RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) { - pif = if_lookup_exact_address(&p.u.prefix6, AF_INET6, - vrf->vrf_id); - if (pif != NULL) - break; - } - if (pif == NULL) { - zlog_warn("%s: is not a local adddress: %s", __func__, - yang_dnode_get_string(dnode, NULL)); - return NB_ERR_VALIDATION; - } - return NB_OK; - case NB_EV_PREPARE: - case NB_EV_ABORT: - return NB_OK; - case NB_EV_APPLY: - /* NOTHING */ - break; - } - - /* Add configuration. */ - rhc = nb_running_get_entry(dnode, NULL, true); - source = yang_dnode_get_string(dnode, NULL); - - /* Set destroy information. */ - rhc->rhc_shook = generic_set_delete; - rhc->rhc_rule = "src"; - - rv = generic_set_add(NULL, rhc->rhc_rmi, "src", source); - if (rv != CMD_SUCCESS) { - rhc->rhc_shook = NULL; - return NB_ERR_INCONSISTENCY; - } - - return NB_OK; -} - -static int -lib_route_map_entry_set_action_source_v6_destroy(enum nb_event event, - const struct lyd_node *dnode) -{ - return lib_route_map_entry_set_destroy(event, dnode); -} - -/* clang-format off */ -const struct frr_yang_module_info frr_zebra_info = { - .name = "frr-zebra", - .nodes = { - { - .xpath = "/frr-zebra:zebra/mcast-rpf-lookup", - .cbs = { - .modify = zebra_mcast_rpf_lookup_modify, - } - }, - { - .xpath = "/frr-zebra:zebra/ip-forwarding", - .cbs = { - .modify = zebra_ip_forwarding_modify, - .destroy = zebra_ip_forwarding_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/ipv6-forwarding", - .cbs = { - .modify = zebra_ipv6_forwarding_modify, - .destroy = zebra_ipv6_forwarding_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/workqueue-hold-timer", - .cbs = { - .modify = zebra_workqueue_hold_timer_modify, - } - }, - { - .xpath = "/frr-zebra:zebra/zapi-packets", - .cbs = { - .modify = zebra_zapi_packets_modify, - } - }, - { - .xpath = "/frr-zebra:zebra/import-kernel-table/table-id", - .cbs = { - .modify = zebra_import_kernel_table_table_id_modify, - .destroy = zebra_import_kernel_table_table_id_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/import-kernel-table/distance", - .cbs = { - .modify = zebra_import_kernel_table_distance_modify, - } - }, - { - .xpath = "/frr-zebra:zebra/import-kernel-table/route-map", - .cbs = { - .modify = zebra_import_kernel_table_route_map_modify, - .destroy = zebra_import_kernel_table_route_map_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/allow-external-route-update", - .cbs = { - .create = zebra_allow_external_route_update_create, - .destroy = zebra_allow_external_route_update_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/dplane-queue-limit", - .cbs = { - .modify = zebra_dplane_queue_limit_modify, - } - }, - { - .xpath = "/frr-zebra:zebra/vrf-vni-mapping", - .cbs = { - .create = zebra_vrf_vni_mapping_create, - .destroy = zebra_vrf_vni_mapping_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/vrf-vni-mapping/vni-id", - .cbs = { - .modify = zebra_vrf_vni_mapping_vni_id_modify, - .destroy = zebra_vrf_vni_mapping_vni_id_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/vrf-vni-mapping/prefix-only", - .cbs = { - .create = zebra_vrf_vni_mapping_prefix_only_create, - .destroy = zebra_vrf_vni_mapping_prefix_only_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-events", - .cbs = { - .modify = zebra_debugs_debug_events_modify, - .destroy = zebra_debugs_debug_events_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-zapi-send", - .cbs = { - .modify = zebra_debugs_debug_zapi_send_modify, - .destroy = zebra_debugs_debug_zapi_send_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-zapi-recv", - .cbs = { - .modify = zebra_debugs_debug_zapi_recv_modify, - .destroy = zebra_debugs_debug_zapi_recv_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-zapi-detail", - .cbs = { - .modify = zebra_debugs_debug_zapi_detail_modify, - .destroy = zebra_debugs_debug_zapi_detail_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-kernel", - .cbs = { - .modify = zebra_debugs_debug_kernel_modify, - .destroy = zebra_debugs_debug_kernel_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-kernel-msg-send", - .cbs = { - .modify = zebra_debugs_debug_kernel_msg_send_modify, - .destroy = zebra_debugs_debug_kernel_msg_send_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-kernel-msg-recv", - .cbs = { - .modify = zebra_debugs_debug_kernel_msg_recv_modify, - .destroy = zebra_debugs_debug_kernel_msg_recv_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-rib", - .cbs = { - .modify = zebra_debugs_debug_rib_modify, - .destroy = zebra_debugs_debug_rib_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-rib-detail", - .cbs = { - .modify = zebra_debugs_debug_rib_detail_modify, - .destroy = zebra_debugs_debug_rib_detail_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-fpm", - .cbs = { - .modify = zebra_debugs_debug_fpm_modify, - .destroy = zebra_debugs_debug_fpm_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-nht", - .cbs = { - .modify = zebra_debugs_debug_nht_modify, - .destroy = zebra_debugs_debug_nht_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-nht-detail", - .cbs = { - .modify = zebra_debugs_debug_nht_detail_modify, - .destroy = zebra_debugs_debug_nht_detail_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-mpls", - .cbs = { - .modify = zebra_debugs_debug_mpls_modify, - .destroy = zebra_debugs_debug_mpls_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-vxlan", - .cbs = { - .modify = zebra_debugs_debug_vxlan_modify, - .destroy = zebra_debugs_debug_vxlan_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-pw", - .cbs = { - .modify = zebra_debugs_debug_pw_modify, - .destroy = zebra_debugs_debug_pw_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-dplane", - .cbs = { - .modify = zebra_debugs_debug_dplane_modify, - .destroy = zebra_debugs_debug_dplane_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-dplane-detail", - .cbs = { - .modify = zebra_debugs_debug_dplane_detail_modify, - .destroy = zebra_debugs_debug_dplane_detail_destroy, - } - }, - { - .xpath = "/frr-zebra:zebra/debugs/debug-mlag", - .cbs = { - .modify = zebra_debugs_debug_mlag_modify, - .destroy = zebra_debugs_debug_mlag_destroy, - } - }, - { - .xpath = "/frr-zebra:get-route-information", - .cbs = { - .rpc = get_route_information_rpc, - } - }, - { - .xpath = "/frr-zebra:get-v6-mroute-info", - .cbs = { - .rpc = get_v6_mroute_info_rpc, - } - }, - { - .xpath = "/frr-zebra:get-vrf-info", - .cbs = { - .rpc = get_vrf_info_rpc, - } - }, - { - .xpath = "/frr-zebra:get-vrf-vni-info", - .cbs = { - .rpc = get_vrf_vni_info_rpc, - } - }, - { - .xpath = "/frr-zebra:get-evpn-info", - .cbs = { - .rpc = get_evpn_info_rpc, - } - }, - { - .xpath = "/frr-zebra:get-vni-info", - .cbs = { - .rpc = get_vni_info_rpc, - } - }, - { - .xpath = "/frr-zebra:get-evpn-vni-rmac", - .cbs = { - .rpc = get_evpn_vni_rmac_rpc, - } - }, - { - .xpath = "/frr-zebra:get-evpn-vni-nexthops", - .cbs = { - .rpc = get_evpn_vni_nexthops_rpc, - } - }, - { - .xpath = "/frr-zebra:clear-evpn-dup-addr", - .cbs = { - .rpc = clear_evpn_dup_addr_rpc, - } - }, - { - .xpath = "/frr-zebra:get-evpn-macs", - .cbs = { - .rpc = get_evpn_macs_rpc, - } - }, - { - .xpath = "/frr-zebra:get-evpn-arp-cache", - .cbs = { - .rpc = get_evpn_arp_cache_rpc, - } - }, - { - .xpath = "/frr-zebra:get-pbr-ipset", - .cbs = { - .rpc = get_pbr_ipset_rpc, - } - }, - { - .xpath = "/frr-zebra:get-pbr-iptable", - .cbs = { - .rpc = get_pbr_iptable_rpc, - } - }, - { - .xpath = "/frr-zebra:get-debugs", - .cbs = { - .rpc = get_debugs_rpc, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list", - .cbs = { - .create = lib_interface_zebra_ip4_addr_list_create, - .destroy = lib_interface_zebra_ip4_addr_list_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/ip4-peer", - .cbs = { - .modify = lib_interface_zebra_ip4_addr_list_ip4_peer_modify, - .destroy = lib_interface_zebra_ip4_addr_list_ip4_peer_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip4-addr-list/label", - .cbs = { - .modify = lib_interface_zebra_ip4_addr_list_label_modify, - .destroy = lib_interface_zebra_ip4_addr_list_label_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list", - .cbs = { - .create = lib_interface_zebra_ip6_addr_list_create, - .destroy = lib_interface_zebra_ip6_addr_list_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/ip6-addr-list/label", - .cbs = { - .modify = lib_interface_zebra_ip6_addr_list_label_modify, - .destroy = lib_interface_zebra_ip6_addr_list_label_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/multicast", - .cbs = { - .modify = lib_interface_zebra_multicast_modify, - .destroy = lib_interface_zebra_multicast_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/link-detect", - .cbs = { - .modify = lib_interface_zebra_link_detect_modify, - .destroy = lib_interface_zebra_link_detect_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/shutdown", - .cbs = { - .modify = lib_interface_zebra_shutdown_modify, - .destroy = lib_interface_zebra_shutdown_destroy, - } - }, - { - .xpath = "/frr-interface:lib/interface/frr-zebra:zebra/bandwidth", - .cbs = { - .modify = lib_interface_zebra_bandwidth_modify, - .destroy = lib_interface_zebra_bandwidth_destroy, - } - }, - { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv4-prefix-length", - .cbs = { - .modify = lib_route_map_entry_match_condition_ipv4_prefix_length_modify, - .destroy = lib_route_map_entry_match_condition_ipv4_prefix_length_destroy, - } - }, - { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:ipv6-prefix-length", - .cbs = { - .modify = lib_route_map_entry_match_condition_ipv6_prefix_length_modify, - .destroy = lib_route_map_entry_match_condition_ipv6_prefix_length_destroy, - } - }, - { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-protocol", - .cbs = { - .modify = lib_route_map_entry_match_condition_source_protocol_modify, - .destroy = lib_route_map_entry_match_condition_source_protocol_destroy, - } - }, - { - .xpath = "/frr-route-map:lib/route-map/entry/match-condition/frr-zebra:source-instance", - .cbs = { - .modify = lib_route_map_entry_match_condition_source_instance_modify, - .destroy = lib_route_map_entry_match_condition_source_instance_destroy, - } - }, - { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v4", - .cbs = { - .modify = lib_route_map_entry_set_action_source_v4_modify, - .destroy = lib_route_map_entry_set_action_source_v4_destroy, - } - }, - { - .xpath = "/frr-route-map:lib/route-map/entry/set-action/frr-zebra:source-v6", - .cbs = { - .modify = lib_route_map_entry_set_action_source_v6_modify, - .destroy = lib_route_map_entry_set_action_source_v6_destroy, - } - }, - { - .xpath = NULL, - }, - } -}; diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index c049aa14f6..62cbcbda4b 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -877,16 +877,15 @@ static void zebra_pbr_display_icmp(struct vty *vty, /* range icmp type */ if (zpie->src_port_max || zpie->dst_port_max) { - vty_out(vty, ":icmp:[type <%d:%d>;code <%d:%d>", + vty_out(vty, ":icmp:[type <%u:%u>;code <%u:%u>", zpie->src_port_min, zpie->src_port_max, zpie->dst_port_min, zpie->dst_port_max); } else { port = ((zpie->src_port_min << 8) & 0xff00) + (zpie->dst_port_min & 0xff); memset(decoded_str, 0, sizeof(decoded_str)); - sprintf(decoded_str, "%d/%d", - zpie->src_port_min, - zpie->dst_port_min); + snprintf(decoded_str, sizeof(decoded_str), "%u/%u", + zpie->src_port_min, zpie->dst_port_min); vty_out(vty, ":icmp:%s", lookup_msg(icmp_typecode_str, port, decoded_str)); @@ -1129,7 +1128,7 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable, if (iptable->fragment) { char val_str[10]; - sprintf(val_str, "%d", iptable->fragment); + snprintf(val_str, sizeof(val_str), "%d", iptable->fragment); vty_out(vty, "\t fragment%s %s\n", iptable->filter_bm & MATCH_FRAGMENT_INVERSE_SET ? " not" : "", lookup_msg(fragment_value_str, diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 669cb2466f..88ea2b87b1 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -132,7 +132,7 @@ void zebra_ptm_init(void) ptm_cb.pid = getpid(); zebra_ptm_install_commands(); - sprintf(buf, "%s", FRR_PTM_NAME); + snprintf(buf, sizeof(buf), "%s", FRR_PTM_NAME); ptm_hdl = ptm_lib_register(buf, NULL, zebra_ptm_handle_msg_cb, zebra_ptm_handle_msg_cb); ptm_cb.wb = buffer_new(0); @@ -710,16 +710,17 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) } ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_START_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", ZEBRA_PTM_BFD_START_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); s = msg; STREAM_GETL(s, pid); - sprintf(tmp_buf, "%d", pid); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", pid); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); @@ -742,21 +743,21 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) } STREAM_GETL(s, min_rx_timer); - sprintf(tmp_buf, "%d", min_rx_timer); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", min_rx_timer); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_RX_FIELD, tmp_buf); STREAM_GETL(s, min_tx_timer); - sprintf(tmp_buf, "%d", min_tx_timer); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", min_tx_timer); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MIN_TX_FIELD, tmp_buf); STREAM_GETC(s, detect_mul); - sprintf(tmp_buf, "%d", detect_mul); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", detect_mul); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_DETECT_MULT_FIELD, tmp_buf); STREAM_GETC(s, multi_hop); if (multi_hop) { - sprintf(tmp_buf, "%d", 1); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", 1); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); STREAM_GETW(s, src_p.family); @@ -778,7 +779,7 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) } STREAM_GETC(s, multi_hop_cnt); - sprintf(tmp_buf, "%d", multi_hop_cnt); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", multi_hop_cnt); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD, tmp_buf); @@ -818,11 +819,11 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) ZEBRA_PTM_BFD_IFNAME_FIELD, if_name); } STREAM_GETC(s, cbit_set); - sprintf(tmp_buf, "%d", cbit_set); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", cbit_set); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CBIT_FIELD, tmp_buf); - sprintf(tmp_buf, "%d", 1); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", 1); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT, tmp_buf); @@ -869,17 +870,18 @@ void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS) ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_STOP_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", ZEBRA_PTM_BFD_STOP_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); s = msg; STREAM_GETL(s, pid); - sprintf(tmp_buf, "%d", pid); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", pid); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); @@ -900,7 +902,7 @@ void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS) STREAM_GETC(s, multi_hop); if (multi_hop) { - sprintf(tmp_buf, "%d", 1); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", 1); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_MULTI_HOP_FIELD, tmp_buf); @@ -996,14 +998,15 @@ void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS) ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_REG_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", ZEBRA_PTM_BFD_CLIENT_REG_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(client->proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + zebra_route_string(client->proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); - sprintf(tmp_buf, "%d", pid); + snprintf(tmp_buf, sizeof(tmp_buf), "%d", pid); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEQID_FIELD, tmp_buf); @@ -1054,10 +1057,11 @@ int zebra_ptm_bfd_client_deregister(struct zserv *client) ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - sprintf(tmp_buf, "%s", ZEBRA_PTM_BFD_CLIENT_DEREG_CMD); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", + ZEBRA_PTM_BFD_CLIENT_DEREG_CMD); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, tmp_buf); - sprintf(tmp_buf, "%s", zebra_route_string(proto)); + snprintf(tmp_buf, sizeof(tmp_buf), "%s", zebra_route_string(proto)); ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_CLIENT_FIELD, tmp_buf); diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index 610a052c31..7a14f6304f 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -547,13 +547,18 @@ static int zebra_pw_config(struct vty *vty) return write; } +static int zebra_pw_config(struct vty *vty); static struct cmd_node pw_node = { - PW_NODE, "%s(config-pw)# ", 1, + .name = "pw", + .node = PW_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pw)# ", + .config_write = zebra_pw_config, }; void zebra_pw_vty_init(void) { - install_node(&pw_node, zebra_pw_config); + install_node(&pw_node); install_default(PW_NODE); install_element(CONFIG_NODE, &pseudowire_if_cmd); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 2dbe907751..447f3dc28d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2456,11 +2456,12 @@ static void _route_entry_dump_nh(const struct route_entry *re, switch (nexthop->type) { case NEXTHOP_TYPE_BLACKHOLE: - sprintf(nhname, "Blackhole"); + snprintf(nhname, sizeof(nhname), "Blackhole"); break; case NEXTHOP_TYPE_IFINDEX: ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id); - sprintf(nhname, "%s", ifp ? ifp->name : "Unknown"); + snprintf(nhname, sizeof(nhname), "%s", + ifp ? ifp->name : "Unknown"); break; case NEXTHOP_TYPE_IPV4: /* fallthrough */ diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 2b3b3afbb5..9b2a58fd17 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -1860,7 +1860,7 @@ void zebra_routemap_config_write_protocol(struct vty *vty, memset(space, 0, sizeof(space)); if (zvrf_id(zvrf) != VRF_DEFAULT) - sprintf(space, "%s", " "); + snprintf(space, sizeof(space), "%s", " "); for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { if (PROTO_RM_NAME(zvrf, AFI_IP, i)) diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 5de45c0294..89b8238c29 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -266,9 +266,9 @@ static void check_replace(struct route_node *np2, struct route_entry *re2, return; } - if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) < 0) + if (prefix_cmp(&(*np)->p, &np2->p) < 0) return; - if (in_addr_cmp(&(*np)->p.u.prefix, &np2->p.u.prefix) > 0) { + if (prefix_cmp(&(*np)->p, &np2->p) > 0) { *np = np2; *re = re2; return; diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index ef3dc9808f..8024db4ca7 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -54,6 +54,7 @@ #include "zebra/zebra_pbr.h" #include "zebra/zebra_nhg.h" #include "zebra/interface.h" +#include "northbound_cli.h" extern int allow_delete; @@ -2934,17 +2935,29 @@ DEFPY (clear_evpn_dup_addr, "IPv4 address\n" "IPv6 address\n") { - struct zebra_vrf *zvrf; struct ipaddr host_ip = {.ipa_type = IPADDR_NONE }; int ret = CMD_SUCCESS; + struct list *input; + struct yang_data *yang_dup = NULL, *yang_dup_ip = NULL, + *yang_dup_mac = NULL; - zvrf = zebra_vrf_get_evpn(); - if (vni_str) { + input = list_new(); + + if (!vni_str) { + yang_dup = yang_data_new( + "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice", + "all-case"); + } else { + yang_dup = yang_data_new_uint32( + "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id", + vni); if (!is_zero_mac(&mac->eth_addr)) { - ret = zebra_vxlan_clear_dup_detect_vni_mac(vty, zvrf, - vni, - &mac->eth_addr); - } else if (ip) { + yang_dup_mac = yang_data_new_mac( + "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/mac-addr", + &mac->eth_addr); + if (yang_dup_mac) + listnode_add(input, yang_dup_mac); + } else if (ip) { if (sockunion_family(ip) == AF_INET) { host_ip.ipa_type = IPADDR_V4; host_ip.ipaddr_v4.s_addr = sockunion2ip(ip); @@ -2953,16 +2966,23 @@ DEFPY (clear_evpn_dup_addr, memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr, sizeof(struct in6_addr)); } - ret = zebra_vxlan_clear_dup_detect_vni_ip(vty, zvrf, - vni, - &host_ip); - } else - ret = zebra_vxlan_clear_dup_detect_vni(vty, zvrf, vni); - } else { - ret = zebra_vxlan_clear_dup_detect_vni_all(vty, zvrf); + yang_dup_ip = yang_data_new_ip( + "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice/single-case/vni-id/vni-ipaddr", + &host_ip); + + if (yang_dup_ip) + listnode_add(input, yang_dup_ip); + } } + if (yang_dup) { + listnode_add(input, yang_dup); + ret = nb_cli_rpc("/frr-zebra:clear-evpn-dup-addr", input, NULL); + } + + list_delete(&input); + return ret; } @@ -3478,22 +3498,42 @@ DEFUN_HIDDEN (show_frr, } /* IP node for static routes. */ -static struct cmd_node ip_node = {IP_NODE, "", 1}; -static struct cmd_node protocol_node = {PROTOCOL_NODE, "", 1}; +static int zebra_ip_config(struct vty *vty); +static struct cmd_node ip_node = { + .name = "static ip", + .node = IP_NODE, + .prompt = "", + .config_write = zebra_ip_config, +}; +static int config_write_protocol(struct vty *vty); +static struct cmd_node protocol_node = { + .name = "protocol", + .node = PROTOCOL_NODE, + .prompt = "", + .config_write = config_write_protocol, +}; /* table node for routing tables. */ -static struct cmd_node table_node = {TABLE_NODE, - "", /* This node has no interface. */ - 1}; -static struct cmd_node forwarding_node = {FORWARDING_NODE, - "", /* This node has no interface. */ - 1}; +static int config_write_table(struct vty *vty); +static struct cmd_node table_node = { + .name = "table", + .node = TABLE_NODE, + .prompt = "", + .config_write = config_write_table, +}; +static int config_write_forwarding(struct vty *vty); +static struct cmd_node forwarding_node = { + .name = "forwarding", + .node = FORWARDING_NODE, + .prompt = "", + .config_write = config_write_forwarding, +}; /* Route VTY. */ void zebra_vty_init(void) { /* Install configuration write function. */ - install_node(&table_node, config_write_table); - install_node(&forwarding_node, config_write_forwarding); + install_node(&table_node); + install_node(&forwarding_node); install_element(VIEW_NODE, &show_ip_forwarding_cmd); install_element(CONFIG_NODE, &ip_forwarding_cmd); @@ -3507,8 +3547,8 @@ void zebra_vty_init(void) /* Route-map */ zebra_route_map_init(); - install_node(&ip_node, zebra_ip_config); - install_node(&protocol_node, config_write_protocol); + install_node(&ip_node); + install_node(&protocol_node); install_element(CONFIG_NODE, &allow_external_route_update_cmd); install_element(CONFIG_NODE, &no_allow_external_route_update_cmd); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 24050d8038..b9e7251117 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -967,7 +967,7 @@ static void zvni_print_neigh_hash_all_vni(struct hash_bucket *bucket, } else { json_vni = json_object_new_object(); json_object_int_add(json_vni, "numArpNd", num_neigh); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!num_neigh) { @@ -1063,7 +1063,7 @@ static void zvni_print_neigh_hash_all_vni_detail(struct hash_bucket *bucket, } else { json_vni = json_object_new_object(); json_object_int_add(json_vni, "numArpNd", num_neigh); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!num_neigh) { if (json) @@ -1534,7 +1534,7 @@ static void zvni_print_mac_hash_all_vni(struct hash_bucket *bucket, void *ctxt) if (json) { json_vni = json_object_new_object(); json_mac = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) { @@ -1610,7 +1610,7 @@ static void zvni_print_mac_hash_all_vni_detail(struct hash_bucket *bucket, if (json) { json_vni = json_object_new_object(); json_mac = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); } if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) { @@ -1693,7 +1693,7 @@ static void zl3vni_print_nh_hash_all_vni(struct hash_bucket *bucket, if (json) { json_vni = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zl3vni->vni); } if (json == NULL) { @@ -1732,7 +1732,7 @@ static void zl3vni_print_rmac_hash_all_vni(struct hash_bucket *bucket, if (json) { json_vni = json_object_new_object(); - snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zl3vni->vni); } if (json == NULL) { @@ -1968,7 +1968,7 @@ static void zl3vni_print_hash(struct hash_bucket *bucket, void *ctx[]) } else { char vni_str[VNI_STR_LEN]; - snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zl3vni->vni); json_vni = json_object_new_object(); json_object_int_add(json_vni, "vni", zl3vni->vni); json_object_string_add(json_vni, "vxlanIf", @@ -2053,7 +2053,7 @@ static void zvni_print_hash(struct hash_bucket *bucket, void *ctxt[]) vrf_id_to_name(zvni->vrf_id)); else { char vni_str[VNI_STR_LEN]; - snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni); + snprintf(vni_str, sizeof(vni_str), "%u", zvni->vni); json_vni = json_object_new_object(); json_object_int_add(json_vni, "vni", zvni->vni); json_object_string_add(json_vni, "type", "L2"); @@ -6853,9 +6853,8 @@ void zebra_vxlan_print_macs_vni_dad(struct vty *vty, } -int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, - struct zebra_vrf *zvrf, - vni_t vni, struct ethaddr *macaddr) +int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni, + struct ethaddr *macaddr) { zebra_vni_t *zvni; zebra_mac_t *mac; @@ -6863,24 +6862,23 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, zebra_neigh_t *nbr = NULL; if (!is_evpn_enabled()) - return CMD_SUCCESS; + return 0; zvni = zvni_lookup(vni); if (!zvni) { - vty_out(vty, "%% VNI %u does not exist\n", vni); - return CMD_WARNING; + zlog_warn("VNI %u does not exist\n", vni); + return -1; } mac = zvni_mac_lookup(zvni, macaddr); if (!mac) { - vty_out(vty, "%% Requested MAC does not exist in VNI %u\n", - vni); - return CMD_WARNING; + zlog_warn("Requested MAC does not exist in VNI %u\n", vni); + return -1; } if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { - vty_out(vty, "%% Requested MAC is not duplicate detected\n"); - return CMD_WARNING; + zlog_warn("Requested MAC is not duplicate detected\n"); + return -1; } /* Remove all IPs as duplicate associcated with this MAC */ @@ -6915,7 +6913,7 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, /* warn-only action return */ if (!zvrf->dad_freeze) - return CMD_SUCCESS; + return 0; /* Local: Notify Peer VTEPs, Remote: Install the entry */ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { @@ -6924,7 +6922,7 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, &mac->macaddr, mac->flags, mac->loc_seq)) - return CMD_SUCCESS; + return 0; /* Process all neighbors associated with this MAC. */ zvni_process_neigh_on_local_mac_change(zvni, mac, 0); @@ -6936,12 +6934,11 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, zvni_mac_install(zvni, mac); } - return CMD_SUCCESS; + return 0; } -int zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty, - struct zebra_vrf *zvrf, - vni_t vni, struct ipaddr *ip) +int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni, + struct ipaddr *ip) { zebra_vni_t *zvni; zebra_neigh_t *nbr; @@ -6950,38 +6947,35 @@ int zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty, char buf2[ETHER_ADDR_STRLEN]; if (!is_evpn_enabled()) - return CMD_SUCCESS; + return 0; zvni = zvni_lookup(vni); if (!zvni) { - vty_out(vty, "%% VNI %u does not exist\n", vni); - return CMD_WARNING; + zlog_debug("VNI %u does not exist\n", vni); + return -1; } nbr = zvni_neigh_lookup(zvni, ip); if (!nbr) { - vty_out(vty, - "%% Requested host IP does not exist in VNI %u\n", - vni); - return CMD_WARNING; + zlog_warn("Requested host IP does not exist in VNI %u\n", vni); + return -1; } ipaddr2str(&nbr->ip, buf, sizeof(buf)); if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) { - vty_out(vty, - "%% Requested host IP %s is not duplicate detected\n", - buf); - return CMD_WARNING; + zlog_warn("Requested host IP %s is not duplicate detected\n", + buf); + return -1; } mac = zvni_mac_lookup(zvni, &nbr->emac); if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) { - vty_out(vty, - "%% Requested IP's associated MAC %s is still in duplicate state\n", + zlog_warn( + "Requested IP's associated MAC %s is still in duplicate state\n", prefix_mac2str(&nbr->emac, buf2, sizeof(buf2))); - return CMD_WARNING_CONFIG_FAILED; + return -1; } if (IS_ZEBRA_DEBUG_VXLAN) @@ -7003,7 +6997,7 @@ int zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty, zvni_neigh_install(zvni, nbr); } - return CMD_SUCCESS; + return 0; } static void zvni_clear_dup_mac_hash(struct hash_bucket *bucket, void *ctxt) @@ -7102,7 +7096,6 @@ static void zvni_clear_dup_neigh_hash(struct hash_bucket *bucket, void *ctxt) static void zvni_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket, void **args) { - struct vty *vty; zebra_vni_t *zvni; struct zebra_vrf *zvrf; struct mac_walk_ctx m_wctx; @@ -7112,12 +7105,10 @@ static void zvni_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket, if (!zvni) return; - vty = (struct vty *)args[0]; - zvrf = (struct zebra_vrf *)args[1]; + zvrf = (struct zebra_vrf *)args[0]; if (hashcount(zvni->neigh_table)) { memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx)); - n_wctx.vty = vty; n_wctx.zvni = zvni; n_wctx.zvrf = zvrf; hash_iterate(zvni->neigh_table, zvni_clear_dup_neigh_hash, @@ -7127,51 +7118,45 @@ static void zvni_clear_dup_detect_hash_vni_all(struct hash_bucket *bucket, if (num_valid_macs(zvni)) { memset(&m_wctx, 0, sizeof(struct mac_walk_ctx)); m_wctx.zvni = zvni; - m_wctx.vty = vty; m_wctx.zvrf = zvrf; hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx); } } -int zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty, - struct zebra_vrf *zvrf) +int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf) { - void *args[2]; + void *args[1]; if (!is_evpn_enabled()) - return CMD_SUCCESS; + return 0; - args[0] = vty; - args[1] = zvrf; + args[0] = zvrf; hash_iterate(zvrf->vni_table, (void (*)(struct hash_bucket *, void *)) zvni_clear_dup_detect_hash_vni_all, args); - return CMD_SUCCESS; + return 0; } -int zebra_vxlan_clear_dup_detect_vni(struct vty *vty, - struct zebra_vrf *zvrf, - vni_t vni) +int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni) { zebra_vni_t *zvni; struct mac_walk_ctx m_wctx; struct neigh_walk_ctx n_wctx; if (!is_evpn_enabled()) - return CMD_SUCCESS; + return 0; zvni = zvni_lookup(vni); if (!zvni) { - vty_out(vty, "%% VNI %u does not exist\n", vni); - return CMD_WARNING; + zlog_warn("VNI %u does not exist\n", vni); + return -1; } if (hashcount(zvni->neigh_table)) { memset(&n_wctx, 0, sizeof(struct neigh_walk_ctx)); - n_wctx.vty = vty; n_wctx.zvni = zvni; n_wctx.zvrf = zvrf; hash_iterate(zvni->neigh_table, zvni_clear_dup_neigh_hash, @@ -7181,12 +7166,11 @@ int zebra_vxlan_clear_dup_detect_vni(struct vty *vty, if (num_valid_macs(zvni)) { memset(&m_wctx, 0, sizeof(struct mac_walk_ctx)); m_wctx.zvni = zvni; - m_wctx.vty = vty; m_wctx.zvrf = zvrf; hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx); } - return CMD_SUCCESS; + return 0; } /* @@ -7417,7 +7401,7 @@ void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS) * clear all duplicate detected addresses. */ if (zvrf->dup_addr_detect && !dup_addr_detect) - zebra_vxlan_clear_dup_detect_vni_all(NULL, zvrf); + zebra_vxlan_clear_dup_detect_vni_all(zvrf); zvrf->dup_addr_detect = dup_addr_detect; zvrf->dad_time = time; diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index a5c13a59e3..064dda6cd0 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -205,18 +205,13 @@ extern void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, extern void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id, struct ipaddr *vtep_ip, struct prefix *host_prefix); -extern int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty, - struct zebra_vrf *zvrf, +extern int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni, struct ethaddr *macaddr); -extern int zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty, - struct zebra_vrf *zvrf, +extern int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni, struct ipaddr *ip); -extern int zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty, - struct zebra_vrf *zvrf); -extern int zebra_vxlan_clear_dup_detect_vni(struct vty *vty, - struct zebra_vrf *zvrf, - vni_t vni); +extern int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf); +extern int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni); extern void zebra_vxlan_handle_result(struct zebra_dplane_ctx *ctx); extern void zebra_evpn_init(void); diff --git a/zebra/zserv.c b/zebra/zserv.c index 740e7c43c7..8a1ed115a7 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -889,6 +889,8 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) vty_out(vty, "Client: %s", zebra_route_string(client->proto)); if (client->instance) vty_out(vty, " Instance: %u", client->instance); + if (client->session_id) + vty_out(vty, " [%u]", client->session_id); vty_out(vty, "\n"); vty_out(vty, "------------------------ \n"); @@ -995,11 +997,16 @@ static void zebra_show_stale_client_detail(struct vty *vty, time_t uptime; struct client_gr_info *info = NULL; struct zserv *s = NULL; - - if (client->instance) - vty_out(vty, " Instance: %d", client->instance); + bool first_p = true; TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) { + if (first_p) { + if (client->instance) + vty_out(vty, " Instance: %u", client->instance); + if (client->session_id) + vty_out(vty, " [%u]", client->session_id); + first_p = false; + } vty_out(vty, "VRF : %s\n", vrf_id_to_name(info->vrf_id)); vty_out(vty, "Capabilities : "); switch (info->capabilities) { @@ -1070,19 +1077,26 @@ static void zebra_show_client_brief(struct vty *vty, struct zserv *client) client->v6_route_del_cnt); } -struct zserv *zserv_find_client(uint8_t proto, unsigned short instance) +struct zserv *zserv_find_client_session(uint8_t proto, unsigned short instance, + uint32_t session_id) { struct listnode *node, *nnode; struct zserv *client; for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { - if (client->proto == proto && client->instance == instance) + if (client->proto == proto && client->instance == instance && + client->session_id == session_id) return client; } return NULL; } +struct zserv *zserv_find_client(uint8_t proto, unsigned short instance) +{ + return zserv_find_client_session(proto, instance, 0); +} + /* This command is for debugging purpose. */ DEFUN (show_zebra_client, show_zebra_client_cmd, diff --git a/zebra/zserv.h b/zebra/zserv.h index 08df664d56..5506c4299d 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -134,9 +134,10 @@ struct zserv { /* Indicates if client is synchronous. */ bool synchronous; - /* client's protocol */ + /* client's protocol and session info */ uint8_t proto; uint16_t instance; + uint32_t session_id; /* * Interested for MLAG Updates, and also stores the client @@ -287,6 +288,24 @@ extern int zserv_send_message(struct zserv *client, struct stream *msg); extern struct zserv *zserv_find_client(uint8_t proto, unsigned short instance); /* + * Retrieve a client by its protocol, instance number, and session id. + * + * proto + * protocol number + * + * instance + * instance number + * + * session_id + * session id + * + * Returns: + * The Zebra API client. + */ +struct zserv *zserv_find_client_session(uint8_t proto, unsigned short instance, + uint32_t session_id); + +/* * Close a client. * * Kills a client's thread, removes the client from the client list and cleans |
