From c3d34b84f3e1b789b78b6ee93068f074eb884af1 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Tue, 2 Apr 2024 00:56:17 +0300 Subject: [PATCH 001/472] isisd: fix ip/ipv6 reachability tlvs Don't allocate subtlvs container if there's nothing to add to it. If the container is allocated, the "sub-TLVs presence" bit is set in the TLVs even if there's no actual sub-TLVs, what violates the RFC. Fixes #14514. Signed-off-by: Igor Ryzhov --- isisd/isis_tlvs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 2b0a58b73986..93ae8c6cb2d9 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -8016,7 +8016,6 @@ void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs, apply_mask_ipv4(&r->prefix); if (pcfgs) { - r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH); for (int i = 0; i < SR_ALGORITHM_COUNT; i++) { struct isis_prefix_sid *psid; struct sr_prefix_cfg *pcfg = pcfgs[i]; @@ -8026,6 +8025,10 @@ void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs, psid = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*psid)); isis_sr_prefix_cfg2subtlv(pcfg, external, psid); + + if (!r->subtlvs) + r->subtlvs = isis_alloc_subtlvs( + ISIS_CONTEXT_SUBTLV_IP_REACH); append_item(&r->subtlvs->prefix_sids, (struct isis_item *)psid); } @@ -8044,7 +8047,6 @@ void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid, memcpy(&r->prefix, dest, sizeof(*dest)); apply_mask_ipv6(&r->prefix); if (pcfgs) { - r->subtlvs = isis_alloc_subtlvs(ISIS_CONTEXT_SUBTLV_IP_REACH); for (int i = 0; i < SR_ALGORITHM_COUNT; i++) { struct isis_prefix_sid *psid; struct sr_prefix_cfg *pcfg = pcfgs[i]; @@ -8054,6 +8056,10 @@ void isis_tlvs_add_ipv6_reach(struct isis_tlvs *tlvs, uint16_t mtid, psid = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*psid)); isis_sr_prefix_cfg2subtlv(pcfg, external, psid); + + if (!r->subtlvs) + r->subtlvs = isis_alloc_subtlvs( + ISIS_CONTEXT_SUBTLV_IPV6_REACH); append_item(&r->subtlvs->prefix_sids, (struct isis_item *)psid); } From 58a8ebc1fca07ba963faf60d54d77336f36e5ded Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Mon, 18 Mar 2024 19:08:23 +0200 Subject: [PATCH 002/472] lib: rework northbound RPC callback Change input/output arguments of the RPC callback from lists of (xpath/value) tuples to YANG data trees. Signed-off-by: Igor Ryzhov --- lib/northbound.c | 7 ++--- lib/northbound.h | 10 +++---- lib/northbound_cli.c | 59 ++++++++++++++++++++++++++++++++++-- lib/northbound_cli.h | 34 ++++++++++++++------- lib/northbound_grpc.cpp | 61 ++++++++++++++++++++++++++----------- lib/northbound_sysrepo.c | 65 ++++------------------------------------ lib/vty.h | 4 +++ ripd/rip_nb_rpcs.c | 9 +++--- ripd/ripd.c | 19 ++---------- ripngd/ripng_nb_rpcs.c | 9 +++--- ripngd/ripngd.c | 19 ++---------- zebra/zebra_nb_rpcs.c | 50 ++++++++++--------------------- zebra/zebra_vty.c | 53 +++++--------------------------- 13 files changed, 177 insertions(+), 222 deletions(-) diff --git a/lib/northbound.c b/lib/northbound.c index 9a5d67cd1bb2..57068cc4e050 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -1820,14 +1820,11 @@ const void *nb_callback_lookup_next(const struct nb_node *nb_node, } int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, - const struct list *input, struct list *output, char *errmsg, - size_t errmsg_len) + const struct lyd_node *input, struct lyd_node *output, + char *errmsg, size_t errmsg_len) { struct nb_cb_rpc_args args = {}; - if (CHECK_FLAG(nb_node->flags, F_NB_NODE_IGNORE_CFG_CBS)) - return 0; - DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath); args.xpath = xpath; diff --git a/lib/northbound.h b/lib/northbound.h index 3bf1eacd610c..34d17a587caa 100644 --- a/lib/northbound.h +++ b/lib/northbound.h @@ -274,11 +274,11 @@ 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; + /* Read-only "input" tree of the RPC/action. */ + const struct lyd_node *input; - /* List of output parameters to be populated by the callback. */ - struct list *output; + /* The "output" tree of the RPC/action to be populated by the callback. */ + struct lyd_node *output; /* Buffer to store human-readable error message in case of error. */ char *errmsg; @@ -833,7 +833,7 @@ extern const void *nb_callback_lookup_next(const struct nb_node *nb_node, const void *parent_list_entry, const struct yang_list_keys *keys); extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, - const struct list *input, struct list *output, + const struct lyd_node *input, struct lyd_node *output, char *errmsg, size_t errmsg_len); extern void nb_callback_notify(const struct nb_node *nb_node, const char *xpath, struct lyd_node *dnode); diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 8809ec2ad87d..5be64f01346f 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -275,10 +275,31 @@ int nb_cli_apply_changes_clear_pending(struct vty *vty, return nb_cli_apply_changes_internal(vty, xpath_base_abs, true); } -int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input, - struct list *output) +int nb_cli_rpc_enqueue(struct vty *vty, const char *xpath, const char *value) +{ + struct nb_cfg_change *param; + + if (vty->num_rpc_params == VTY_MAXCFGCHANGES) { + /* Not expected to happen. */ + vty_out(vty, + "%% Exceeded the maximum number of params (%u) for a single command\n\n", + VTY_MAXCFGCHANGES); + return CMD_WARNING; + } + + param = &vty->rpc_params[vty->num_rpc_params++]; + strlcpy(param->xpath, xpath, sizeof(param->xpath)); + param->value = value; + + return CMD_SUCCESS; +} + +int nb_cli_rpc(struct vty *vty, const char *xpath, struct lyd_node **output_p) { struct nb_node *nb_node; + struct lyd_node *input = NULL; + struct lyd_node *output = NULL; + LY_ERR err; int ret; char errmsg[BUFSIZ] = {0}; @@ -289,12 +310,46 @@ int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input, return CMD_WARNING; } + /* create input tree */ + err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0, NULL, + &input); + assert(err == LY_SUCCESS); + + for (size_t i = 0; i < vty->num_rpc_params; i++) { + err = lyd_new_path(input, ly_native_ctx, + vty->rpc_params[i].xpath, + vty->rpc_params[i].value, 0, NULL); + assert(err == LY_SUCCESS); + } + + /* validate input tree to create implicit defaults */ + err = lyd_validate_op(input, NULL, LYD_TYPE_RPC_YANG, NULL); + assert(err == LY_SUCCESS); + + /* create output tree root for population in the callback */ + err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0, NULL, + &output); + assert(err == LY_SUCCESS); + ret = nb_callback_rpc(nb_node, xpath, input, output, errmsg, sizeof(errmsg)); + + /* validate output tree to create implicit defaults */ + err = lyd_validate_op(output, NULL, LYD_TYPE_REPLY_YANG, NULL); + assert(err == LY_SUCCESS); + + lyd_free_all(input); + vty->num_rpc_params = 0; + switch (ret) { case NB_OK: + if (output_p) + *output_p = output; + else + lyd_free_all(output); return CMD_SUCCESS; default: + lyd_free_all(output); if (strlen(errmsg)) vty_show_nb_errors(vty, ret, errmsg); return CMD_WARNING; diff --git a/lib/northbound_cli.h b/lib/northbound_cli.h index 1a45794d4526..4c8dc50bd232 100644 --- a/lib/northbound_cli.h +++ b/lib/northbound_cli.h @@ -80,7 +80,23 @@ extern int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...) PRINTFRR(2, 3); /* - * Execute a YANG RPC or Action. + * Add an input child node for an RPC or an action. + * + * vty + * The vty context. + * + * xpath + * XPath of the child being added, relative to the input container. + * + * value + * Value of the child being added. Can be NULL for containers and leafs of + * type 'empty'. + */ +extern int nb_cli_rpc_enqueue(struct vty *vty, const char *xpath, + const char *value); + +/* + * Execute a YANG RPC or Action using the enqueued input parameters. * * vty * The vty terminal to dump any error. @@ -88,20 +104,16 @@ extern int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, * xpath * XPath of the YANG RPC or Action node. * - * input - * List of 'yang_data' structures containing the RPC input parameters. It - * can be set to NULL when there are no input parameters. - * - * output - * List of 'yang_data' structures used to retrieve the RPC output parameters. - * It can be set to NULL when it's known that the given YANG RPC or Action - * doesn't have any output parameters. + * output_p + * A pointer to the libyang data node that will hold the output data tree. + * It can be set to NULL if the caller is not interested in processing the + * output. The caller is responsible for freeing the output data tree. * * Returns: * CMD_SUCCESS on success, CMD_WARNING otherwise. */ -extern int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input, - struct list *output); +extern int nb_cli_rpc(struct vty *vty, const char *xpath, + struct lyd_node **output_p); /* * Show CLI commands associated to the given YANG data node. diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp index 7957752589c4..612ec3981b82 100644 --- a/lib/northbound_grpc.cpp +++ b/lib/northbound_grpc.cpp @@ -1011,12 +1011,11 @@ grpc::Status HandleUnaryExecute( grpc_debug("%s: entered", __func__); struct nb_node *nb_node; - struct list *input_list; - struct list *output_list; - struct listnode *node; - struct yang_data *data; + struct lyd_node *input_tree, *output_tree, *child; const char *xpath; char errmsg[BUFSIZ] = {0}; + char path[XPATH_MAXLEN]; + LY_ERR err; // Request: string path = 1; xpath = tag->request.path().c_str(); @@ -1032,40 +1031,66 @@ grpc::Status HandleUnaryExecute( return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, "Unknown data path"); - input_list = yang_data_list_new(); - output_list = yang_data_list_new(); + // Create input data tree. + err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, + (LYD_ANYDATA_VALUETYPE)0, 0, NULL, &input_tree); + if (err != LY_SUCCESS) { + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + "Invalid data path"); + } // Read input parameters. auto input = tag->request.input(); for (const frr::PathValue &pv : input) { // Request: repeated PathValue input = 2; - data = yang_data_new(pv.path().c_str(), pv.value().c_str()); - listnode_add(input_list, data); + err = lyd_new_path(input_tree, ly_native_ctx, pv.path().c_str(), + pv.value().c_str(), 0, NULL); + if (err != LY_SUCCESS) { + lyd_free_tree(input_tree); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + "Invalid input data"); + } + } + + // Validate input data. + err = lyd_validate_op(input_tree, NULL, LYD_TYPE_RPC_YANG, NULL); + if (err != LY_SUCCESS) { + lyd_free_tree(input_tree); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + "Invalid input data"); + } + + // Create output data tree. + err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, + (LYD_ANYDATA_VALUETYPE)0, 0, NULL, &output_tree); + if (err != LY_SUCCESS) { + lyd_free_tree(input_tree); + return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT, + "Invalid data path"); } // Execute callback registered for this XPath. - if (nb_callback_rpc(nb_node, xpath, input_list, output_list, errmsg, - sizeof(errmsg)) - != NB_OK) { + if (nb_callback_rpc(nb_node, xpath, input_tree, output_tree, errmsg, + sizeof(errmsg)) != NB_OK) { flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s", __func__, xpath); - list_delete(&input_list); - list_delete(&output_list); + lyd_free_tree(input_tree); + lyd_free_tree(output_tree); return grpc::Status(grpc::StatusCode::INTERNAL, "RPC failed"); } // Process output parameters. - for (ALL_LIST_ELEMENTS_RO(output_list, node, data)) { + LY_LIST_FOR (lyd_child(output_tree), child) { // Response: repeated PathValue output = 1; frr::PathValue *pv = tag->response.add_output(); - pv->set_path(data->xpath); - pv->set_value(data->value); + pv->set_path(lyd_path(child, LYD_PATH_STD, path, sizeof(path))); + pv->set_value(yang_dnode_get_string(child, NULL)); } // Release memory. - list_delete(&input_list); - list_delete(&output_list); + lyd_free_tree(input_tree); + lyd_free_tree(output_tree); return grpc::Status::OK; } diff --git a/lib/northbound_sysrepo.c b/lib/northbound_sysrepo.c index 640334926dd8..0ec7610a9a7c 100644 --- a/lib/northbound_sysrepo.c +++ b/lib/northbound_sysrepo.c @@ -377,16 +377,11 @@ static int frr_sr_state_cb(sr_session_ctx_t *session, uint32_t sub_id, return SR_ERR_OK; } static int frr_sr_config_rpc_cb(sr_session_ctx_t *session, uint32_t sub_id, - const char *xpath, const sr_val_t *sr_input, - const size_t input_cnt, sr_event_t sr_ev, - uint32_t request_id, sr_val_t **sr_output, - size_t *sr_output_cnt, void *private_ctx) + const char *xpath, const struct lyd_node *input, + sr_event_t sr_ev, uint32_t request_id, + struct lyd_node *output, void *private_ctx) { struct nb_node *nb_node; - struct list *input; - struct list *output; - struct yang_data *data; - size_t cb_output_cnt; int ret = SR_ERR_OK; char errmsg[BUFSIZ] = {0}; @@ -397,19 +392,6 @@ static int frr_sr_config_rpc_cb(sr_session_ctx_t *session, uint32_t sub_id, return SR_ERR_INTERNAL; } - input = yang_data_list_new(); - output = yang_data_list_new(); - - /* Process input. */ - for (size_t i = 0; i < input_cnt; i++) { - char value_str[YANG_VALUE_MAXLEN]; - - sr_val_to_buff(&sr_input[i], value_str, sizeof(value_str)); - - data = yang_data_new(xpath, value_str); - listnode_add(input, data); - } - /* Execute callback registered for this XPath. */ if (nb_callback_rpc(nb_node, xpath, input, output, errmsg, sizeof(errmsg)) @@ -417,44 +399,8 @@ static int frr_sr_config_rpc_cb(sr_session_ctx_t *session, uint32_t sub_id, flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s", __func__, xpath); ret = SR_ERR_OPERATION_FAILED; - goto exit; } - /* Process output. */ - if (listcount(output) > 0) { - sr_val_t *values = NULL; - struct listnode *node; - int i = 0; - - cb_output_cnt = listcount(output); - ret = sr_new_values(cb_output_cnt, &values); - if (ret != SR_ERR_OK) { - flog_err(EC_LIB_LIBSYSREPO, "%s: sr_new_values(): %s", - __func__, sr_strerror(ret)); - goto exit; - } - - for (ALL_LIST_ELEMENTS_RO(output, node, data)) { - if (yang_data_frr2sr(data, &values[i++]) != 0) { - flog_err( - EC_LIB_SYSREPO_DATA_CONVERT, - "%s: failed to convert data to Sysrepo format", - __func__); - ret = SR_ERR_INTERNAL; - sr_free_values(values, cb_output_cnt); - goto exit; - } - } - - *sr_output = values; - *sr_output_cnt = cb_output_cnt; - } - -exit: - /* Release memory. */ - list_delete(&input); - list_delete(&output); - return ret; } @@ -579,8 +525,9 @@ static int frr_sr_subscribe_rpc(const struct lysc_node *snode, void *arg) DEBUGD(&nb_dbg_client_sysrepo, "sysrepo: providing RPC to '%s'", nb_node->xpath); - ret = sr_rpc_subscribe(session, nb_node->xpath, frr_sr_config_rpc_cb, - NULL, 0, 0, &module->sr_subscription); + ret = sr_rpc_subscribe_tree(session, nb_node->xpath, + frr_sr_config_rpc_cb, NULL, 0, 0, + &module->sr_subscription); if (ret != SR_ERR_OK) flog_err(EC_LIB_LIBSYSREPO, "sr_rpc_subscribe(): %s", sr_strerror(ret)); diff --git a/lib/vty.h b/lib/vty.h index 0e0c92c33650..a51cee76fb5d 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -122,6 +122,10 @@ struct vty { size_t num_cfg_changes; struct nb_cfg_change cfg_changes[VTY_MAXCFGCHANGES]; + /* Input parameters */ + size_t num_rpc_params; + struct nb_cfg_change rpc_params[VTY_MAXCFGCHANGES]; + /* XPath of the current node */ int xpath_index; char xpath[VTY_MAXDEPTH][XPATH_MAXLEN]; diff --git a/ripd/rip_nb_rpcs.c b/ripd/rip_nb_rpcs.c index bbe3d0f0f834..5d3d7145b1d4 100644 --- a/ripd/rip_nb_rpcs.c +++ b/ripd/rip_nb_rpcs.c @@ -68,12 +68,11 @@ static void clear_rip_route(struct rip *rip) 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(args->input, "%s/%s", args->xpath, - "input/vrf"); - if (yang_vrf) { - rip = rip_lookup_by_vrf_name(yang_vrf->value); + if (args->input && yang_dnode_exists(args->input, "vrf")) { + const char *name = yang_dnode_get_string(args->input, "vrf"); + + rip = rip_lookup_by_vrf_name(name); if (rip) clear_rip_route(rip); } else { diff --git a/ripd/ripd.c b/ripd/ripd.c index e3220a9267f3..4640880e4941 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -3267,23 +3267,10 @@ DEFPY_YANG (clear_ip_rip, "Clear IP RIP database\n" VRF_CMD_HELP_STR) { - struct list *input; - int ret; - - input = list_new(); - if (vrf) { - struct yang_data *yang_vrf; - - yang_vrf = yang_data_new("/frr-ripd:clear-rip-route/input/vrf", - vrf); - listnode_add(input, yang_vrf); - } - - ret = nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", input, NULL); - - list_delete(&input); + if (vrf) + nb_cli_rpc_enqueue(vty, "vrf", vrf); - return ret; + return nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", NULL); } /* Distribute-list update functions. */ diff --git a/ripngd/ripng_nb_rpcs.c b/ripngd/ripng_nb_rpcs.c index b23572d49282..5498bbfc8e38 100644 --- a/ripngd/ripng_nb_rpcs.c +++ b/ripngd/ripng_nb_rpcs.c @@ -70,12 +70,11 @@ static void clear_ripng_route(struct ripng *ripng) 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(args->input, "%s/%s", args->xpath, - "input/vrf"); - if (yang_vrf) { - ripng = ripng_lookup_by_vrf_name(yang_vrf->value); + if (args->input && yang_dnode_exists(args->input, "vrf")) { + const char *name = yang_dnode_get_string(args->input, "vrf"); + + ripng = ripng_lookup_by_vrf_name(name); if (ripng) clear_ripng_route(ripng); } else { diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index 80b9013e0f23..e26acf59d19d 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2244,23 +2244,10 @@ DEFPY_YANG (clear_ipv6_rip, "Clear IPv6 RIP database\n" VRF_CMD_HELP_STR) { - struct list *input; - int ret; - - input = list_new(); - if (vrf) { - struct yang_data *yang_vrf; - - yang_vrf = yang_data_new( - "/frr-ripngd:clear-ripng-route/input/vrf", vrf); - listnode_add(input, yang_vrf); - } - - ret = nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", input, NULL); - - list_delete(&input); + if (vrf) + nb_cli_rpc_enqueue(vty, "vrf", vrf); - return ret; + return nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", NULL); } /* Update ECMP routes to zebra when ECMP is disabled. */ diff --git a/zebra/zebra_nb_rpcs.c b/zebra/zebra_nb_rpcs.c index 083ab3fde69d..938193df2f2a 100644 --- a/zebra/zebra_nb_rpcs.c +++ b/zebra/zebra_nb_rpcs.c @@ -20,48 +20,30 @@ 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) { + if (yang_dnode_exists(args->input, "all-vnis")) { zebra_vxlan_clear_dup_detect_vni_all(zvrf); } else { - vni_t vni; + vni_t vni = yang_dnode_get_uint32(args->input, "vni-id"); 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, args->errmsg, - args->errmsg_len); - } 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, args->errmsg, - args->errmsg_len); - } else - ret = zebra_vxlan_clear_dup_detect_vni(zvrf, - vni); + if (yang_dnode_exists(args->input, "mac-addr")) { + yang_dnode_get_mac(&mac, args->input, "mac-addr"); + ret = zebra_vxlan_clear_dup_detect_vni_mac(zvrf, vni, + &mac, + args->errmsg, + args->errmsg_len); + } else if (yang_dnode_exists(args->input, "vni-ipaddr")) { + yang_dnode_get_ip(&host_ip, args->input, "vni-ipaddr"); + ret = zebra_vxlan_clear_dup_detect_vni_ip(zvrf, vni, + &host_ip, + args->errmsg, + args->errmsg_len); + } else { + ret = zebra_vxlan_clear_dup_detect_vni(zvrf, vni); } } if (ret < 0) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 0b5362094eab..bdbb059e5619 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3553,56 +3553,17 @@ DEFPY (clear_evpn_dup_addr, "IPv4 address\n" "IPv6 address\n") { - 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; - - input = list_new(); - if (!vni_str) { - yang_dup = yang_data_new( - "/frr-zebra:clear-evpn-dup-addr/input/clear-dup-choice", - "all-case"); + nb_cli_rpc_enqueue(vty, "all-vnis", NULL); } 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)) { - 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); - } else { - host_ip.ipa_type = IPADDR_V6; - memcpy(&host_ip.ipaddr_v6, &ip->sin6.sin6_addr, - sizeof(struct in6_addr)); - } - - 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(vty, "/frr-zebra:clear-evpn-dup-addr", input, - NULL); + nb_cli_rpc_enqueue(vty, "vni-id", vni_str); + if (mac_str) + nb_cli_rpc_enqueue(vty, "mac-addr", mac_str); + else if (ip_str) + nb_cli_rpc_enqueue(vty, "vni-ipaddr", ip_str); } - list_delete(&input); - - return ret; + return nb_cli_rpc(vty, "/frr-zebra:clear-evpn-dup-addr", NULL); } DEFPY_HIDDEN (evpn_accept_bgp_seq, From 03883ee431565b4a1f4857f6655ed8c97313b204 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Mon, 18 Mar 2024 19:24:40 +0200 Subject: [PATCH 003/472] tests: add test for NB RPC callback Signed-off-by: Igor Ryzhov --- lib/yang.c | 10 +++++ lib/yang.h | 15 +++++++ tests/lib/northbound/test_oper_data.c | 47 ++++++++++++++++++++++ tests/lib/northbound/test_oper_data.in | 1 + tests/lib/northbound/test_oper_data.refout | 2 + yang/frr-test-module.yang | 17 ++++++++ 6 files changed, 92 insertions(+) diff --git a/lib/yang.c b/lib/yang.c index 013a7628424a..f506d8bf2336 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -653,6 +653,16 @@ void yang_dnode_free(struct lyd_node *dnode) lyd_free_all(dnode); } +void yang_dnode_rpc_output_add(struct lyd_node *output, const char *xpath, + const char *value) +{ + LY_ERR err; + + err = lyd_new_path(output, ly_native_ctx, xpath, value, + LYD_NEW_PATH_OUTPUT | LYD_NEW_PATH_UPDATE, NULL); + assert(err == LY_SUCCESS); +} + struct yang_data *yang_data_new(const char *xpath, const char *value) { struct yang_data *data; diff --git a/lib/yang.h b/lib/yang.h index 25703b187903..1903079d1c15 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -535,6 +535,21 @@ extern struct lyd_node *yang_dnode_dup(const struct lyd_node *dnode); */ extern void yang_dnode_free(struct lyd_node *dnode); +/* + * Add a libyang data node to an RPC/action output container. + * + * output + * RPC/action output container. + * + * xpath + * XPath of the data node to add, relative to the output container. + * + * value + * String representing the value of the data node. + */ +extern void yang_dnode_rpc_output_add(struct lyd_node *output, + const char *xpath, const char *value); + /* * Create a new yang_data structure. * diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c index 8f7e7c5f8c71..321f158668e2 100644 --- a/tests/lib/northbound/test_oper_data.c +++ b/tests/lib/northbound/test_oper_data.c @@ -14,6 +14,7 @@ #include "lib_vty.h" #include "log.h" #include "northbound.h" +#include "northbound_cli.h" static struct event_loop *master; @@ -200,6 +201,19 @@ static struct yang_data *frr_test_module_vrfs_vrf_routes_route_active_get_elem( return NULL; } +/* + * XPath: /frr-test-module:frr-test-module/vrfs/vrf/ping + */ +static int frr_test_module_vrfs_vrf_ping(struct nb_cb_rpc_args *args) +{ + const char *vrf = yang_dnode_get_string(args->input, "../name"); + const char *data = yang_dnode_get_string(args->input, "data"); + + yang_dnode_rpc_output_add(args->output, "vrf", vrf); + yang_dnode_rpc_output_add(args->output, "data-out", data); + + return NB_OK; +} /* * XPath: /frr-test-module:frr-test-module/c1value @@ -262,6 +276,10 @@ const struct frr_yang_module_info frr_test_module_info = { .xpath = "/frr-test-module:frr-test-module/vrfs/vrf/routes/route/active", .cbs.get_elem = frr_test_module_vrfs_vrf_routes_route_active_get_elem, }, + { + .xpath = "/frr-test-module:frr-test-module/vrfs/vrf/ping", + .cbs.rpc = frr_test_module_vrfs_vrf_ping, + }, { .xpath = "/frr-test-module:frr-test-module/c1value", .cbs.get_elem = frr_test_module_c1value_get_elem, @@ -277,6 +295,33 @@ const struct frr_yang_module_info frr_test_module_info = { }; /* clang-format on */ +DEFUN(test_rpc, test_rpc_cmd, "test rpc", + "Test\n" + "RPC\n") +{ + struct lyd_node *output = NULL; + char xpath[XPATH_MAXLEN]; + int ret; + + snprintf(xpath, sizeof(xpath), + "/frr-test-module:frr-test-module/vrfs/vrf[name='testname']/ping"); + + nb_cli_rpc_enqueue(vty, "data", "testdata"); + + ret = nb_cli_rpc(vty, xpath, &output); + if (ret != CMD_SUCCESS) { + vty_out(vty, "RPC failed\n"); + return ret; + } + + vty_out(vty, "vrf %s data %s\n", yang_dnode_get_string(output, "vrf"), + yang_dnode_get_string(output, "data-out")); + + yang_dnode_free(output); + + return CMD_SUCCESS; +} + static const struct frr_yang_module_info *const modules[] = { &frr_test_module_info, }; @@ -416,6 +461,8 @@ int main(int argc, char **argv) lib_cmd_init(); nb_init(master, modules, array_size(modules), false); + install_element(ENABLE_NODE, &test_rpc_cmd); + /* Create artificial data. */ create_data(num_vrfs, num_interfaces, num_routes); diff --git a/tests/lib/northbound/test_oper_data.in b/tests/lib/northbound/test_oper_data.in index a6c4f874f500..f7c44cad3154 100644 --- a/tests/lib/northbound/test_oper_data.in +++ b/tests/lib/northbound/test_oper_data.in @@ -1 +1,2 @@ show yang operational-data /frr-test-module:frr-test-module +test rpc diff --git a/tests/lib/northbound/test_oper_data.refout b/tests/lib/northbound/test_oper_data.refout index aa930fe127be..7c565641431c 100644 --- a/tests/lib/northbound/test_oper_data.refout +++ b/tests/lib/northbound/test_oper_data.refout @@ -119,5 +119,7 @@ test# show yang operational-data /frr-test-module:frr-test-module } } } +test# test rpc +vrf testname data testdata test# end. diff --git a/yang/frr-test-module.yang b/yang/frr-test-module.yang index 6cc60e866533..dcf204a95656 100644 --- a/yang/frr-test-module.yang +++ b/yang/frr-test-module.yang @@ -80,6 +80,23 @@ module frr-test-module { } } } + action ping { + input { + leaf data { + type string; + } + } + output { + leaf vrf { + type string; + } + // can't use the same name in input and output + // because of a bug in libyang < 2.1.148 + leaf data-out { + type string; + } + } + } } } choice achoice { From 5c3e95d422d487249ee3c6405ac2cddfa69af394 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Tue, 19 Mar 2024 00:49:19 +0200 Subject: [PATCH 004/472] lib: add native RPC processing to mgmt backend client Signed-off-by: Igor Ryzhov --- lib/mgmt_be_client.c | 143 ++++++++++++++++++++++++++++++++++++++++++ lib/mgmt_be_client.h | 2 + lib/mgmt_msg_native.c | 2 + lib/mgmt_msg_native.h | 40 ++++++++++++ lib/yang.c | 57 +++++++++++++++++ lib/yang.h | 19 ++++++ 6 files changed, 263 insertions(+) diff --git a/lib/mgmt_be_client.c b/lib/mgmt_be_client.c index f483d48d8d0e..6e2fb05e846e 100644 --- a/lib/mgmt_be_client.c +++ b/lib/mgmt_be_client.c @@ -915,6 +915,143 @@ static void be_client_handle_get_tree(struct mgmt_be_client *client, be_client_send_tree_data_batch, args); } +static void be_client_send_rpc_reply(struct mgmt_be_client *client, + uint64_t txn_id, uint64_t req_id, + uint8_t result_type, + struct lyd_node *output) +{ + struct mgmt_msg_rpc_reply *rpc_reply_msg; + uint8_t **darrp; + LY_ERR err; + int ret = NB_OK; + + rpc_reply_msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_rpc_reply, 0, + MTYPE_MSG_NATIVE_RPC_REPLY); + rpc_reply_msg->refer_id = txn_id; + rpc_reply_msg->req_id = req_id; + rpc_reply_msg->code = MGMT_MSG_CODE_RPC_REPLY; + rpc_reply_msg->result_type = result_type; + + if (output) { + darrp = mgmt_msg_native_get_darrp(rpc_reply_msg); + err = yang_print_tree_append(darrp, output, result_type, + LYD_PRINT_SHRINK); + lyd_free_all(output); + if (err) { + ret = NB_ERR; + goto done; + } + } + + (void)be_client_send_native_msg(client, rpc_reply_msg, + mgmt_msg_native_get_msg_len( + rpc_reply_msg), + false); +done: + mgmt_msg_native_free_msg(rpc_reply_msg); + if (ret != NB_OK) + be_client_send_error(client, txn_id, req_id, false, -EINVAL, + "Can't format RPC reply"); +} + +/* + * Process the RPC request. + */ +static void be_client_handle_rpc(struct mgmt_be_client *client, uint64_t txn_id, + void *msgbuf, size_t msg_len) +{ + struct mgmt_msg_rpc *rpc_msg = msgbuf; + struct nb_node *nb_node; + struct lyd_node *input, *output; + const char *xpath; + const char *data; + char errmsg[BUFSIZ] = { 0 }; + LY_ERR err; + int ret; + + debug_be_client("Received RPC request for client %s txn-id %" PRIu64 + " req-id %" PRIu64, + client->name, txn_id, rpc_msg->req_id); + + xpath = mgmt_msg_native_xpath_data_decode(rpc_msg, msg_len, data); + if (!xpath) { + be_client_send_error(client, txn_id, rpc_msg->req_id, false, + -EINVAL, "Corrupt RPC message"); + return; + } + + nb_node = nb_node_find(xpath); + if (!nb_node) { + be_client_send_error(client, txn_id, rpc_msg->req_id, false, + -EINVAL, "No schema found for RPC: %s", + xpath); + return; + } + + if (!nb_node->cbs.rpc) { + be_client_send_error(client, txn_id, rpc_msg->req_id, false, + -EINVAL, "No RPC callback for: %s", xpath); + return; + } + + if (data) { + err = yang_parse_rpc(xpath, rpc_msg->request_type, data, false, + &input); + if (err) { + be_client_send_error(client, txn_id, rpc_msg->req_id, + false, -EINVAL, + "Can't parse RPC data for: %s", + xpath); + return; + } + } else { + /* + * If there's no input data, create an empty input container. + * It is especially needed for actions, because their parents + * may hold necessary information. + */ + err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0, + NULL, &input); + if (err) { + be_client_send_error(client, txn_id, rpc_msg->req_id, + false, -EINVAL, + "Can't create input node for RPC: %s", + xpath); + return; + } + } + + err = lyd_new_path2(NULL, ly_native_ctx, xpath, NULL, 0, 0, 0, NULL, + &output); + if (err) { + lyd_free_all(input); + be_client_send_error(client, txn_id, rpc_msg->req_id, false, + -EINVAL, + "Can't create output node for RPC: %s", + xpath); + return; + } + + ret = nb_callback_rpc(nb_node, xpath, input, output, errmsg, + sizeof(errmsg)); + if (ret != NB_OK) { + lyd_free_all(input); + lyd_free_all(output); + be_client_send_error(client, txn_id, rpc_msg->req_id, false, + -EINVAL, "%s", errmsg); + return; + } + + lyd_free_all(input); + if (!lyd_child(output)) { + lyd_free_all(output); + output = NULL; + } + + be_client_send_rpc_reply(client, txn_id, rpc_msg->req_id, + rpc_msg->request_type, output); +} + /* * Process the notification. */ @@ -975,6 +1112,9 @@ static void be_client_handle_native_msg(struct mgmt_be_client *client, case MGMT_MSG_CODE_GET_TREE: be_client_handle_get_tree(client, txn_id, msg, msg_len); break; + case MGMT_MSG_CODE_RPC: + be_client_handle_rpc(client, txn_id, msg, msg_len); + break; case MGMT_MSG_CODE_NOTIFY: be_client_handle_notify(client, msg, msg_len); break; @@ -1040,6 +1180,9 @@ int mgmt_be_send_subscr_req(struct mgmt_be_client *client_ctx, subscr_req.n_notif_xpaths = client_ctx->cbs.nnotif_xpaths; subscr_req.notif_xpaths = (char **)client_ctx->cbs.notif_xpaths; + subscr_req.n_rpc_xpaths = client_ctx->cbs.nrpc_xpaths; + subscr_req.rpc_xpaths = (char **)client_ctx->cbs.rpc_xpaths; + mgmtd__be_message__init(&be_msg); be_msg.message_case = MGMTD__BE_MESSAGE__MESSAGE_SUBSCR_REQ; be_msg.subscr_req = &subscr_req; diff --git a/lib/mgmt_be_client.h b/lib/mgmt_be_client.h index cd8b23752671..7ad0589bdbcb 100644 --- a/lib/mgmt_be_client.h +++ b/lib/mgmt_be_client.h @@ -75,6 +75,8 @@ struct mgmt_be_client_cbs { const char **notif_xpaths; uint nnotif_xpaths; + const char **rpc_xpaths; + uint nrpc_xpaths; }; /*************************************************************** diff --git a/lib/mgmt_msg_native.c b/lib/mgmt_msg_native.c index 09ea43ece0bf..39ce9abae649 100644 --- a/lib/mgmt_msg_native.c +++ b/lib/mgmt_msg_native.c @@ -16,6 +16,8 @@ DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_GET_DATA, "native get data msg"); DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_NOTIFY, "native get data msg"); DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT, "native edit msg"); DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT_REPLY, "native edit reply msg"); +DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_RPC, "native RPC msg"); +DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_RPC_REPLY, "native RPC reply msg"); int vmgmt_msg_native_send_error(struct msg_conn *conn, uint64_t sess_or_txn_id, uint64_t req_id, bool short_circuit_ok, diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index b7c29862aadd..342f6f04cd7a 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -152,6 +152,8 @@ DECLARE_MTYPE(MSG_NATIVE_GET_DATA); DECLARE_MTYPE(MSG_NATIVE_NOTIFY); DECLARE_MTYPE(MSG_NATIVE_EDIT); DECLARE_MTYPE(MSG_NATIVE_EDIT_REPLY); +DECLARE_MTYPE(MSG_NATIVE_RPC); +DECLARE_MTYPE(MSG_NATIVE_RPC_REPLY); /* * Native message codes @@ -163,6 +165,8 @@ DECLARE_MTYPE(MSG_NATIVE_EDIT_REPLY); #define MGMT_MSG_CODE_NOTIFY 4 #define MGMT_MSG_CODE_EDIT 5 #define MGMT_MSG_CODE_EDIT_REPLY 6 +#define MGMT_MSG_CODE_RPC 7 +#define MGMT_MSG_CODE_RPC_REPLY 8 /* * Datastores @@ -377,6 +381,42 @@ _Static_assert(sizeof(struct mgmt_msg_edit_reply) == offsetof(struct mgmt_msg_edit_reply, data), "Size mismatch"); +/** + * struct mgmt_msg_rpc - RPC/action request. + * + * @request_type: ``LYD_FORMAT`` for the @data. + * @data: the xpath followed by the tree data for the operation. + */ +struct mgmt_msg_rpc { + struct mgmt_msg_header; + uint8_t request_type; + uint8_t resv2[7]; + + alignas(8) char data[]; +}; + +_Static_assert(sizeof(struct mgmt_msg_rpc) == + offsetof(struct mgmt_msg_rpc, data), + "Size mismatch"); + +/** + * struct mgmt_msg_rpc_reply - RPC/action reply. + * + * @result_type: ``LYD_FORMAT`` for the @data. + * @data: the tree data for the reply. + */ +struct mgmt_msg_rpc_reply { + struct mgmt_msg_header; + uint8_t result_type; + uint8_t resv2[7]; + + alignas(8) char data[]; +}; + +_Static_assert(sizeof(struct mgmt_msg_rpc_reply) == + offsetof(struct mgmt_msg_rpc_reply, data), + "Size mismatch"); + /* * Validate that the message ends in a NUL terminating byte */ diff --git a/lib/yang.c b/lib/yang.c index f506d8bf2336..06d29bb9c415 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -774,6 +774,63 @@ LY_ERR yang_parse_notification(const char *xpath, LYD_FORMAT format, return LY_SUCCESS; } +LY_ERR yang_parse_rpc(const char *xpath, LYD_FORMAT format, const char *data, + bool reply, struct lyd_node **rpc) +{ + const struct lysc_node *snode; + struct lyd_node *parent = NULL; + struct ly_in *in = NULL; + LY_ERR err; + + snode = lys_find_path(ly_native_ctx, NULL, xpath, 0); + if (!snode) { + zlog_err("Failed to find RPC/action schema node: %s", xpath); + return LY_ENOTFOUND; + } + + /* If it's an action, create its parent */ + if (snode->nodetype == LYS_ACTION) { + char *parent_xpath = XSTRDUP(MTYPE_TMP, xpath); + + if (yang_xpath_pop_node(parent_xpath) != NB_OK) { + XFREE(MTYPE_TMP, parent_xpath); + zlog_err("Invalid action xpath: %s", xpath); + return LY_EINVAL; + } + + err = lyd_new_path2(NULL, ly_native_ctx, parent_xpath, NULL, 0, + 0, 0, NULL, &parent); + XFREE(MTYPE_TMP, parent_xpath); + if (err) { + zlog_err("Failed to create parent node for action: %s", + ly_last_errmsg()); + return err; + } + } else if (snode->nodetype != LYS_RPC) { + zlog_err("Schema node is not an RPC/action: %s", xpath); + return LY_EINVAL; + } + + err = ly_in_new_memory(data, &in); + if (err) { + lyd_free_all(parent); + zlog_err("Failed to initialize ly_in: %s", ly_last_errmsg()); + return err; + } + + err = lyd_parse_op(ly_native_ctx, parent, in, format, + reply ? LYD_TYPE_REPLY_YANG : LYD_TYPE_RPC_YANG, + NULL, rpc); + ly_in_free(in, 0); + if (err) { + lyd_free_all(parent); + zlog_err("Failed to parse RPC/action: %s", ly_last_errmsg()); + return err; + } + + return LY_SUCCESS; +} + static ssize_t yang_print_darr(void *arg, const void *buf, size_t count) { uint8_t *dst = darr_append_n(*(uint8_t **)arg, count); diff --git a/lib/yang.h b/lib/yang.h index 1903079d1c15..57131f478bac 100644 --- a/lib/yang.h +++ b/lib/yang.h @@ -634,6 +634,25 @@ extern void yang_debugging_set(bool enable); extern LY_ERR yang_parse_notification(const char *xpath, LYD_FORMAT format, const char *data, struct lyd_node **notif); +/* + * Parse a YANG RPC. + * + * Args: + * xpath: xpath of an RPC/action. + * format: LYD_FORMAT of input data. + * data: input data. + * reply: true if the data represents a reply to an RPC/action. + * rpc: pointer to the libyang data tree to store the parsed RPC/action. + * If data represents an action, the pointer to the action node is + * still returned, but it's part of the full data tree with all its + * parents. + * + * Returns: + * LY_ERR from underlying calls. + */ +LY_ERR yang_parse_rpc(const char *xpath, LYD_FORMAT format, const char *data, + bool reply, struct lyd_node **rpc); + /* * "Print" the yang tree in `root` into dynamic sized array. * From 5b219644aeeff43521f0b5e7740a3cc841497955 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Wed, 20 Mar 2024 18:12:33 +0200 Subject: [PATCH 005/472] mgmtd: add backend xpath map for RPC Signed-off-by: Igor Ryzhov --- lib/mgmt.proto | 1 + mgmtd/mgmt_be_adapter.c | 116 ++++++++++++++++++++++++++++++---------- mgmtd/mgmt_be_adapter.h | 12 ++++- mgmtd/mgmt_fe_adapter.c | 3 +- mgmtd/mgmt_txn.c | 4 +- 5 files changed, 103 insertions(+), 33 deletions(-) diff --git a/lib/mgmt.proto b/lib/mgmt.proto index 01a99ab63b98..c95301118bab 100644 --- a/lib/mgmt.proto +++ b/lib/mgmt.proto @@ -79,6 +79,7 @@ message BeSubscribeReq { repeated string config_xpaths = 2; repeated string oper_xpaths = 3; repeated string notif_xpaths = 4; + repeated string rpc_xpaths = 5; } message BeSubscribeReply { diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index 830c410676e7..8ce263bb23ce 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -147,6 +147,8 @@ static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { [MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths, }; +static const char *const *be_client_rpc_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {}; + /* * We would like to have a better ADT than one with O(n) comparisons * @@ -159,6 +161,7 @@ static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { static struct mgmt_be_xpath_map *be_cfg_xpath_map; static struct mgmt_be_xpath_map *be_oper_xpath_map; static struct mgmt_be_xpath_map *be_notif_xpath_map; +static struct mgmt_be_xpath_map *be_rpc_xpath_map; static struct event_loop *mgmt_loop; static struct msg_server mgmt_be_server = {.fd = -1}; @@ -173,8 +176,8 @@ static struct mgmt_be_client_adapter static void mgmt_be_adapter_sched_init_event(struct mgmt_be_client_adapter *adapter); -static bool be_is_client_interested(const char *xpath, - enum mgmt_be_client_id id, bool config); +static bool be_is_client_interested(const char *xpath, enum mgmt_be_client_id id, + enum mgmt_be_xpath_subscr_type type); const char *mgmt_be_client_id2name(enum mgmt_be_client_id id) { @@ -223,16 +226,25 @@ mgmt_be_find_adapter_by_name(const char *name) } static void mgmt_register_client_xpath(enum mgmt_be_client_id id, - const char *xpath, bool config, bool oper) + const char *xpath, + enum mgmt_be_xpath_subscr_type type) { struct mgmt_be_xpath_map **maps, *map; - if (config) + switch (type) { + case MGMT_BE_XPATH_SUBSCR_TYPE_CFG: maps = &be_cfg_xpath_map; - else if (oper) + break; + case MGMT_BE_XPATH_SUBSCR_TYPE_OPER: maps = &be_oper_xpath_map; - else + break; + case MGMT_BE_XPATH_SUBSCR_TYPE_NOTIF: maps = &be_notif_xpath_map; + break; + case MGMT_BE_XPATH_SUBSCR_TYPE_RPC: + maps = &be_rpc_xpath_map; + break; + } darr_foreach_p (*maps, map) { if (!strcmp(xpath, map->xpath_prefix)) { @@ -260,18 +272,28 @@ static void mgmt_be_xpath_map_init(void) /* Initialize the common config init map */ for (init = be_client_config_xpaths[id]; init && *init; init++) { __dbg(" - CFG XPATH: '%s'", *init); - mgmt_register_client_xpath(id, *init, true, false); + mgmt_register_client_xpath(id, *init, + MGMT_BE_XPATH_SUBSCR_TYPE_CFG); } /* Initialize the common oper init map */ for (init = be_client_oper_xpaths[id]; init && *init; init++) { __dbg(" - OPER XPATH: '%s'", *init); - mgmt_register_client_xpath(id, *init, false, true); + mgmt_register_client_xpath(id, *init, + MGMT_BE_XPATH_SUBSCR_TYPE_OPER); + } + + /* Initialize the common RPC init map */ + for (init = be_client_rpc_xpaths[id]; init && *init; init++) { + __dbg(" - RPC XPATH: '%s'", *init); + mgmt_register_client_xpath(id, *init, + MGMT_BE_XPATH_SUBSCR_TYPE_RPC); } } __dbg("Total Cfg XPath Maps: %u", darr_len(be_cfg_xpath_map)); __dbg("Total Oper XPath Maps: %u", darr_len(be_oper_xpath_map)); + __dbg("Total RPC XPath Maps: %u", darr_len(be_rpc_xpath_map)); } static void mgmt_be_xpath_map_cleanup(void) @@ -289,6 +311,10 @@ static void mgmt_be_xpath_map_cleanup(void) darr_foreach_p (be_notif_xpath_map, map) XFREE(MTYPE_MGMTD_XPATH, map->xpath_prefix); darr_free(be_notif_xpath_map); + + darr_foreach_p (be_rpc_xpath_map, map) + XFREE(MTYPE_MGMTD_XPATH, map->xpath_prefix); + darr_free(be_rpc_xpath_map); } @@ -405,11 +431,12 @@ mgmt_be_adapter_handle_msg(struct mgmt_be_client_adapter *adapter, */ switch ((int)be_msg->message_case) { case MGMTD__BE_MESSAGE__MESSAGE_SUBSCR_REQ: - __dbg("Got SUBSCR_REQ from '%s' to register xpaths config: %zu oper: %zu notif: %zu", + __dbg("Got SUBSCR_REQ from '%s' to register xpaths config: %zu oper: %zu notif: %zu rpc: %zu", be_msg->subscr_req->client_name, be_msg->subscr_req->n_config_xpaths, be_msg->subscr_req->n_oper_xpaths, - be_msg->subscr_req->n_notif_xpaths); + be_msg->subscr_req->n_notif_xpaths, + be_msg->subscr_req->n_rpc_xpaths); if (strlen(be_msg->subscr_req->client_name)) { strlcpy(adapter->name, be_msg->subscr_req->client_name, @@ -432,22 +459,29 @@ mgmt_be_adapter_handle_msg(struct mgmt_be_client_adapter *adapter, num = be_msg->subscr_req->n_config_xpaths; for (i = 0; i < num; i++) { xpath = be_msg->subscr_req->config_xpaths[i]; - mgmt_register_client_xpath(adapter->id, xpath, true, - false); + mgmt_register_client_xpath(adapter->id, xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_CFG); } num = be_msg->subscr_req->n_oper_xpaths; for (i = 0; i < num; i++) { xpath = be_msg->subscr_req->oper_xpaths[i]; - mgmt_register_client_xpath(adapter->id, xpath, false, - true); + mgmt_register_client_xpath(adapter->id, xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_OPER); } num = be_msg->subscr_req->n_notif_xpaths; for (i = 0; i < num; i++) { xpath = be_msg->subscr_req->notif_xpaths[i]; - mgmt_register_client_xpath(adapter->id, xpath, false, - false); + mgmt_register_client_xpath(adapter->id, xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_NOTIF); + } + + num = be_msg->subscr_req->n_rpc_xpaths; + for (i = 0; i < num; i++) { + xpath = be_msg->subscr_req->rpc_xpaths[i]; + mgmt_register_client_xpath(adapter->id, xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_RPC); } mgmt_be_send_subscr_reply(adapter, true); @@ -882,7 +916,8 @@ void mgmt_be_get_adapter_config(struct mgmt_be_client_adapter *adapter, goto walk_cont; xpath = lyd_path(dnode, LYD_PATH_STD, NULL, 0); - if (be_is_client_interested(xpath, adapter->id, true)) + if (be_is_client_interested(xpath, adapter->id, + MGMT_BE_XPATH_SUBSCR_TYPE_CFG)) nb_config_diff_add_change(*changes, NB_CB_CREATE, &seq, dnode); else LYD_TREE_DFS_continue = 1; /* skip any subtree */ @@ -893,13 +928,27 @@ void mgmt_be_get_adapter_config(struct mgmt_be_client_adapter *adapter, } } -uint64_t mgmt_be_interested_clients(const char *xpath, bool config) +uint64_t mgmt_be_interested_clients(const char *xpath, + enum mgmt_be_xpath_subscr_type type) { - struct mgmt_be_xpath_map *maps, *map; + struct mgmt_be_xpath_map *maps = NULL, *map; enum mgmt_be_client_id id; uint64_t clients; - maps = config ? be_cfg_xpath_map : be_oper_xpath_map; + switch (type) { + case MGMT_BE_XPATH_SUBSCR_TYPE_CFG: + maps = be_cfg_xpath_map; + break; + case MGMT_BE_XPATH_SUBSCR_TYPE_OPER: + maps = be_oper_xpath_map; + break; + case MGMT_BE_XPATH_SUBSCR_TYPE_NOTIF: + maps = be_notif_xpath_map; + break; + case MGMT_BE_XPATH_SUBSCR_TYPE_RPC: + maps = be_rpc_xpath_map; + break; + } clients = 0; @@ -928,8 +977,8 @@ uint64_t mgmt_be_interested_clients(const char *xpath, bool config) * Returns: * Interested or not. */ -static bool be_is_client_interested(const char *xpath, - enum mgmt_be_client_id id, bool config) +static bool be_is_client_interested(const char *xpath, enum mgmt_be_client_id id, + enum mgmt_be_xpath_subscr_type type) { uint64_t clients; @@ -938,7 +987,7 @@ static bool be_is_client_interested(const char *xpath, __dbg("Checking client: %s for xpath: '%s'", mgmt_be_client_id2name(id), xpath); - clients = mgmt_be_interested_clients(xpath, config); + clients = mgmt_be_interested_clients(xpath, type); if (IS_IDBIT_SET(clients, id)) { __dbg("client: %s: interested", mgmt_be_client_id2name(id)); return true; @@ -998,23 +1047,32 @@ void mgmt_be_xpath_register_write(struct vty *vty) darr_len(be_oper_xpath_map)); darr_foreach_p (be_oper_xpath_map, map) be_show_xpath_register(vty, map); + + vty_out(vty, "\nMGMTD Backend RPC XPath Registry: Count: %u\n", + darr_len(be_rpc_xpath_map)); + darr_foreach_p (be_rpc_xpath_map, map) + be_show_xpath_register(vty, map); } void mgmt_be_show_xpath_registries(struct vty *vty, const char *xpath) { enum mgmt_be_client_id id; struct mgmt_be_client_adapter *adapter; - uint64_t cclients, oclients, combined; - - cclients = mgmt_be_interested_clients(xpath, true); - oclients = mgmt_be_interested_clients(xpath, false); + uint64_t cclients, oclients, rclients, combined; + + cclients = mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_CFG); + oclients = mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_OPER); + rclients = mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_RPC); combined = cclients | oclients; vty_out(vty, "XPath: '%s'\n", xpath); FOREACH_BE_CLIENT_BITS (id, combined) { - vty_out(vty, " -- Client: '%s'\tconfig:%d oper:%d\n", + vty_out(vty, " -- Client: '%s'\tconfig:%d oper:%d rpc:%d\n", mgmt_be_client_id2name(id), IS_IDBIT_SET(cclients, id), - IS_IDBIT_SET(oclients, id)); + IS_IDBIT_SET(oclients, id), IS_IDBIT_SET(rclients, id)); adapter = mgmt_be_get_adapter_by_id(id); if (adapter) vty_out(vty, " -- Adapter: %p\n", adapter); diff --git a/mgmtd/mgmt_be_adapter.h b/mgmtd/mgmt_be_adapter.h index 491410aa153b..c9f2ab1b7a88 100644 --- a/mgmtd/mgmt_be_adapter.h +++ b/mgmtd/mgmt_be_adapter.h @@ -235,15 +235,23 @@ extern void mgmt_be_xpath_register_write(struct vty *vty); */ extern int mgmt_be_send_native(enum mgmt_be_client_id id, void *msg); +enum mgmt_be_xpath_subscr_type { + MGMT_BE_XPATH_SUBSCR_TYPE_CFG, + MGMT_BE_XPATH_SUBSCR_TYPE_OPER, + MGMT_BE_XPATH_SUBSCR_TYPE_NOTIF, + MGMT_BE_XPATH_SUBSCR_TYPE_RPC, +}; + /** * Lookup the clients which are subscribed to a given `xpath` * and the way they are subscribed. * * Args: * xpath - the xpath to check for subscription information. - * config - true for config interest false for oper interest. + * type - type of subscription to check for. */ -extern uint64_t mgmt_be_interested_clients(const char *xpath, bool config); +extern uint64_t mgmt_be_interested_clients(const char *xpath, + enum mgmt_be_xpath_subscr_type type); /** * mgmt_fe_adapter_send_notify() - notify FE clients of a notification. diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index ab0da64d8f88..8ae473fb66fb 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -1215,7 +1215,8 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session, } darr_free(snodes); - clients = mgmt_be_interested_clients(msg->xpath, false); + clients = mgmt_be_interested_clients(msg->xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_OPER); if (!clients && !CHECK_FLAG(msg->flags, GET_DATA_FLAG_CONFIG)) { __dbg("No backends provide xpath: %s for txn-id: %" PRIu64 " session-id: %" PRIu64, diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 901163c6e69a..75abca1cff92 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -880,7 +880,9 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req, __dbg("XPATH: %s, Value: '%s'", xpath, value ? value : "NIL"); - clients = mgmt_be_interested_clients(xpath, true); + clients = + mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_CFG); chg_clients = 0; From cb6c18285235be8a5d030f87db837632cc20611f Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Tue, 19 Mar 2024 21:11:59 +0200 Subject: [PATCH 006/472] mgmtd: add native RPC processing Signed-off-by: Igor Ryzhov --- lib/mgmt_msg_native.h | 5 +- mgmtd/mgmt_be_adapter.c | 10 ++ mgmtd/mgmt_fe_adapter.c | 154 +++++++++++++++++++++++++++- mgmtd/mgmt_fe_adapter.h | 20 ++++ mgmtd/mgmt_memory.c | 2 + mgmtd/mgmt_memory.h | 2 + mgmtd/mgmt_txn.c | 219 ++++++++++++++++++++++++++++++++++++++++ mgmtd/mgmt_txn.h | 37 ++++++- 8 files changed, 446 insertions(+), 3 deletions(-) diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index 342f6f04cd7a..cf528a635638 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -609,7 +609,10 @@ extern int vmgmt_msg_native_send_error(struct msg_conn *conn, const char *__s = NULL; \ if (msg->vsplit && msg->vsplit <= __len && \ msg->data[msg->vsplit - 1] == 0) { \ - (__data) = msg->data + msg->vsplit; \ + if (msg->vsplit < __len) \ + (__data) = msg->data + msg->vsplit; \ + else \ + (__data) = NULL; \ __s = msg->data; \ } \ __s; \ diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index 8ce263bb23ce..f4fa389b879b 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -672,6 +672,7 @@ static void be_adapter_handle_native_msg(struct mgmt_be_client_adapter *adapter, { struct mgmt_msg_notify_data *notify_msg; struct mgmt_msg_tree_data *tree_msg; + struct mgmt_msg_rpc_reply *rpc_msg; struct mgmt_msg_error *error_msg; /* get the transaction */ @@ -696,6 +697,15 @@ static void be_adapter_handle_native_msg(struct mgmt_be_client_adapter *adapter, /* Forward the reply to the txn module */ mgmt_txn_notify_tree_data_reply(adapter, tree_msg, msg_len); break; + case MGMT_MSG_CODE_RPC_REPLY: + /* RPC reply from a backend client */ + rpc_msg = (typeof(rpc_msg))msg; + __dbg("Got RPC_REPLY from '%s' txn-id %" PRIx64, adapter->name, + msg->refer_id); + + /* Forward the reply to the txn module */ + mgmt_txn_notify_rpc_reply(adapter, rpc_msg, msg_len); + break; case MGMT_MSG_CODE_NOTIFY: notify_msg = (typeof(notify_msg))msg; __dbg("Got NOTIFY from '%s'", adapter->name); diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index 8ae473fb66fb..b20e36ce0cd4 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -1101,6 +1101,47 @@ static int fe_adapter_send_tree_data(struct mgmt_fe_session_ctx *session, return ret; } +static int fe_adapter_send_rpc_reply(struct mgmt_fe_session_ctx *session, + uint64_t req_id, uint8_t result_type, + const struct lyd_node *result) +{ + struct mgmt_msg_rpc_reply *msg; + uint8_t **darrp = NULL; + int ret; + + msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_rpc_reply, 0, + MTYPE_MSG_NATIVE_RPC_REPLY); + msg->refer_id = session->session_id; + msg->req_id = req_id; + msg->code = MGMT_MSG_CODE_RPC_REPLY; + msg->result_type = result_type; + + if (result) { + darrp = mgmt_msg_native_get_darrp(msg); + ret = yang_print_tree_append(darrp, result, result_type, 0); + if (ret != LY_SUCCESS) { + __log_err("Error building rpc-reply result for client %s session-id %" PRIu64 + " req-id %" PRIu64 " result type %u", + session->adapter->name, session->session_id, + req_id, result_type); + goto done; + } + } + + __dbg("Sending rpc-reply from adapter %s to session-id %" PRIu64 + " req-id %" PRIu64 " len %u", + session->adapter->name, session->session_id, req_id, + mgmt_msg_native_get_msg_len(msg)); + + ret = fe_adapter_send_native_msg(session->adapter, msg, + mgmt_msg_native_get_msg_len(msg), + false); +done: + mgmt_msg_native_free_msg(msg); + + return ret; +} + static int fe_adapter_send_edit_reply(struct mgmt_fe_session_ctx *session, uint64_t req_id, const char *xpath) { @@ -1271,7 +1312,7 @@ static void fe_adapter_handle_edit(struct mgmt_fe_session_ctx *session, } xpath = mgmt_msg_native_xpath_data_decode(msg, msg_len, data); - if (!xpath || !data) { + if (!xpath) { fe_adapter_send_error(session, msg->req_id, false, -EINVAL, "Invalid message"); return; @@ -1360,6 +1401,96 @@ static void fe_adapter_handle_edit(struct mgmt_fe_session_ctx *session, } } +/** + * fe_adapter_handle_rpc() - Handle an RPC message from an FE client. + * @session: the client session. + * @msg_raw: the message data. + * @msg_len: the length of the message data. + */ +static void fe_adapter_handle_rpc(struct mgmt_fe_session_ctx *session, + void *__msg, size_t msg_len) +{ + struct mgmt_msg_rpc *msg = __msg; + const struct lysc_node *snode; + const char *xpath, *data; + uint64_t req_id = msg->req_id; + uint64_t clients; + int ret; + + __dbg("Received RPC request from client %s for session-id %" PRIu64 + " req-id %" PRIu64, + session->adapter->name, session->session_id, msg->req_id); + + xpath = mgmt_msg_native_xpath_data_decode(msg, msg_len, data); + if (!xpath) { + fe_adapter_send_error(session, req_id, false, -EINVAL, + "Invalid message"); + return; + } + + if (session->txn_id != MGMTD_TXN_ID_NONE) { + fe_adapter_send_error(session, req_id, false, -EINPROGRESS, + "Transaction in progress txn-id: %" PRIu64 + " for session-id: %" PRIu64, + session->txn_id, session->session_id); + return; + } + + snode = lys_find_path(ly_native_ctx, NULL, xpath, 0); + if (!snode) { + fe_adapter_send_error(session, req_id, false, -ENOENT, + "No such path: %s", xpath); + return; + } + + if (snode->nodetype == LYS_RPC) + clients = + mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_RPC); + else if (snode->nodetype == LYS_ACTION) + clients = + mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_CFG); + else { + fe_adapter_send_error(session, req_id, false, -EINVAL, + "Not an RPC or action path: %s", xpath); + return; + } + + if (!clients) { + __dbg("No backends implement xpath: %s for txn-id: %" PRIu64 + " session-id: %" PRIu64, + xpath, session->txn_id, session->session_id); + + fe_adapter_send_error(session, req_id, false, -ENOENT, + "No backends implement xpath: %s", xpath); + return; + } + + /* Start a RPC Transaction */ + session->txn_id = mgmt_create_txn(session->session_id, + MGMTD_TXN_TYPE_RPC); + if (session->txn_id == MGMTD_SESSION_ID_NONE) { + fe_adapter_send_error(session, req_id, false, -EINPROGRESS, + "Failed to create an RPC transaction"); + return; + } + + __dbg("Created new rpc txn-id: %" PRIu64 " for session-id: %" PRIu64, + session->txn_id, session->session_id); + + /* Create an RPC request under the transaction */ + ret = mgmt_txn_send_rpc(session->txn_id, req_id, clients, + msg->request_type, xpath, data, + mgmt_msg_native_data_len_decode(msg, msg_len)); + if (ret) { + /* destroy the just created txn */ + mgmt_destroy_txn(&session->txn_id); + fe_adapter_send_error(session, req_id, false, -EINPROGRESS, + "Failed to create an RPC transaction"); + } +} + /** * Handle a native encoded message from the FE client. */ @@ -1384,6 +1515,9 @@ static void fe_adapter_handle_native_msg(struct mgmt_fe_client_adapter *adapter, case MGMT_MSG_CODE_EDIT: fe_adapter_handle_edit(session, msg, msg_len); break; + case MGMT_MSG_CODE_RPC: + fe_adapter_handle_rpc(session, msg, msg_len); + break; default: __log_err("unknown native message session-id %" PRIu64 " req-id %" PRIu64 " code %u to FE adapter %s", @@ -1623,6 +1757,24 @@ int mgmt_fe_adapter_send_tree_data(uint64_t session_id, uint64_t txn_id, return ret; } +int mgmt_fe_adapter_send_rpc_reply(uint64_t session_id, uint64_t txn_id, + uint64_t req_id, LYD_FORMAT result_type, + const struct lyd_node *result) +{ + struct mgmt_fe_session_ctx *session; + int ret; + + session = mgmt_session_id2ctx(session_id); + if (!session || session->txn_id != txn_id) + return -1; + + ret = fe_adapter_send_rpc_reply(session, req_id, result_type, result); + + mgmt_destroy_txn(&session->txn_id); + + return ret; +} + int mgmt_fe_adapter_send_edit_reply(uint64_t session_id, uint64_t txn_id, uint64_t req_id, bool unlock, bool commit, const char *xpath, int16_t error, diff --git a/mgmtd/mgmt_fe_adapter.h b/mgmtd/mgmt_fe_adapter.h index 8d61ffe9106b..61d6cfae13aa 100644 --- a/mgmtd/mgmt_fe_adapter.h +++ b/mgmtd/mgmt_fe_adapter.h @@ -162,6 +162,26 @@ mgmt_fe_adapter_send_tree_data(uint64_t session_id, uint64_t txn_id, uint32_t wd_options, const struct lyd_node *tree, int partial_error, bool short_circuit_ok); +/** + * Send RPC reply back to client. + * + * This also cleans up and frees the transaction. + * + * Args: + * session_id: the session. + * txn_id: the txn_id this data pertains to + * req_id: the req id for the rpc message + * result_type: the format of the result data. + * result: the results. + * + * Return: + * the return value from the underlying send function. + */ +extern int mgmt_fe_adapter_send_rpc_reply(uint64_t session_id, uint64_t txn_id, + uint64_t req_id, + LYD_FORMAT result_type, + const struct lyd_node *result); + /** * Send edit reply back to client. If error is not 0, a native error is sent. * diff --git a/mgmtd/mgmt_memory.c b/mgmtd/mgmt_memory.c index 0fce61aa9792..72ccca062670 100644 --- a/mgmtd/mgmt_memory.c +++ b/mgmtd/mgmt_memory.c @@ -20,6 +20,7 @@ DEFINE_MGROUP(MGMTD, "mgmt"); DEFINE_MTYPE(MGMTD, MGMTD, "instance"); DEFINE_MTYPE(MGMTD, MGMTD_XPATH, "xpath regex"); +DEFINE_MTYPE(MGMTD, MGMTD_ERR, "error"); DEFINE_MTYPE(MGMTD, MGMTD_BE_ADPATER, "backend adapter"); DEFINE_MTYPE(MGMTD, MGMTD_FE_ADPATER, "frontend adapter"); DEFINE_MTYPE(MGMTD, MGMTD_FE_SESSION, "frontend session"); @@ -30,5 +31,6 @@ DEFINE_MTYPE(MGMTD, MGMTD_TXN_COMMCFG_REQ, "txn commit-config requests"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_GETDATA_REQ, "txn get-data requests"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_GETDATA_REPLY, "txn get-data replies"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_GETTREE_REQ, "txn get-tree requests"); +DEFINE_MTYPE(MGMTD, MGMTD_TXN_RPC_REQ, "txn rpc requests"); DEFINE_MTYPE(MGMTD, MGMTD_TXN_CFG_BATCH, "txn config batches"); DEFINE_MTYPE(MGMTD, MGMTD_CMT_INFO, "commit info"); diff --git a/mgmtd/mgmt_memory.h b/mgmtd/mgmt_memory.h index d5b6aa632ea3..e28586ed830d 100644 --- a/mgmtd/mgmt_memory.h +++ b/mgmtd/mgmt_memory.h @@ -14,6 +14,7 @@ DECLARE_MGROUP(MGMTD); DECLARE_MTYPE(MGMTD); DECLARE_MTYPE(MGMTD_XPATH); +DECLARE_MTYPE(MGMTD_ERR); DECLARE_MTYPE(MGMTD_BE_ADPATER); DECLARE_MTYPE(MGMTD_FE_ADPATER); DECLARE_MTYPE(MGMTD_FE_SESSION); @@ -24,6 +25,7 @@ DECLARE_MTYPE(MGMTD_TXN_COMMCFG_REQ); DECLARE_MTYPE(MGMTD_TXN_GETDATA_REQ); DECLARE_MTYPE(MGMTD_TXN_GETDATA_REPLY); DECLARE_MTYPE(MGMTD_TXN_GETTREE_REQ); +DECLARE_MTYPE(MGMTD_TXN_RPC_REQ); DECLARE_MTYPE(MGMTD_TXN_CFG_BATCH); DECLARE_MTYPE(MGMTD_BE_ADAPTER_MSG_BUF); DECLARE_MTYPE(MGMTD_CMT_INFO); diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 75abca1cff92..25376c16576f 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -29,6 +29,7 @@ enum mgmt_txn_event { MGMTD_TXN_PROC_COMMITCFG, MGMTD_TXN_PROC_GETCFG, MGMTD_TXN_PROC_GETTREE, + MGMTD_TXN_PROC_RPC, MGMTD_TXN_COMMITCFG_TIMEOUT, }; @@ -188,6 +189,15 @@ struct txn_req_get_tree { struct lyd_node *client_results; /* result tree from clients */ }; +struct txn_req_rpc { + char *xpath; /* xpath of rpc/action to invoke */ + uint64_t sent_clients; /* Bitmask of clients sent req to */ + uint64_t recv_clients; /* Bitmask of clients recv reply from */ + uint8_t result_type; /* LYD_FORMAT for results */ + char *errstr; /* error string */ + struct lyd_node *client_results; /* result tree from clients */ +}; + struct mgmt_txn_req { struct mgmt_txn_ctx *txn; enum mgmt_txn_event req_event; @@ -196,6 +206,7 @@ struct mgmt_txn_req { struct mgmt_set_cfg_req *set_cfg; struct mgmt_get_data_req *get_data; struct txn_req_get_tree *get_tree; + struct txn_req_rpc *rpc; struct mgmt_commit_cfg_req commit_cfg; } req; @@ -221,6 +232,7 @@ struct mgmt_txn_ctx { struct event *proc_get_tree; struct event *comm_cfg_timeout; struct event *get_tree_timeout; + struct event *rpc_timeout; struct event *clnup; /* List of backend adapters involved in this transaction */ @@ -252,6 +264,10 @@ struct mgmt_txn_ctx { * List of pending get-tree requests. */ struct mgmt_txn_reqs_head get_tree_reqs; + /* + * List of pending rpc requests. + */ + struct mgmt_txn_reqs_head rpc_reqs; /* * There will always be one commit-config allowed for a given * transaction/session. No need to maintain lists for it. @@ -416,6 +432,15 @@ static struct mgmt_txn_req *mgmt_txn_req_alloc(struct mgmt_txn_ctx *txn, " session-id: %" PRIu64, txn_req->req_id, txn->txn_id, txn->session_id); break; + case MGMTD_TXN_PROC_RPC: + txn_req->req.rpc = XCALLOC(MTYPE_MGMTD_TXN_RPC_REQ, + sizeof(struct txn_req_rpc)); + assert(txn_req->req.rpc); + mgmt_txn_reqs_add_tail(&txn->rpc_reqs, txn_req); + __dbg("Added a new RPC req-id: %" PRIu64 " txn-id: %" PRIu64 + " session-id: %" PRIu64, + txn_req->req_id, txn->txn_id, txn->session_id); + break; case MGMTD_TXN_COMMITCFG_TIMEOUT: break; } @@ -506,6 +531,15 @@ static void mgmt_txn_req_free(struct mgmt_txn_req **txn_req) XFREE(MTYPE_MGMTD_XPATH, (*txn_req)->req.get_tree->xpath); XFREE(MTYPE_MGMTD_TXN_GETTREE_REQ, (*txn_req)->req.get_tree); break; + case MGMTD_TXN_PROC_RPC: + __dbg("Deleting RPC req-id: %" PRIu64 " txn-id: %" PRIu64, + (*txn_req)->req_id, (*txn_req)->txn->txn_id); + req_list = &(*txn_req)->txn->rpc_reqs; + lyd_free_all((*txn_req)->req.rpc->client_results); + XFREE(MTYPE_MGMTD_ERR, (*txn_req)->req.rpc->errstr); + XFREE(MTYPE_MGMTD_XPATH, (*txn_req)->req.rpc->xpath); + XFREE(MTYPE_MGMTD_TXN_RPC_REQ, (*txn_req)->req.rpc); + break; case MGMTD_TXN_COMMITCFG_TIMEOUT: break; } @@ -1308,6 +1342,33 @@ static int txn_get_tree_data_done(struct mgmt_txn_ctx *txn, return ret; } +static int txn_rpc_done(struct mgmt_txn_ctx *txn, struct mgmt_txn_req *txn_req) +{ + struct txn_req_rpc *rpc = txn_req->req.rpc; + uint64_t req_id = txn_req->req_id; + + /* cancel timer and send reply onward */ + EVENT_OFF(txn->rpc_timeout); + + if (rpc->errstr) + mgmt_fe_adapter_txn_error(txn->txn_id, req_id, false, -1, + rpc->errstr); + else if (mgmt_fe_adapter_send_rpc_reply(txn->session_id, txn->txn_id, + req_id, rpc->result_type, + rpc->client_results)) { + __log_err("Error sending the results of RPC for txn-id %" PRIu64 + " req_id %" PRIu64 " to requested type %u", + txn->txn_id, req_id, rpc->result_type); + + (void)mgmt_fe_adapter_txn_error(txn->txn_id, req_id, false, -1, + "Error converting results of RPC"); + } + + /* we're done with the request */ + mgmt_txn_req_free(&txn_req); + + return 0; +} static void txn_get_tree_timeout(struct event *thread) { @@ -1335,6 +1396,31 @@ static void txn_get_tree_timeout(struct event *thread) txn_get_tree_data_done(txn, txn_req); } +static void txn_rpc_timeout(struct event *thread) +{ + struct mgmt_txn_ctx *txn; + struct mgmt_txn_req *txn_req; + + txn_req = (struct mgmt_txn_req *)EVENT_ARG(thread); + txn = txn_req->txn; + + assert(txn); + assert(txn->type == MGMTD_TXN_TYPE_RPC); + + __log_err("Backend timeout txn-id: %" PRIu64 " ending rpc", txn->txn_id); + + /* + * Send a get-tree data reply. + * + * NOTE: The transaction cleanup will be triggered from Front-end + * adapter. + */ + + txn_req->req.rpc->errstr = + XSTRDUP(MTYPE_MGMTD_ERR, "Operation on the backend timed-out"); + txn_rpc_done(txn, txn_req); +} + /* * Send CFG_APPLY_REQs to all the backend client. * @@ -1518,6 +1604,7 @@ static void mgmt_txn_send_getcfg_reply_data(struct mgmt_txn_req *txn_req, case MGMTD_TXN_PROC_SETCFG: case MGMTD_TXN_PROC_COMMITCFG: case MGMTD_TXN_PROC_GETTREE: + case MGMTD_TXN_PROC_RPC: case MGMTD_TXN_COMMITCFG_TIMEOUT: __log_err("Invalid Txn-Req-Event %u", txn_req->req_event); break; @@ -1723,6 +1810,7 @@ static struct mgmt_txn_ctx *mgmt_txn_create_new(uint64_t session_id, mgmt_txn_reqs_init(&txn->set_cfg_reqs); mgmt_txn_reqs_init(&txn->get_cfg_reqs); mgmt_txn_reqs_init(&txn->get_tree_reqs); + mgmt_txn_reqs_init(&txn->rpc_reqs); txn->commit_cfg_req = NULL; txn->refcount = 0; if (!mgmt_txn_mm->next_txn_id) @@ -1892,6 +1980,7 @@ static void mgmt_txn_register_event(struct mgmt_txn_ctx *txn, &txn->comm_cfg_timeout); break; case MGMTD_TXN_PROC_GETTREE: + case MGMTD_TXN_PROC_RPC: assert(!"code bug do not register this event"); break; } @@ -2498,6 +2587,64 @@ int mgmt_txn_send_edit(uint64_t txn_id, uint64_t req_id, return 0; } +int mgmt_txn_send_rpc(uint64_t txn_id, uint64_t req_id, uint64_t clients, + LYD_FORMAT result_type, const char *xpath, + const char *data, size_t data_len) +{ + struct mgmt_txn_ctx *txn; + struct mgmt_txn_req *txn_req; + struct mgmt_msg_rpc *msg; + struct txn_req_rpc *rpc; + uint64_t id; + int ret; + + txn = mgmt_txn_id2ctx(txn_id); + if (!txn) + return -1; + + txn_req = mgmt_txn_req_alloc(txn, req_id, MGMTD_TXN_PROC_RPC); + rpc = txn_req->req.rpc; + rpc->xpath = XSTRDUP(MTYPE_MGMTD_XPATH, xpath); + rpc->result_type = result_type; + + msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_rpc, 0, + MTYPE_MSG_NATIVE_RPC); + msg->refer_id = txn_id; + msg->req_id = req_id; + msg->code = MGMT_MSG_CODE_RPC; + msg->request_type = result_type; + + mgmt_msg_native_xpath_encode(msg, xpath); + if (data) + mgmt_msg_native_append(msg, data, data_len); + + assert(clients); + FOREACH_BE_CLIENT_BITS (id, clients) { + ret = mgmt_be_send_native(id, msg); + if (ret) { + __log_err("Could not send rpc message to backend client %s", + mgmt_be_client_id2name(id)); + continue; + } + + __dbg("Sent rpc req to backend client %s", + mgmt_be_client_id2name(id)); + + /* record that we sent the request to the client */ + rpc->sent_clients |= (1u << id); + } + + mgmt_msg_native_free_msg(msg); + + if (!rpc->sent_clients) + return txn_rpc_done(txn, txn_req); + + event_add_timer(mgmt_txn_tm, txn_rpc_timeout, txn_req, + MGMTD_TXN_RPC_MAX_DELAY_SEC, &txn->rpc_timeout); + + return 0; +} + /* * Error reply from the backend client. */ @@ -2508,6 +2655,7 @@ int mgmt_txn_notify_error(struct mgmt_be_client_adapter *adapter, enum mgmt_be_client_id id = adapter->id; struct mgmt_txn_ctx *txn = mgmt_txn_id2ctx(txn_id); struct txn_req_get_tree *get_tree; + struct txn_req_rpc *rpc; struct mgmt_txn_req *txn_req; if (!txn) { @@ -2520,6 +2668,10 @@ int mgmt_txn_notify_error(struct mgmt_be_client_adapter *adapter, FOREACH_TXN_REQ_IN_LIST (&txn->get_tree_reqs, txn_req) if (txn_req->req_id == req_id) break; + if (!txn_req) + FOREACH_TXN_REQ_IN_LIST (&txn->rpc_reqs, txn_req) + if (txn_req->req_id == req_id) + break; if (!txn_req) { __log_err("Error reply from %s for txn-id %" PRIu64 " cannot find req_id %" PRIu64, @@ -2540,6 +2692,15 @@ int mgmt_txn_notify_error(struct mgmt_be_client_adapter *adapter, if (get_tree->recv_clients != get_tree->sent_clients) return 0; return txn_get_tree_data_done(txn, txn_req); + case MGMTD_TXN_PROC_RPC: + rpc = txn_req->req.rpc; + rpc->recv_clients |= (1u << id); + rpc->errstr = XSTRDUP(MTYPE_MGMTD_ERR, errstr); + + /* check if done yet */ + if (rpc->recv_clients != rpc->sent_clients) + return 0; + return txn_rpc_done(txn, txn_req); /* non-native message events */ case MGMTD_TXN_PROC_SETCFG: @@ -2627,6 +2788,64 @@ int mgmt_txn_notify_tree_data_reply(struct mgmt_be_client_adapter *adapter, return txn_get_tree_data_done(txn, txn_req); } +int mgmt_txn_notify_rpc_reply(struct mgmt_be_client_adapter *adapter, + struct mgmt_msg_rpc_reply *reply_msg, + size_t msg_len) +{ + uint64_t txn_id = reply_msg->refer_id; + uint64_t req_id = reply_msg->req_id; + enum mgmt_be_client_id id = adapter->id; + struct mgmt_txn_ctx *txn = mgmt_txn_id2ctx(txn_id); + struct mgmt_txn_req *txn_req; + struct txn_req_rpc *rpc; + size_t data_len = msg_len - sizeof(*reply_msg); + LY_ERR err; + + if (!txn) { + __log_err("RPC reply from %s for a missing txn-id %" PRIu64, + adapter->name, txn_id); + return -1; + } + + /* Find the request. */ + FOREACH_TXN_REQ_IN_LIST (&txn->rpc_reqs, txn_req) + if (txn_req->req_id == req_id) + break; + if (!txn_req) { + __log_err("RPC reply from %s for txn-id %" PRIu64 + " missing req_id %" PRIu64, + adapter->name, txn_id, req_id); + return -1; + } + + rpc = txn_req->req.rpc; + + /* we don't expect more than one daemon to provide output for an RPC */ + if (!rpc->client_results && data_len > 0) { + err = yang_parse_rpc(rpc->xpath, reply_msg->result_type, + reply_msg->data, true, + &rpc->client_results); + if (err) { + __log_err("RPC reply from %s for txn-id %" PRIu64 + " req_id %" PRIu64 + " error parsing result of type %u", + adapter->name, txn_id, req_id, + reply_msg->result_type); + rpc->errstr = + XSTRDUP(MTYPE_MGMTD_ERR, + "Cannot parse result from the backend"); + } + } + + rpc->recv_clients |= (1u << id); + + /* check if done yet */ + if (rpc->recv_clients != rpc->sent_clients) + return 0; + + return txn_rpc_done(txn, txn_req); +} + void mgmt_txn_status_write(struct vty *vty) { struct mgmt_txn_ctx *txn; diff --git a/mgmtd/mgmt_txn.h b/mgmtd/mgmt_txn.h index aeb74469f141..b6ca288675b7 100644 --- a/mgmtd/mgmt_txn.h +++ b/mgmtd/mgmt_txn.h @@ -21,6 +21,7 @@ #define MGMTD_TXN_CFG_COMMIT_MAX_DELAY_SEC 600 #define MGMTD_TXN_GET_TREE_MAX_DELAY_SEC 600 +#define MGMTD_TXN_RPC_MAX_DELAY_SEC 60 #define MGMTD_TXN_CLEANUP_DELAY_USEC 10 @@ -48,7 +49,8 @@ struct mgmt_edit_req; enum mgmt_txn_type { MGMTD_TXN_TYPE_NONE = 0, MGMTD_TXN_TYPE_CONFIG, - MGMTD_TXN_TYPE_SHOW + MGMTD_TXN_TYPE_SHOW, + MGMTD_TXN_TYPE_RPC, }; static inline const char *mgmt_txn_type2str(enum mgmt_txn_type type) @@ -60,6 +62,8 @@ static inline const char *mgmt_txn_type2str(enum mgmt_txn_type type) return "CONFIG"; case MGMTD_TXN_TYPE_SHOW: return "SHOW"; + case MGMTD_TXN_TYPE_RPC: + return "RPC"; } return "Unknown"; @@ -246,6 +250,25 @@ mgmt_txn_send_edit(uint64_t txn_id, uint64_t req_id, Mgmtd__DatastoreId ds_id, LYD_FORMAT request_type, uint8_t flags, uint8_t operation, const char *xpath, const char *data); +/** + * Send RPC request. + * + * Args: + * txn_id: Transaction identifier. + * req_id: FE client request identifier. + * clients: Bitmask of clients to send RPC to. + * result_type: LYD_FORMAT result format. + * xpath: The xpath of the RPC. + * data: The input parameters data tree. + * data_len: The length of the input parameters data. + * + * Return: + * 0 on success. + */ +extern int mgmt_txn_send_rpc(uint64_t txn_id, uint64_t req_id, uint64_t clients, + LYD_FORMAT result_type, const char *xpath, + const char *data, size_t data_len); + /* * Notifiy backend adapter on connection. */ @@ -312,6 +335,18 @@ extern int mgmt_txn_notify_tree_data_reply(struct mgmt_be_client_adapter *adapte struct mgmt_msg_tree_data *data_msg, size_t msg_len); +/** + * Process a reply from a backend client to our RPC request + * + * Args: + * adapter: The adapter that received the result. + * reply_msg: The message from the backend. + * msg_len: Total length of the message. + */ +extern int mgmt_txn_notify_rpc_reply(struct mgmt_be_client_adapter *adapter, + struct mgmt_msg_rpc_reply *reply_msg, + size_t msg_len); + /* * Dump transaction status to vty. */ From a94f74bc2ed8165b66c640096586e78f63a0aaf4 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Wed, 20 Mar 2024 00:46:07 +0200 Subject: [PATCH 007/472] lib: add native RPC processing to mgmt frontend client Signed-off-by: Igor Ryzhov --- lib/mgmt_fe_client.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ lib/mgmt_fe_client.h | 35 ++++++++++++++++++++++++++++++++++ lib/northbound_cli.c | 16 ++++++++++++++++ lib/vty.c | 40 +++++++++++++++++++++++++++++++++++++++ lib/vty.h | 2 ++ mgmtd/mgmt_vty.c | 16 ++++++++++++++++ 6 files changed, 154 insertions(+) diff --git a/lib/mgmt_fe_client.c b/lib/mgmt_fe_client.c index 3345505213ff..8cfb025f7225 100644 --- a/lib/mgmt_fe_client.c +++ b/lib/mgmt_fe_client.c @@ -360,6 +360,33 @@ int mgmt_fe_send_edit_req(struct mgmt_fe_client *client, uint64_t session_id, return ret; } +int mgmt_fe_send_rpc_req(struct mgmt_fe_client *client, uint64_t session_id, + uint64_t req_id, LYD_FORMAT request_type, + const char *xpath, const char *data) +{ + struct mgmt_msg_rpc *msg; + int ret; + + msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_rpc, 0, + MTYPE_MSG_NATIVE_RPC); + msg->refer_id = session_id; + msg->req_id = req_id; + msg->code = MGMT_MSG_CODE_RPC; + msg->request_type = request_type; + + mgmt_msg_native_xpath_encode(msg, xpath); + if (data) + mgmt_msg_native_append(msg, data, strlen(data) + 1); + + debug_fe_client("Sending RPC_REQ session-id %" PRIu64 " req-id %" PRIu64 + " xpath: %s", + session_id, req_id, xpath); + + ret = mgmt_msg_native_send_msg(&client->client.conn, msg, false); + mgmt_msg_native_free_msg(msg); + return ret; +} + static int mgmt_fe_client_handle_msg(struct mgmt_fe_client *client, Mgmtd__FeMessage *fe_msg) { @@ -534,6 +561,7 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client, struct mgmt_msg_notify_data *notify_msg; struct mgmt_msg_tree_data *tree_msg; struct mgmt_msg_edit_reply *edit_msg; + struct mgmt_msg_rpc_reply *rpc_msg; struct mgmt_msg_error *err_msg; const char *xpath = NULL; const char *data = NULL; @@ -608,6 +636,23 @@ static void fe_client_handle_native_msg(struct mgmt_fe_client *client, session->user_ctx, msg->req_id, xpath); break; + case MGMT_MSG_CODE_RPC_REPLY: + if (!session->client->cbs.rpc_notify) + return; + + rpc_msg = (typeof(rpc_msg))msg; + if (msg_len < sizeof(*rpc_msg)) { + log_err_fe_client("Corrupt rpc-reply msg recv"); + return; + } + dlen = msg_len - sizeof(*rpc_msg); + + session->client->cbs.rpc_notify(client, client->user_data, + session->client_id, + msg->refer_id, + session->user_ctx, msg->req_id, + dlen ? rpc_msg->data : NULL); + break; case MGMT_MSG_CODE_NOTIFY: if (!session->client->cbs.async_notification) return; diff --git a/lib/mgmt_fe_client.h b/lib/mgmt_fe_client.h index 9d569348ae58..20c87044a5e4 100644 --- a/lib/mgmt_fe_client.h +++ b/lib/mgmt_fe_client.h @@ -120,6 +120,12 @@ struct mgmt_fe_client_cbs { uintptr_t session_ctx, uint64_t req_id, const char *xpath); + /* Called when RPC result is returned */ + int (*rpc_notify)(struct mgmt_fe_client *client, uintptr_t user_data, + uint64_t client_id, uint64_t session_id, + uintptr_t session_ctx, uint64_t req_id, + const char *result); + /* Called with asynchronous notifications from backends */ int (*async_notification)(struct mgmt_fe_client *client, uintptr_t user_data, uint64_t client_id, @@ -454,6 +460,35 @@ extern int mgmt_fe_send_edit_req(struct mgmt_fe_client *client, uint8_t flags, uint8_t operation, const char *xpath, const char *data); +/* + * Send RPC request to MGMTD daemon. + * + * client + * Client object. + * + * session_id + * Client session ID. + * + * req_id + * Client request ID. + * + * result_type + * The LYD_FORMAT of the result. + * + * xpath + * the xpath of the RPC. + * + * data + * the data tree. + * + * Returns: + * 0 on success, otherwise msg_conn_send_msg() return values. + */ +extern int mgmt_fe_send_rpc_req(struct mgmt_fe_client *client, + uint64_t session_id, uint64_t req_id, + LYD_FORMAT request_type, const char *xpath, + const char *data); + /* * Destroy library and cleanup everything. */ diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 5be64f01346f..4f962cda5c1d 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -322,6 +322,22 @@ int nb_cli_rpc(struct vty *vty, const char *xpath, struct lyd_node **output_p) assert(err == LY_SUCCESS); } + if (vty_mgmt_fe_enabled()) { + char *data = NULL; + + err = lyd_print_mem(&data, input, LYD_JSON, LYD_PRINT_SHRINK); + assert(err == LY_SUCCESS); + + ret = vty_mgmt_send_rpc_req(vty, LYD_JSON, xpath, data); + + free(data); + lyd_free_all(input); + + if (ret < 0) + return CMD_WARNING; + return CMD_SUCCESS; + } + /* validate input tree to create implicit defaults */ err = lyd_validate_op(input, NULL, LYD_TYPE_RPC_YANG, NULL); assert(err == LY_SUCCESS); diff --git a/lib/vty.c b/lib/vty.c index d69b5eebd270..0a2a7552f8e4 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -3843,6 +3843,26 @@ static int vty_mgmt_edit_result_notified(struct mgmt_fe_client *client, return 0; } +static int vty_mgmt_rpc_result_notified(struct mgmt_fe_client *client, + uintptr_t user_data, uint64_t client_id, + uint64_t session_id, + uintptr_t session_ctx, uint64_t req_id, + const char *result) +{ + struct vty *vty = (struct vty *)session_ctx; + + debug_fe_client("RPC request for client 0x%" PRIx64 " req-id %" PRIu64 + " was successful", + client_id, req_id); + + if (result) + vty_out(vty, "%s\n", result); + + vty_mgmt_resume_response(vty, CMD_SUCCESS); + + return 0; +} + static int vty_mgmt_error_notified(struct mgmt_fe_client *client, uintptr_t user_data, uint64_t client_id, uint64_t session_id, uintptr_t session_ctx, @@ -3885,6 +3905,7 @@ static struct mgmt_fe_client_cbs mgmt_cbs = { .get_data_notify = vty_mgmt_get_data_result_notified, .get_tree_notify = vty_mgmt_get_tree_result_notified, .edit_notify = vty_mgmt_edit_result_notified, + .rpc_notify = vty_mgmt_rpc_result_notified, .error_notify = vty_mgmt_error_notified, }; @@ -4162,6 +4183,25 @@ int vty_mgmt_send_edit_req(struct vty *vty, uint8_t datastore, return 0; } +int vty_mgmt_send_rpc_req(struct vty *vty, LYD_FORMAT request_type, + const char *xpath, const char *data) +{ + vty->mgmt_req_id++; + + if (mgmt_fe_send_rpc_req(mgmt_fe_client, vty->mgmt_session_id, + vty->mgmt_req_id, request_type, xpath, data)) { + zlog_err("Failed to send RPC to MGMTD session-id: %" PRIu64 + " req-id %" PRIu64 ".", + vty->mgmt_session_id, vty->mgmt_req_id); + vty_out(vty, "Failed to send RPC to MGMTD!\n"); + return -1; + } + + vty->mgmt_req_pending_cmd = "MESSAGE_RPC_REQ"; + + return 0; +} + /* Install vty's own commands like `who' command. */ void vty_init(struct event_loop *master_thread, bool do_command_logging) { diff --git a/lib/vty.h b/lib/vty.h index a51cee76fb5d..a9570ef048d5 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -427,6 +427,8 @@ extern int vty_mgmt_send_edit_req(struct vty *vty, uint8_t datastore, LYD_FORMAT request_type, uint8_t flags, uint8_t operation, const char *xpath, const char *data); +extern int vty_mgmt_send_rpc_req(struct vty *vty, LYD_FORMAT request_type, + const char *xpath, const char *data); extern int vty_mgmt_send_lockds_req(struct vty *vty, Mgmtd__DatastoreId ds_id, bool lock, bool scok); extern void vty_mgmt_resume_response(struct vty *vty, int ret); diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c index 61d0760e05d6..8ccb463577d4 100644 --- a/mgmtd/mgmt_vty.c +++ b/mgmtd/mgmt_vty.c @@ -296,6 +296,21 @@ DEFPY(mgmt_edit, mgmt_edit_cmd, return CMD_SUCCESS; } +DEFPY(mgmt_rpc, mgmt_rpc_cmd, + "mgmt rpc XPATH [json|xml]$fmt [DATA]", + MGMTD_STR + "Invoke RPC\n" + "XPath expression specifying the YANG data path\n" + "JSON input format (default)\n" + "XML input format\n" + "Input data tree\n") +{ + LYD_FORMAT format = (fmt && fmt[0] == 'x') ? LYD_XML : LYD_JSON; + + vty_mgmt_send_rpc_req(vty, format, xpath, data); + return CMD_SUCCESS; +} + DEFPY(show_mgmt_get_config, show_mgmt_get_config_cmd, "show mgmt get-config [candidate|operational|running]$dsname WORD$path", SHOW_STR MGMTD_STR @@ -702,6 +717,7 @@ void mgmt_vty_init(void) install_element(CONFIG_NODE, &mgmt_remove_config_data_cmd); install_element(CONFIG_NODE, &mgmt_replace_config_data_cmd); install_element(CONFIG_NODE, &mgmt_edit_cmd); + install_element(CONFIG_NODE, &mgmt_rpc_cmd); install_element(CONFIG_NODE, &mgmt_load_config_cmd); install_element(CONFIG_NODE, &mgmt_save_config_cmd); install_element(CONFIG_NODE, &mgmt_rollback_cmd); From dbaf05ae3df9c285c2660cbd32483e690c7b1a8a Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 21 Mar 2024 17:10:42 +0200 Subject: [PATCH 008/472] ripd: convert RPC commands to mgmtd Signed-off-by: Igor Ryzhov --- mgmtd/mgmt_be_adapter.c | 10 +++++++++- ripd/rip_cli.c | 19 +++++++++++++++++++ ripd/ripd.c | 20 -------------------- ripd/subdir.am | 1 - 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index f4fa389b879b..d830120af10a 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -98,6 +98,10 @@ static const char *const ripd_oper_xpaths[] = { "/ietf-key-chain:key-chains", NULL, }; +static const char *const ripd_rpc_xpaths[] = { + "/frr-ripd", + NULL, +}; #endif #if HAVE_RIPNGD @@ -147,7 +151,11 @@ static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { [MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths, }; -static const char *const *be_client_rpc_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {}; +static const char *const *be_client_rpc_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { +#ifdef HAVE_RIPD + [MGMTD_BE_CLIENT_ID_RIPD] = ripd_rpc_xpaths, +#endif +}; /* * We would like to have a better ADT than one with O(n) comparisons diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index 4d4349b81aff..7066485be065 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -1233,6 +1233,23 @@ DEFPY_YANG(no_rip_distribute_list_prefix, return nb_cli_apply_changes(vty, NULL); } +/* + * XPath: /frr-ripd:clear-rip-route + */ +DEFPY_YANG (clear_ip_rip, + clear_ip_rip_cmd, + "clear ip rip [vrf WORD]", + CLEAR_STR + IP_STR + "Clear IP RIP database\n" + VRF_CMD_HELP_STR) +{ + if (vrf) + nb_cli_rpc_enqueue(vty, "vrf", vrf); + + return nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", NULL); +} + /* RIP node structure. */ static struct cmd_node rip_node = { .name = "rip", @@ -1295,6 +1312,8 @@ void rip_cli_init(void) install_element(INTERFACE_NODE, &ip_rip_bfd_profile_cmd); install_element(INTERFACE_NODE, &no_ip_rip_bfd_profile_cmd); + install_element(ENABLE_NODE, &clear_ip_rip_cmd); + if_rmap_init(RIP_NODE); } /* clang-format off */ diff --git a/ripd/ripd.c b/ripd/ripd.c index 4640880e4941..b8a140c9ca5a 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -3254,25 +3254,6 @@ DEFUN (show_ip_rip_status, return CMD_SUCCESS; } -#include "ripd/ripd_clippy.c" - -/* - * XPath: /frr-ripd:clear-rip-route - */ -DEFPY_YANG (clear_ip_rip, - clear_ip_rip_cmd, - "clear ip rip [vrf WORD]", - CLEAR_STR - IP_STR - "Clear IP RIP database\n" - VRF_CMD_HELP_STR) -{ - if (vrf) - nb_cli_rpc_enqueue(vty, "vrf", vrf); - - return nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", NULL); -} - /* Distribute-list update functions. */ static void rip_distribute_update(struct distribute_ctx *ctx, struct distribute *dist) @@ -3647,7 +3628,6 @@ void rip_init(void) /* Install rip commands. */ install_element(VIEW_NODE, &show_ip_rip_cmd); install_element(VIEW_NODE, &show_ip_rip_status_cmd); - install_element(ENABLE_NODE, &clear_ip_rip_cmd); /* Debug related init. */ rip_debug_init(); diff --git a/ripd/subdir.am b/ripd/subdir.am index 7fb3726077df..aed8d249fea2 100644 --- a/ripd/subdir.am +++ b/ripd/subdir.am @@ -33,7 +33,6 @@ ripd_ripd_SOURCES = \ clippy_scan += \ ripd/rip_bfd.c \ ripd/rip_cli.c \ - ripd/ripd.c \ # end noinst_HEADERS += \ From 6e0e84491b684167324052f8d20a930505795d29 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 21 Mar 2024 20:17:49 +0200 Subject: [PATCH 009/472] ripngd: convert RPC commands to mgmtd Signed-off-by: Igor Ryzhov --- mgmtd/mgmt_be_adapter.c | 7 +++++++ ripngd/ripng_cli.c | 19 +++++++++++++++++++ ripngd/ripngd.c | 20 -------------------- ripngd/subdir.am | 1 - 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index d830120af10a..fadeafa408e1 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -117,6 +117,10 @@ static const char *const ripngd_oper_xpaths[] = { "/frr-ripngd:ripngd", NULL, }; +static const char *const ripngd_rpc_xpaths[] = { + "/frr-ripngd", + NULL, +}; #endif #if HAVE_STATICD @@ -155,6 +159,9 @@ static const char *const *be_client_rpc_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { #ifdef HAVE_RIPD [MGMTD_BE_CLIENT_ID_RIPD] = ripd_rpc_xpaths, #endif +#ifdef HAVE_RIPNGD + [MGMTD_BE_CLIENT_ID_RIPNGD] = ripngd_rpc_xpaths, +#endif }; /* diff --git a/ripngd/ripng_cli.c b/ripngd/ripng_cli.c index 4806861fe08d..99cb68ea3296 100644 --- a/ripngd/ripng_cli.c +++ b/ripngd/ripng_cli.c @@ -624,6 +624,23 @@ DEFPY_YANG(no_ripng_ipv6_distribute_list_prefix, return nb_cli_apply_changes(vty, NULL); } +/* + * XPath: /frr-ripngd:clear-ripng-route + */ +DEFPY_YANG (clear_ipv6_rip, + clear_ipv6_rip_cmd, + "clear ipv6 ripng [vrf WORD]", + CLEAR_STR + IPV6_STR + "Clear IPv6 RIP database\n" + VRF_CMD_HELP_STR) +{ + if (vrf) + nb_cli_rpc_enqueue(vty, "vrf", vrf); + + return nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", NULL); +} + /* RIPng node structure. */ static struct cmd_node cmd_ripng_node = { .name = "ripng", @@ -663,6 +680,8 @@ void ripng_cli_init(void) install_element(INTERFACE_NODE, &ipv6_ripng_split_horizon_cmd); + install_element(ENABLE_NODE, &clear_ipv6_rip_cmd); + if_rmap_init(RIPNG_NODE); } diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index e26acf59d19d..f4dadf377df2 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2231,25 +2231,6 @@ DEFUN (show_ipv6_ripng_status, return CMD_SUCCESS; } -#include "ripngd/ripngd_clippy.c" - -/* - * XPath: /frr-ripngd:clear-ripng-route - */ -DEFPY_YANG (clear_ipv6_rip, - clear_ipv6_rip_cmd, - "clear ipv6 ripng [vrf WORD]", - CLEAR_STR - IPV6_STR - "Clear IPv6 RIP database\n" - VRF_CMD_HELP_STR) -{ - if (vrf) - nb_cli_rpc_enqueue(vty, "vrf", vrf); - - return nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", NULL); -} - /* Update ECMP routes to zebra when ECMP is disabled. */ void ripng_ecmp_disable(struct ripng *ripng) { @@ -2667,7 +2648,6 @@ void ripng_init(void) /* Install ripng commands. */ install_element(VIEW_NODE, &show_ipv6_ripng_cmd); install_element(VIEW_NODE, &show_ipv6_ripng_status_cmd); - install_element(ENABLE_NODE, &clear_ipv6_rip_cmd); ripng_if_init(); ripng_debug_init(); diff --git a/ripngd/subdir.am b/ripngd/subdir.am index a88114432df0..83e376b55530 100644 --- a/ripngd/subdir.am +++ b/ripngd/subdir.am @@ -27,7 +27,6 @@ ripngd_ripngd_SOURCES = \ clippy_scan += \ ripngd/ripng_cli.c \ - ripngd/ripngd.c \ # end noinst_HEADERS += \ From 3c8336c845462edf48e71f624a408f14c2598ac9 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 21 Mar 2024 22:41:48 +0200 Subject: [PATCH 010/472] tests: add topotest for mgmtd rpc processing Signed-off-by: Igor Ryzhov --- mgmtd/mgmt_testc.c | 34 +++++++++++++ tests/topotests/mgmt_rpc/r1/frr.conf | 0 tests/topotests/mgmt_rpc/test_rpc.py | 74 ++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 tests/topotests/mgmt_rpc/r1/frr.conf create mode 100644 tests/topotests/mgmt_rpc/test_rpc.py diff --git a/mgmtd/mgmt_testc.c b/mgmtd/mgmt_testc.c index a33a55efcab3..8bb07ed06863 100644 --- a/mgmtd/mgmt_testc.c +++ b/mgmtd/mgmt_testc.c @@ -18,6 +18,7 @@ /* ---------------- */ static void async_notification(struct nb_cb_notify_args *args); +static int rpc_callback(struct nb_cb_rpc_args *args); static void sigusr1(void); static void sigint(void); @@ -86,6 +87,10 @@ static const struct frr_yang_module_info frr_ripd_info = { .xpath = "/frr-ripd:authentication-failure", .cbs.notify = async_notification, }, + { + .xpath = "/frr-ripd:clear-rip-route", + .cbs.rpc = rpc_callback, + }, { .xpath = NULL, } @@ -113,6 +118,7 @@ FRR_DAEMON_INFO(mgmtd_testc, MGMTD_TESTC, /* clang-format on */ const char **__notif_xpaths; +const char **__rpc_xpaths; struct mgmt_be_client_cbs __client_cbs = {}; struct event *event_timeout; @@ -134,6 +140,7 @@ static void quit(int exit_code) { EVENT_OFF(event_timeout); darr_free(__client_cbs.notif_xpaths); + darr_free(__client_cbs.rpc_xpaths); frr_fini(); @@ -152,6 +159,12 @@ static void timeout(struct event *event) quit(1); } +static void success(struct event *event) +{ + zlog_notice("Success, exiting"); + quit(0); +} + static void async_notification(struct nb_cb_notify_args *args) { zlog_notice("Received YANG notification"); @@ -163,6 +176,23 @@ static void async_notification(struct nb_cb_notify_args *args) quit(0); } +static int rpc_callback(struct nb_cb_rpc_args *args) +{ + const char *vrf = NULL; + + zlog_notice("Received YANG RPC"); + + if (yang_dnode_exists(args->input, "vrf")) + vrf = yang_dnode_get_string(args->input, "vrf"); + + printf("{\"frr-ripd:clear-rip-route\": {\"vrf\": \"%s\"}}\n", vrf); + + event_cancel(&event_timeout); + event_add_timer(master, success, NULL, 1, NULL); + + return 0; +} + int main(int argc, char **argv) { int f_listen = 0; @@ -217,6 +247,10 @@ int main(int argc, char **argv) __client_cbs.nnotif_xpaths = darr_len(__notif_xpaths); } + darr_push(__rpc_xpaths, "/frr-ripd:clear-rip-route"); + __client_cbs.rpc_xpaths = __rpc_xpaths; + __client_cbs.nrpc_xpaths = darr_len(__rpc_xpaths); + mgmt_be_client = mgmt_be_client_create("mgmtd-testc", &__client_cbs, 0, master); diff --git a/tests/topotests/mgmt_rpc/r1/frr.conf b/tests/topotests/mgmt_rpc/r1/frr.conf new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/mgmt_rpc/test_rpc.py b/tests/topotests/mgmt_rpc/test_rpc.py new file mode 100644 index 000000000000..618d9022cea0 --- /dev/null +++ b/tests/topotests/mgmt_rpc/test_rpc.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 eval: (blacken-mode 1) -*- +# SPDX-License-Identifier: ISC +# +# March 21 2024, Igor Ryzhov +# +# Copyright (c) 2024, NFWare Inc. +# + +""" +Test YANG Notifications +""" +import json +import os +import threading + +import pytest +from lib.topogen import Topogen +from lib.topotest import json_cmp + +pytestmark = [pytest.mark.ripd, pytest.mark.mgmtd] + +CWD = os.path.dirname(os.path.realpath(__file__)) + + +@pytest.fixture(scope="module") +def tgen(request): + "Setup/Teardown the environment and provide tgen argument to tests" + + topodef = {"s1": ("r1",)} + + tgen = Topogen(topodef, request.module.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + router.load_frr_config("frr.conf") + + tgen.start_router() + yield tgen + tgen.stop_topology() + + +def test_backend_rpc(tgen): + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + be_client_path = "/usr/lib/frr/mgmtd_testc" + rc, _, _ = r1.net.cmd_status(be_client_path + " --help") + + if rc: + pytest.skip("No mgmtd_testc") + + out = [] + + def run_testc(): + output = r1.net.cmd_raises( + be_client_path + " --timeout 10 --log file:mgmt_testc.log" + ) + out.append(json.loads(output)) + + t = threading.Thread(target=run_testc) + t.start() + + r1.vtysh_cmd("clear ip rip vrf testname") + + t.join() + + jsout = out[0] + + expected = {"frr-ripd:clear-rip-route": {"vrf": "testname"}} + result = json_cmp(jsout, expected) + assert result is None From cb88ce132a68506a1f738accea3c715322722457 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Mon, 22 Apr 2024 16:49:03 +0300 Subject: [PATCH 011/472] lib: fix style and add more comments to NB code Signed-off-by: Igor Ryzhov --- lib/northbound.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/northbound.c b/lib/northbound.c index 57068cc4e050..0bc79d027740 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -932,14 +932,22 @@ static int nb_candidate_edit_tree_add(struct nb_config *candidate, /* if replace failed, restore the original node */ if (existing) { if (root) { + /* Restoring the whole config. */ candidate->dnode = existing; + } else if (ex_parent) { + /* + * Restoring a nested node. Insert it as a + * child. + */ + lyd_insert_child(ex_parent, existing); } else { - if (ex_parent) - lyd_insert_child(ex_parent, existing); - else - lyd_insert_sibling(candidate->dnode, - existing, - &candidate->dnode); + /* + * Restoring a top-level node. Insert it as a + * sibling to candidate->dnode to make sure + * the linkage is correct. + */ + lyd_insert_sibling(candidate->dnode, existing, + &candidate->dnode); } } yang_print_errors(ly_native_ctx, errmsg, errmsg_len); From d346d1ac414c7ce5db6cc7e6b539dc8820d499d3 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 27 Mar 2024 15:04:38 +0100 Subject: [PATCH 012/472] Revert "bgpd: fix 6vpe nexthop" This reverts commit 0325116a27258e1df773a046e8668a029bead60c. It was causing an issue where a nexthop for IPv6 over an IPv4 session was always rewritten to an IPv4-mapped IPv6 address even when a valid IPv6 global address was existing. Link: https://github.com/FRRouting/frr/issues/15610 Signed-off-by: Louis Scalbert --- bgpd/bgp_updgrp_packet.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index bff52c80d8c7..7502bf2ec6dc 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -523,16 +523,11 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, gnh_modified = 1; } - if (peer->nexthop.v4.s_addr != INADDR_ANY && - (IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg) || - (peer->connection->su.sa.sa_family == AF_INET && - paf->afi == AFI_IP6))) { - /* set a IPv4 mapped IPv6 address if no global IPv6 - * address is found or if announcing IPv6 prefix - * over an IPv4 BGP session. - */ - ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, peer->nexthop.v4); - gnh_modified = 1; + if (IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg)) { + if (peer->nexthop.v4.s_addr != INADDR_ANY) { + ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, + peer->nexthop.v4); + } } if (IS_MAPPED_IPV6(&peer->nexthop.v6_global)) { From 8599fe2b5e34b2ac1a46a14983ddcc2336e9116d Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 11:07:23 +0100 Subject: [PATCH 013/472] bgpd: optimize bgp_interface_address_add Move common checks outside of the loop. Signed-off-by: Louis Scalbert --- bgpd/bgp_zebra.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 9a819657734e..520b01b768f1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -335,13 +335,11 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) && !list_isempty(ifc->ifp->nbr_connected)) bgp_start_interface_nbrs(bgp, ifc->ifp); - else { + else if (ifc->address->family == AF_INET6 && + !IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6)) { addr = ifc->address; for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (addr->family == AF_INET) - continue; - /* * If the Peer's interface name matches the * interface name for which BGP received the @@ -355,7 +353,6 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) if ((peer->conf_if && (strcmp(peer->conf_if, ifc->ifp->name) == 0)) && - !IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6) && ((IS_MAPPED_IPV6( &peer->nexthop.v6_global)) || IN6_IS_ADDR_LINKLOCAL( From 778e0df87b7a846f46d84f61ea889a32fe578e49 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 15:49:58 +0100 Subject: [PATCH 014/472] bgpd: reduce bgp_interface_address_add indentation Reduce bgp_interface_address_add indentation Signed-off-by: Louis Scalbert --- bgpd/bgp_zebra.c | 84 ++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 520b01b768f1..a6d2a30013a3 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -325,53 +325,47 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) if (!bgp) return 0; - if (if_is_operative(ifc->ifp)) { - bgp_connected_add(bgp, ifc); + if (!if_is_operative(ifc->ifp)) + return 0; - /* If we have learnt of any neighbors on this interface, - * check to kick off any BGP interface-based neighbors, - * but only if this is a link-local address. - */ - if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) - && !list_isempty(ifc->ifp->nbr_connected)) - bgp_start_interface_nbrs(bgp, ifc->ifp); - else if (ifc->address->family == AF_INET6 && - !IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6)) { - addr = ifc->address; - - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - /* - * If the Peer's interface name matches the - * interface name for which BGP received the - * update and if the received interface address - * is a globalV6 and if the peer is currently - * using a v4-mapped-v6 addr or a link local - * address, then copy the Rxed global v6 addr - * into peer's v6_global and send updates out - * with new nexthop addr. - */ - if ((peer->conf_if && - (strcmp(peer->conf_if, ifc->ifp->name) == - 0)) && - ((IS_MAPPED_IPV6( - &peer->nexthop.v6_global)) || - IN6_IS_ADDR_LINKLOCAL( - &peer->nexthop.v6_global))) { - - if (bgp_debug_zebra(ifc->address)) { - zlog_debug( - "Update peer %pBP's current intf addr %pI6 and send updates", - peer, - &peer->nexthop - .v6_global); - } - memcpy(&peer->nexthop.v6_global, - &addr->u.prefix6, - IPV6_MAX_BYTELEN); - FOREACH_AFI_SAFI (afi, safi) - bgp_announce_route(peer, afi, - safi, true); + bgp_connected_add(bgp, ifc); + + /* If we have learnt of any neighbors on this interface, + * check to kick off any BGP interface-based neighbors, + * but only if this is a link-local address. + */ + if (IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6) && + !list_isempty(ifc->ifp->nbr_connected)) + bgp_start_interface_nbrs(bgp, ifc->ifp); + else if (ifc->address->family == AF_INET6 && + !IN6_IS_ADDR_LINKLOCAL(&ifc->address->u.prefix6)) { + addr = ifc->address; + + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + /* + * If the Peer's interface name matches the + * interface name for which BGP received the + * update and if the received interface address + * is a globalV6 and if the peer is currently + * using a v4-mapped-v6 addr or a link local + * address, then copy the Rxed global v6 addr + * into peer's v6_global and send updates out + * with new nexthop addr. + */ + if ((peer->conf_if && + (strcmp(peer->conf_if, ifc->ifp->name) == 0)) && + ((IS_MAPPED_IPV6(&peer->nexthop.v6_global)) || + IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global))) { + if (bgp_debug_zebra(ifc->address)) { + zlog_debug("Update peer %pBP's current intf addr %pI6 and send updates", + peer, + &peer->nexthop.v6_global); } + memcpy(&peer->nexthop.v6_global, + &addr->u.prefix6, IPV6_MAX_BYTELEN); + FOREACH_AFI_SAFI (afi, safi) + bgp_announce_route(peer, afi, safi, + true); } } } From b083885198157555bbb916ecae9809c5d67a567b Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 11:07:24 +0100 Subject: [PATCH 015/472] bgpd: log new ipv6 global in bgp_interface_address_add Log new IPv6 global address in bgp_interface_address_add Signed-off-by: Louis Scalbert --- bgpd/bgp_zebra.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index a6d2a30013a3..5977180ce513 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -357,9 +357,10 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) ((IS_MAPPED_IPV6(&peer->nexthop.v6_global)) || IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global))) { if (bgp_debug_zebra(ifc->address)) { - zlog_debug("Update peer %pBP's current intf addr %pI6 and send updates", + zlog_debug("Update peer %pBP's current intf global addr from %pI6 to %pI6 and send updates", peer, - &peer->nexthop.v6_global); + &peer->nexthop.v6_global, + &addr->u.prefix6); } memcpy(&peer->nexthop.v6_global, &addr->u.prefix6, IPV6_MAX_BYTELEN); From 424fe0bf809c1d84f16aba3f5e5f8249af29083b Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 11:11:05 +0100 Subject: [PATCH 016/472] bgpd: fix sending ipv6 local nexthop if global present bgpd keeps on advertising IPv6 prefixes with a IPv6 link-local nexthop after a valid IPv6 global appears. At bgpd startup, the IPv6 global is announced by zebra after the link-local. Only the link-local is advertised. Clearing the BGP sessions make the global to to be announced. Update the nexthops with the global IPv6 when available. Signed-off-by: Louis Scalbert --- bgpd/bgp_zebra.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 5977180ce513..5c0a6a09c3df 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -303,11 +303,12 @@ static int bgp_ifp_down(struct interface *ifp) static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) { - struct connected *ifc; + struct connected *ifc, *connected; struct bgp *bgp; struct peer *peer; struct prefix *addr; struct listnode *node, *nnode; + bool v6_ll_in_nh_global; afi_t afi; safi_t safi; @@ -342,6 +343,27 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) addr = ifc->address; for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { + v6_ll_in_nh_global = false; + + if (IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global)) { + frr_each (if_connected, ifc->ifp->connected, + connected) { + if (connected->address->family != + AF_INET6) + continue; + if (!IPV6_ADDR_SAME(&connected->address + ->u.prefix6, + &peer->nexthop + .v6_global)) + continue; + /* peer->nexthop.v6_global contains a link-local address + * that needs to be replaced by the global address. + */ + v6_ll_in_nh_global = true; + break; + } + } + /* * If the Peer's interface name matches the * interface name for which BGP received the @@ -352,10 +374,11 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) * into peer's v6_global and send updates out * with new nexthop addr. */ - if ((peer->conf_if && - (strcmp(peer->conf_if, ifc->ifp->name) == 0)) && - ((IS_MAPPED_IPV6(&peer->nexthop.v6_global)) || - IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global))) { + if (v6_ll_in_nh_global || + (peer->conf_if && + strcmp(peer->conf_if, ifc->ifp->name) == 0 && + (IS_MAPPED_IPV6(&peer->nexthop.v6_global) || + IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_global)))) { if (bgp_debug_zebra(ifc->address)) { zlog_debug("Update peer %pBP's current intf global addr from %pI6 to %pI6 and send updates", peer, From 62913cb15d8195c41229c2f6090d7e189e04646e Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 27 Mar 2024 16:13:46 +0100 Subject: [PATCH 017/472] topotests: add bgp_nexthop_mp_ipv4_6 test Add bgp_nexthop_mp_ipv4_6 topotest to test to nexhop value with MP-BGP IPv4 and IPv6 on IPv4 peering. The test has route-reflector, route-server, iBGP and eBGP peers. Signed-off-by: Louis Scalbert --- .../bgp_nexthop_mp_ipv4_6/__init__.py | 0 .../bgp_nexthop_mp_ipv4_6/h1/zebra.conf | 6 + .../bgp_nexthop_mp_ipv4_6/h2/zebra.conf | 6 + .../bgp_nexthop_mp_ipv4_6/h3/zebra.conf | 6 + .../bgp_nexthop_mp_ipv4_6/r1/bgp_ipv4.json | 70 ++++++ .../r1/bgp_ipv6_step1.json | 90 +++++++ .../bgp_nexthop_mp_ipv4_6/r1/bgpd.conf | 23 ++ .../bgp_nexthop_mp_ipv4_6/r1/zebra.conf | 16 ++ .../bgp_nexthop_mp_ipv4_6/r2/bgp_ipv4.json | 46 ++++ .../r2/bgp_ipv6_step1.json | 53 ++++ .../bgp_nexthop_mp_ipv4_6/r2/bgpd.conf | 11 + .../bgp_nexthop_mp_ipv4_6/r2/isisd.conf | 24 ++ .../bgp_nexthop_mp_ipv4_6/r2/zebra.conf | 12 + .../bgp_nexthop_mp_ipv4_6/r3/bgp_ipv4.json | 46 ++++ .../r3/bgp_ipv6_step1.json | 53 ++++ .../bgp_nexthop_mp_ipv4_6/r3/bgpd.conf | 11 + .../bgp_nexthop_mp_ipv4_6/r3/isisd.conf | 24 ++ .../bgp_nexthop_mp_ipv4_6/r3/zebra.conf | 12 + .../bgp_nexthop_mp_ipv4_6/r4/bgp_ipv4.json | 46 ++++ .../r4/bgp_ipv6_step1.json | 49 ++++ .../bgp_nexthop_mp_ipv4_6/r4/bgpd.conf | 13 + .../bgp_nexthop_mp_ipv4_6/r4/isisd.conf | 26 ++ .../bgp_nexthop_mp_ipv4_6/r4/zebra.conf | 12 + .../bgp_nexthop_mp_ipv4_6/r5/bgp_ipv4.json | 46 ++++ .../r5/bgp_ipv6_step1.json | 49 ++++ .../bgp_nexthop_mp_ipv4_6/r5/bgpd.conf | 13 + .../bgp_nexthop_mp_ipv4_6/r5/isisd.conf | 26 ++ .../bgp_nexthop_mp_ipv4_6/r5/zebra.conf | 12 + .../bgp_nexthop_mp_ipv4_6/r6/bgp_ipv4.json | 46 ++++ .../r6/bgp_ipv6_step1.json | 48 ++++ .../bgp_nexthop_mp_ipv4_6/r6/bgpd.conf | 17 ++ .../bgp_nexthop_mp_ipv4_6/r6/isisd.conf | 31 +++ .../bgp_nexthop_mp_ipv4_6/r6/zebra.conf | 16 ++ .../bgp_nexthop_mp_ipv4_6/r7/bgp_ipv4.json | 46 ++++ .../r7/bgp_ipv6_step1.json | 48 ++++ .../bgp_nexthop_mp_ipv4_6/r7/bgpd.conf | 21 ++ .../bgp_nexthop_mp_ipv4_6/r7/zebra.conf | 12 + .../bgp_nexthop_mp_ipv4_6/r8/bgp_ipv4.json | 46 ++++ .../r8/bgp_ipv6_step1.json | 48 ++++ .../bgp_nexthop_mp_ipv4_6/r8/bgpd.conf | 21 ++ .../bgp_nexthop_mp_ipv4_6/r8/zebra.conf | 12 + .../bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv4.json | 58 +++++ .../rr1/bgp_ipv6_step1.json | 62 +++++ .../bgp_nexthop_mp_ipv4_6/rr1/bgpd.conf | 26 ++ .../bgp_nexthop_mp_ipv4_6/rr1/isisd.conf | 40 +++ .../bgp_nexthop_mp_ipv4_6/rr1/zebra.conf | 21 ++ .../bgp_nexthop_mp_ipv4_6/rs1/bgpd.conf | 21 ++ .../bgp_nexthop_mp_ipv4_6/rs1/isisd.conf | 36 +++ .../bgp_nexthop_mp_ipv4_6/rs1/zebra.conf | 8 + .../test_nexthop_mp_ipv4_6.py | 231 ++++++++++++++++++ 50 files changed, 1716 insertions(+) create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/__init__.py create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/h1/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/h2/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/h3/zebra.conf create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv4.json create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r1/zebra.conf create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv4.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r2/isisd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r2/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv4.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r3/isisd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r3/zebra.conf create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv4.json create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r4/isisd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r4/zebra.conf create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv4.json create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r5/isisd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r5/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv4.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r6/isisd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r6/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv4.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r7/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv4.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r8/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv4.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step1.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/isisd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/bgpd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/isisd.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/zebra.conf create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/__init__.py b/tests/topotests/bgp_nexthop_mp_ipv4_6/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/h1/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/h1/zebra.conf new file mode 100644 index 000000000000..9b19b2cfbd36 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/h1/zebra.conf @@ -0,0 +1,6 @@ +ipv6 route ::/0 fd00:100::2 +ip route 0.0.0.0/0 192.168.1.2 +interface eth-r1 + ip address 192.168.1.1/24 + ipv6 address fd00:100::1/64 +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/h2/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/h2/zebra.conf new file mode 100644 index 000000000000..2bf4a666808a --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/h2/zebra.conf @@ -0,0 +1,6 @@ +ipv6 route ::/0 fd00:700::2 +ip route 0.0.0.0/0 192.168.7.2 +interface eth-r7 + ip address 192.168.7.1/24 + ipv6 address fd00:700::1/64 +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/h3/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/h3/zebra.conf new file mode 100644 index 000000000000..e8b6ac6e268e --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/h3/zebra.conf @@ -0,0 +1,6 @@ +ipv6 route ::/0 fd00:800::2 +ip route 0.0.0.0/0 192.168.8.2 +interface eth-r8 + ip address 192.168.8.1/24 + ipv6 address fd00:800::1/64 +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv4.json new file mode 100755 index 000000000000..12fecee39fdf --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv4.json @@ -0,0 +1,70 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "0.0.0.0", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "multipath": true, + "path": "65000 65700", + "nexthops": [ + { + "ip": "172.16.1.3", + "afi": "ipv4", + "used": true + } + ] + }, + { + "valid": true, + "bestpath": true, + "path": "65000 65700", + "nexthops": [ + { + "ip": "172.16.0.2", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "multipath": true, + "path": "65000 65800", + "nexthops": [ + { + "ip": "172.16.1.3", + "afi": "ipv4", + "used": true + } + ] + }, + { + "valid": true, + "bestpath": true, + "path": "65000 65800", + "nexthops": [ + { + "ip": "172.16.0.2", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step1.json new file mode 100755 index 000000000000..f7c5c7c3b56a --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step1.json @@ -0,0 +1,90 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "::", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "multipath": true, + "path": "65000 65700", + "nexthops": [ + { + "ip": "fd00:0:2::3", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "valid": true, + "bestpath": true, + "path": "65000 65700", + "nexthops": [ + { + "ip": "fd00:0:1::2", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "multipath": true, + "path": "65000 65800", + "nexthops": [ + { + "ip": "fd00:0:2::3", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "valid": true, + "bestpath": true, + "path": "65000 65800", + "nexthops": [ + { + "ip": "fd00:0:1::2", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgpd.conf new file mode 100644 index 000000000000..23b986d1301a --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgpd.conf @@ -0,0 +1,23 @@ +router bgp 65100 + no bgp ebgp-requires-policy + neighbor 172.16.0.2 remote-as external + neighbor 172.16.1.3 remote-as external + ! neighbor 172.16.0.2 capability extended-nexthop + ! + address-family ipv4 unicast + redistribute connected route-map RMAP4 + ! + address-family ipv6 unicast + redistribute connected route-map RMAP6 + neighbor 172.16.0.2 activate + neighbor 172.16.1.3 activate + ! + +ip prefix-list RANGE4 seq 10 permit 192.168.0.0/16 le 24 +ipv6 prefix-list RANGE6 seq 10 permit fd00:100::0/64 + +route-map RMAP4 permit 10 + match ip address prefix-list RANGE4 +! +route-map RMAP6 permit 10 + match ipv6 address prefix-list RANGE6 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/zebra.conf new file mode 100644 index 000000000000..79cbafb5b817 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/zebra.conf @@ -0,0 +1,16 @@ +! +interface eth-h1 + ip address 192.168.1.2/24 + ipv6 address fd00:100::2/64 +! +interface eth-r2 + ip address 172.16.0.1/24 + ipv6 address fd00:0:1::1/64 +! +interface eth-r3 + ip address 172.16.1.1/24 + ipv6 address fd00:0:2::1/64 +! +interface lo + ip address 192.0.2.1/32 + ipv6 address 2001:db8::1/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv4.json new file mode 100755 index 000000000000..64dadf680c0b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv4.json @@ -0,0 +1,46 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "172.16.0.1", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "172.17.0.7", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "172.17.0.8", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step1.json new file mode 100644 index 000000000000..4f86a1a648a5 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step1.json @@ -0,0 +1,53 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "fd00:0:1::1", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgpd.conf new file mode 100644 index 000000000000..badb11cbebe2 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgpd.conf @@ -0,0 +1,11 @@ +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 172.16.0.1 remote-as external + ! neighbor 172.16.0.1 capability extended-nexthop + neighbor 192.0.2.101 remote-as internal + neighbor 192.0.2.101 update-source 192.0.2.2 + ! + address-family ipv6 unicast + neighbor 172.16.0.1 activate + neighbor 192.0.2.101 activate + ! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/isisd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/isisd.conf new file mode 100644 index 000000000000..16963798f817 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/isisd.conf @@ -0,0 +1,24 @@ +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rr1 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r1 + ip router isis 1 + ipv6 router isis 1 + isis passive +! +router isis 1 + net 49.0000.0000.0000.0002.00 + is-type level-1 + lsp-gen-interval 1 + topology ipv6-unicast +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/zebra.conf new file mode 100644 index 000000000000..8997115d87cc --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/zebra.conf @@ -0,0 +1,12 @@ +! +interface eth-r1 + ip address 172.16.0.2/24 + ipv6 address fd00:0:1::2/64 +! +interface eth-rr1 + ip address 10.0.0.2/24 + ipv6 address fd00:0:3::2/64 +! +interface lo + ip address 192.0.2.2/32 + ipv6 address 2001:db8::2/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv4.json new file mode 100644 index 000000000000..0f18a43bf54a --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv4.json @@ -0,0 +1,46 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "172.16.1.1", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "172.17.0.7", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "172.17.0.8", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step1.json new file mode 100644 index 000000000000..f44121c30ef8 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step1.json @@ -0,0 +1,53 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "fd00:0:2::1", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgpd.conf new file mode 100644 index 000000000000..4dec311f511d --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgpd.conf @@ -0,0 +1,11 @@ +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 172.16.1.1 remote-as external + ! neighbor 172.16.1.1 capability extended-nexthop + neighbor 192.0.2.101 remote-as internal + neighbor 192.0.2.101 update-source 192.0.2.3 + ! + address-family ipv6 unicast + neighbor 172.16.1.1 activate + neighbor 192.0.2.101 activate + ! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/isisd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/isisd.conf new file mode 100644 index 000000000000..fe3e307b42ee --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/isisd.conf @@ -0,0 +1,24 @@ +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rr1 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r1 + ip router isis 1 + ipv6 router isis 1 + isis passive +! +router isis 1 + net 49.0000.0000.0000.0003.00 + is-type level-1 + lsp-gen-interval 1 + topology ipv6-unicast +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/zebra.conf new file mode 100644 index 000000000000..8074bbdcde43 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/zebra.conf @@ -0,0 +1,12 @@ +! +interface eth-r1 + ip address 172.16.1.3/24 + ipv6 address fd00:0:2::3/64 +! +interface eth-rr1 + ip address 10.0.1.3/24 + ipv6 address fd00:0:4::3/64 +! +interface lo + ip address 192.0.2.3/32 + ipv6 address 2001:db8::3/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv4.json new file mode 100755 index 000000000000..64dadf680c0b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv4.json @@ -0,0 +1,46 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "172.16.0.1", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "172.17.0.7", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "172.17.0.8", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step1.json new file mode 100755 index 000000000000..756a78e3b141 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step1.json @@ -0,0 +1,49 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "fd00:0:1::1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgpd.conf new file mode 100644 index 000000000000..2dbc4acddc11 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgpd.conf @@ -0,0 +1,13 @@ +router bgp 65000 + neighbor 192.0.2.5 remote-as internal + neighbor 192.0.2.6 remote-as internal + neighbor 192.0.2.101 remote-as internal + neighbor 192.0.2.5 update-source 192.0.2.4 + neighbor 192.0.2.6 update-source 192.0.2.4 + neighbor 192.0.2.101 update-source 192.0.2.4 + ! + address-family ipv6 unicast + neighbor 192.0.2.5 activate + neighbor 192.0.2.6 activate + neighbor 192.0.2.101 activate + ! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/isisd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/isisd.conf new file mode 100644 index 000000000000..21eb80f58b44 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/isisd.conf @@ -0,0 +1,26 @@ +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rr1 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r6 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0004.00 + is-type level-1 + lsp-gen-interval 1 + topology ipv6-unicast +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/zebra.conf new file mode 100644 index 000000000000..c598b345e506 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/zebra.conf @@ -0,0 +1,12 @@ +! +interface eth-r6 + ip address 10.0.4.4/24 + ipv6 address fd00:0:7::4/64 +! +interface eth-rr1 + ip address 10.0.2.4/24 + ipv6 address fd00:0:5::4/64 +! +interface lo + ip address 192.0.2.4/32 + ipv6 address 2001:db8::4/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv4.json new file mode 100755 index 000000000000..64dadf680c0b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv4.json @@ -0,0 +1,46 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "172.16.0.1", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "172.17.0.7", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "172.17.0.8", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step1.json new file mode 100755 index 000000000000..756a78e3b141 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step1.json @@ -0,0 +1,49 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "fd00:0:1::1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgpd.conf new file mode 100644 index 000000000000..101edbd71b21 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgpd.conf @@ -0,0 +1,13 @@ +router bgp 65000 + neighbor 192.0.2.4 remote-as internal + neighbor 192.0.2.6 remote-as internal + neighbor 192.0.2.101 remote-as internal + neighbor 192.0.2.4 update-source 192.0.2.5 + neighbor 192.0.2.6 update-source 192.0.2.5 + neighbor 192.0.2.101 update-source 192.0.2.5 + ! + address-family ipv6 unicast + neighbor 192.0.2.4 activate + neighbor 192.0.2.6 activate + neighbor 192.0.2.101 activate + ! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/isisd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/isisd.conf new file mode 100644 index 000000000000..f998e805b5d9 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/isisd.conf @@ -0,0 +1,26 @@ +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-rr1 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r6 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0005.00 + is-type level-1 + lsp-gen-interval 1 + topology ipv6-unicast +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/zebra.conf new file mode 100644 index 000000000000..7b43db0958cd --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/zebra.conf @@ -0,0 +1,12 @@ +! +interface eth-r6 + ip address 10.0.5.5/24 + ipv6 address fd00:0:8::5/64 +! +interface eth-rr1 + ip address 10.0.3.5/24 + ipv6 address fd00:0:6::5/64 +! +interface lo + ip address 192.0.2.5/32 + ipv6 address 2001:db8::5/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv4.json new file mode 100644 index 000000000000..64dadf680c0b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv4.json @@ -0,0 +1,46 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "172.16.0.1", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "172.17.0.7", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "172.17.0.8", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step1.json new file mode 100644 index 000000000000..1a01ead2cd14 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step1.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "nexthops": [ + { + "ip": "fd00:0:1::1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgpd.conf new file mode 100644 index 000000000000..e036a779ae32 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgpd.conf @@ -0,0 +1,17 @@ +router bgp 65000 + no bgp ebgp-requires-policy + no bgp enforce-first-as + neighbor 192.0.2.4 remote-as internal + neighbor 192.0.2.5 remote-as internal + neighbor 192.0.2.101 remote-as internal + neighbor 172.17.0.201 remote-as external + neighbor 192.0.2.4 update-source 192.0.2.6 + neighbor 192.0.2.5 update-source 192.0.2.6 + neighbor 192.0.2.101 update-source 192.0.2.6 + ! + address-family ipv6 unicast + neighbor 192.0.2.4 activate + neighbor 192.0.2.5 activate + neighbor 192.0.2.101 activate + neighbor 172.17.0.201 activate + ! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/isisd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/isisd.conf new file mode 100644 index 000000000000..b575290e9b0b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/isisd.conf @@ -0,0 +1,31 @@ +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-r4 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r5 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-sw1 + ip router isis 1 + ipv6 router isis 1 + isis passive +! +router isis 1 + net 49.0000.0000.0000.0006.00 + is-type level-1 + lsp-gen-interval 1 + topology ipv6-unicast +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/zebra.conf new file mode 100644 index 000000000000..fce74c146c2d --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/zebra.conf @@ -0,0 +1,16 @@ +! +interface eth-r4 + ip address 10.0.4.6/24 + ipv6 address fd00:0:7::6/64 +! +interface eth-r5 + ip address 10.0.5.6/24 + ipv6 address fd00:0:8::6/64 +! +interface eth-sw1 + ip address 172.17.0.6/24 + ipv6 address fd00:0:9::6/64 +! +interface lo + ip address 192.0.2.6/32 + ipv6 address 2001:db8::6/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv4.json new file mode 100644 index 000000000000..72b0f03c5139 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv4.json @@ -0,0 +1,46 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65000 65100", + "nexthops": [ + { + "ip": "172.17.0.6", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "0.0.0.0", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "172.17.0.8", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step1.json new file mode 100644 index 000000000000..8fe5f7c1de48 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step1.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65000 65100", + "nexthops": [ + { + "ip": "fd00:0:9::6", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "::", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgpd.conf new file mode 100644 index 000000000000..a707b23af0c2 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgpd.conf @@ -0,0 +1,21 @@ +router bgp 65700 + no bgp ebgp-requires-policy + no bgp enforce-first-as + neighbor 172.17.0.201 remote-as external + ! + address-family ipv4 unicast + redistribute connected route-map RMAP4 + ! + address-family ipv6 unicast + redistribute connected route-map RMAP6 + neighbor 172.17.0.201 activate + ! + +ip prefix-list RANGE4 seq 10 permit 192.168.0.0/16 le 24 +ipv6 prefix-list RANGE6 seq 10 permit fd00:700::0/64 + +route-map RMAP4 permit 10 + match ip address prefix-list RANGE4 +! +route-map RMAP6 permit 10 + match ipv6 address prefix-list RANGE6 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/zebra.conf new file mode 100644 index 000000000000..75448297eb78 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/zebra.conf @@ -0,0 +1,12 @@ +! +interface eth-h2 + ip address 192.168.7.2/24 + ipv6 address fd00:700::2/64 +! +interface eth-sw1 + ip address 172.17.0.7/24 + ipv6 address fd00:0:9::7/64 +! +interface lo + ip address 192.0.2.7/32 + ipv6 address 2001:db8::7/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv4.json new file mode 100644 index 000000000000..596ee4b40bcf --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv4.json @@ -0,0 +1,46 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65000 65100", + "nexthops": [ + { + "ip": "172.17.0.6", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "172.17.0.7", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "0.0.0.0", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step1.json new file mode 100644 index 000000000000..20f4940328f7 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step1.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65000 65100", + "nexthops": [ + { + "ip": "fd00:0:9::6", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "::", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgpd.conf new file mode 100644 index 000000000000..d57712dcddbf --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgpd.conf @@ -0,0 +1,21 @@ +router bgp 65800 + no bgp ebgp-requires-policy + no bgp enforce-first-as + neighbor 172.17.0.201 remote-as external + ! + address-family ipv4 unicast + redistribute connected route-map RMAP4 + ! + address-family ipv6 unicast + redistribute connected route-map RMAP6 + neighbor 172.17.0.201 activate + ! + +ip prefix-list RANGE4 seq 10 permit 192.168.0.0/16 le 24 +ipv6 prefix-list RANGE6 seq 10 permit fd00:800::0/64 + +route-map RMAP4 permit 10 + match ip address prefix-list RANGE4 +! +route-map RMAP6 permit 10 + match ipv6 address prefix-list RANGE6 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/zebra.conf new file mode 100644 index 000000000000..7e2479b751d9 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/zebra.conf @@ -0,0 +1,12 @@ +! +interface eth-h3 + ip address 192.168.8.2/24 + ipv6 address fd00:800::2/64 +! +interface eth-sw1 + ip address 172.17.0.8/24 + ipv6 address fd00:0:9::8/64 +! +interface lo + ip address 192.0.2.8/32 + ipv6 address 2001:db8::8/128 diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv4.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv4.json new file mode 100644 index 000000000000..ac67fe069c8b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv4.json @@ -0,0 +1,58 @@ +{ + "routes": { + "192.168.1.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "172.16.0.1", + "afi": "ipv4", + "used": true + } + ] + }, + { + "valid": true, + "multipath": true, + "path": "65100", + "nexthops": [ + { + "ip": "172.16.1.1", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.7.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "172.17.0.7", + "afi": "ipv4", + "used": true + } + ] + } + ], + "192.168.8.0/24": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "172.17.0.8", + "afi": "ipv4", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step1.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step1.json new file mode 100644 index 000000000000..4e359fd97ff9 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step1.json @@ -0,0 +1,62 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "fd00:0:1::1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "valid": true, + "multipath": true, + "path": "65100", + "nexthops": [ + { + "ip": "fd00:0:2::1", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgpd.conf new file mode 100644 index 000000000000..9bbac8b68e9e --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgpd.conf @@ -0,0 +1,26 @@ +router bgp 65000 + neighbor 192.0.2.2 remote-as internal + neighbor 192.0.2.3 remote-as internal + neighbor 192.0.2.4 remote-as internal + neighbor 192.0.2.5 remote-as internal + neighbor 192.0.2.6 remote-as internal + neighbor 192.0.2.2 update-source 192.0.2.101 + neighbor 192.0.2.3 update-source 192.0.2.101 + neighbor 192.0.2.4 update-source 192.0.2.101 + neighbor 192.0.2.5 update-source 192.0.2.101 + neighbor 192.0.2.6 update-source 192.0.2.101 + ! + address-family ipv4 unicast + neighbor 192.0.2.2 route-reflector-client + neighbor 192.0.2.3 route-reflector-client + + ! + address-family ipv6 unicast + neighbor 192.0.2.2 activate + neighbor 192.0.2.3 activate + neighbor 192.0.2.4 activate + neighbor 192.0.2.5 activate + neighbor 192.0.2.6 activate + neighbor 192.0.2.2 route-reflector-client + neighbor 192.0.2.3 route-reflector-client + ! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/isisd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/isisd.conf new file mode 100644 index 000000000000..fe5bcfb9f1bc --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/isisd.conf @@ -0,0 +1,40 @@ +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-r2 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r3 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r4 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +interface eth-r5 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 + isis network point-to-point +! +router isis 1 + net 49.0000.0000.0000.0101.00 + is-type level-1 + lsp-gen-interval 1 + topology ipv6-unicast +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/zebra.conf new file mode 100644 index 000000000000..7f5c8d1c61a1 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/zebra.conf @@ -0,0 +1,21 @@ +! +interface eth-r2 + ip address 10.0.0.101/24 + ipv6 address fd00:0:3::101/64 +! +interface eth-r3 + ip address 10.0.1.101/24 + ipv6 address fd00:0:4::101/64 +! +interface eth-r4 + ip address 10.0.2.101/24 + ipv6 address fd00:0:5::101/64 +! +interface eth-r5 + ip address 10.0.3.101/24 + ipv6 address fd00:0:6::101/64 +! +interface lo + ip address 192.0.2.101/32 + ipv6 address 2001:db8::101/128 + diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/bgpd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/bgpd.conf new file mode 100644 index 000000000000..596cc3e25cb0 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/bgpd.conf @@ -0,0 +1,21 @@ +router bgp 65200 view RS + bgp router-id 192.0.2.201 + no bgp ebgp-requires-policy + neighbor 172.17.0.6 remote-as external + neighbor 172.17.0.7 remote-as external + neighbor 172.17.0.8 remote-as external + ! + address-family ipv4 unicast + neighbor 172.17.0.6 route-server-client + neighbor 172.17.0.7 route-server-client + neighbor 172.17.0.8 route-server-client + + ! + address-family ipv6 unicast + neighbor 172.17.0.6 activate + neighbor 172.17.0.7 activate + neighbor 172.17.0.8 activate + neighbor 172.17.0.6 route-server-client + neighbor 172.17.0.7 route-server-client + neighbor 172.17.0.8 route-server-client + ! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/isisd.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/isisd.conf new file mode 100644 index 000000000000..892b4e7b74e8 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/isisd.conf @@ -0,0 +1,36 @@ +! +interface lo + ip router isis 1 + ipv6 router isis 1 + isis passive +! +interface eth-r2 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +! +interface eth-r3 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +! +interface eth-r4 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +! +interface eth-r5 + ip router isis 1 + ipv6 router isis 1 + isis hello-interval 1 + isis hello-multiplier 3 +! +router isis 1 + net 49.0000.0000.0000.0101.00 + is-type level-1 + lsp-gen-interval 1 + topology ipv6-unicast +! diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/zebra.conf b/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/zebra.conf new file mode 100644 index 000000000000..75ee08363ae4 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rs1/zebra.conf @@ -0,0 +1,8 @@ +interface eth-sw1 + ip address 172.17.0.201/24 + ipv6 address fd00:0:9::201/64 +! +interface lo + ip address 192.0.2.201/32 + ipv6 address 2001:db8::201/128 + diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py new file mode 100644 index 000000000000..a58debd3e286 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by 6WIND +# + +""" +Test BGP nexthop conformity with IPv4,6 MP-BGP over IPv4 peering +""" + +import os +import sys +import json +import functools +from functools import partial +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from lib.checkping import check_ping +from lib.bgp import verify_bgp_convergence_from_running_config + +pytestmark = [pytest.mark.bgpd, pytest.mark.isisd] + + +def build_topo(tgen): + """ + +---+ + | h1| + +---+ + | + +---+ + | r1| AS 65100 + +---+ + / \ _____________ + / \ + +---+ +---+ + | r2| | r3| rr1 is route-reflector + +---+ +---+ for r2 and r3 + \ / + \ / + +---+ + |rr1| AS 65000 + +---+ + / \ + / \ + +---+ +---+ + | r4| | r5| iBGP full-mesh between + +---+ +---+ rr1, r4, r5 and r6 + \ / + \ / + +---+ + | r6| + +---+ + | _____________ + | + | +---+ + [sw1]-----|rs1| AS 65200 + /\ +---+ rs1: route-server + / \ + / \ _____________ + +---+ +---+ + | r7| | r8| AS 65700 (r7) + +---+ +---+ AS 65800 (r8) + | | + +---+ +---+ + | h2| | h3| + +---+ +---+ + """ + + def connect_routers(tgen, left, right): + for rname in [left, right]: + if rname not in tgen.routers().keys(): + tgen.add_router(rname) + + switch = tgen.add_switch("s-{}-{}".format(left, right)) + switch.add_link(tgen.gears[left], nodeif="eth-{}".format(right)) + switch.add_link(tgen.gears[right], nodeif="eth-{}".format(left)) + + def connect_switchs(tgen, rname, switch): + if rname not in tgen.routers().keys(): + tgen.add_router(rname) + + switch.add_link(tgen.gears[rname], nodeif="eth-{}".format(switch.name)) + + connect_routers(tgen, "h1", "r1") + connect_routers(tgen, "r1", "r2") + connect_routers(tgen, "r1", "r3") + connect_routers(tgen, "r2", "rr1") + connect_routers(tgen, "r3", "rr1") + connect_routers(tgen, "rr1", "r4") + connect_routers(tgen, "rr1", "r5") + connect_routers(tgen, "r4", "r6") + connect_routers(tgen, "r5", "r6") + + sw1 = tgen.add_switch("sw1") + connect_switchs(tgen, "r6", sw1) + connect_switchs(tgen, "rs1", sw1) + connect_switchs(tgen, "r7", sw1) + connect_switchs(tgen, "r8", sw1) + + connect_routers(tgen, "r7", "h2") + connect_routers(tgen, "r8", "h3") + + +def setup_module(mod): + "Sets up the pytest environment" + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + logger.info("setup_module") + + for rname, router in tgen.routers().items(): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + if "h" in rname: + # hosts + continue + + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + if rname in ["r1", "r7", "r8", "rs1"]: + # external routers + continue + + router.load_config( + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) + ) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(_mod): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_convergence(): + "Assert that BGP is converging." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("waiting for bgp peers to go up") + + for rname in tgen.routers().keys(): + if "h" in rname: + # hosts + continue + result = verify_bgp_convergence_from_running_config(tgen, dut=rname) + assert result is True, "BGP is not converging on {}".format(rname) + + +def test_bgp_ipv4_nexthop_step1(): + "Assert that BGP has correct ipv4 nexthops." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname, router in tgen.routers().items(): + if "h" in rname: + # hosts + continue + if "rs1" in rname: + continue + ref_file = "{}/{}/bgp_ipv4.json".format(CWD, rname) + expected = json.loads(open(ref_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show bgp ipv4 unicast json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP IPv4 Nexthop failure".format(rname) + assert res is None, assertmsg + + +def test_bgp_ipv6_nexthop_step1(): + "Assert that BGP has correct ipv6 nexthops." + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname, router in tgen.routers().items(): + if "h" in rname: + # hosts + continue + if "rs1" in rname: + continue + ref_file = "{}/{}/bgp_ipv6_step1.json".format(CWD, rname) + expected = json.loads(open(ref_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show bgp ipv6 unicast json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP IPv6 Nexthop failure".format(rname) + assert res is None, assertmsg + + +def test_bgp_ping_ok_step1(): + "Check that h1 pings h2 and h3" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_ping("h1", "192.168.7.1", True, 5, 1) + check_ping("h1", "fd00:700::1", True, 5, 1) + check_ping("h1", "192.168.8.1", True, 5, 1) + check_ping("h1", "fd00:800::1", True, 5, 1) + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From fc1dd2e5060b6e470daa203080bdb9473a637407 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 13:58:32 +0100 Subject: [PATCH 018/472] bgpd: optimize bgp_interface_address_del Move common checks outside of the loop. Signed-off-by: Louis Scalbert --- bgpd/bgp_zebra.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 5c0a6a09c3df..590d192c4b53 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -404,6 +404,8 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) struct peer *peer; struct bgp *bgp; struct prefix *addr; + afi_t afi; + safi_t safi; bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -422,7 +424,8 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) addr = ifc->address; - if (bgp) { + if (bgp && addr->family == AF_INET6 && + !IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix)) { /* * When we are using the v6 global as part of the peering * nexthops and we are removing it, then we need to @@ -431,17 +434,10 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) * we do not want the peering to bounce. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - afi_t afi; - safi_t safi; - - if (addr->family == AF_INET) - continue; - - if (!IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6) - && memcmp(&peer->nexthop.v6_global, - &addr->u.prefix6, 16) - == 0) { - memset(&peer->nexthop.v6_global, 0, 16); + if (IPV6_ADDR_SAME(&peer->nexthop.v6_global, + &addr->u.prefix6)) { + memset(&peer->nexthop.v6_global, 0, + IPV6_MAX_BYTELEN); FOREACH_AFI_SAFI (afi, safi) bgp_announce_route(peer, afi, safi, true); From ee0378cdbb458f9d3710f1fb557368ace8d72477 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 14:29:26 +0100 Subject: [PATCH 019/472] bgpd: fix removing ipv6 global nexhop When the IPv6 global is removed on an interface towards a peer, the IPv6 nexthop global that is sent is a IPv4-mapped IPv6 address. It should be the link-local. At removal, replace the global by the next global address or the link-local as last resort. Signed-off-by: Louis Scalbert --- bgpd/bgp_zebra.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 590d192c4b53..5deea3f32f4f 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -400,10 +400,12 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) { struct listnode *node, *nnode; - struct connected *ifc; + struct connected *ifc, *connected; struct peer *peer; struct bgp *bgp; struct prefix *addr; + struct in6_addr *v6_global = NULL; + struct in6_addr *v6_local = NULL; afi_t afi; safi_t safi; @@ -425,7 +427,17 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) addr = ifc->address; if (bgp && addr->family == AF_INET6 && - !IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix)) { + !IN6_IS_ADDR_LINKLOCAL(&addr->u.prefix6)) { + /* find another IPv6 global if possible and find the IPv6 link-local */ + frr_each (if_connected, ifc->ifp->connected, connected) { + if (connected->address->family != AF_INET6) + continue; + if (IN6_IS_ADDR_LINKLOCAL(&connected->address->u.prefix6)) + v6_local = &connected->address->u.prefix6; + else + v6_global = &connected->address->u.prefix6; + } + /* * When we are using the v6 global as part of the peering * nexthops and we are removing it, then we need to @@ -436,8 +448,15 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { if (IPV6_ADDR_SAME(&peer->nexthop.v6_global, &addr->u.prefix6)) { - memset(&peer->nexthop.v6_global, 0, - IPV6_MAX_BYTELEN); + if (v6_global) + IPV6_ADDR_COPY(&peer->nexthop.v6_global, + v6_global); + else if (v6_local) + IPV6_ADDR_COPY(&peer->nexthop.v6_global, + v6_local); + else + memset(&peer->nexthop.v6_global, 0, + IPV6_MAX_BYTELEN); FOREACH_AFI_SAFI (afi, safi) bgp_announce_route(peer, afi, safi, true); From 2de4dfc97adfec788e45e148b4204196d612c81c Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 15:00:37 +0100 Subject: [PATCH 020/472] bgpd: fix "used" json key on link-local nexthop When a peer has no IPv6 global address to send as nexthop, it sends the IPv6 link-local instead as global. "show bgp ipv6 json" displays the same address in global and link-local scopes. > "nexthops": [ > { > "ip": "fe80::a495:38ff:fea6:6ea3", > "afi": "ipv6", > "scope": "global", > "used": true > }, > { > "ip": "fe80::a495:38ff:fea6:6ea3", > "afi": "ipv6", > "scope": "link-local" > } > ] However, "used" key is set on the global nexthop but not in link-local. It is correct but it makes difficult to test JSON to expect the usage of a link-local. The contrary is also correct. Set "used" key on the link-local nexhop instead to facilitate the tests. Signed-off-by: Louis Scalbert --- bgpd/bgp_route.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 848e8ffd8d87..185ad0e31727 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -9629,10 +9629,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p, json_object_string_add(json_nexthop_ll, "scope", "link-local"); - if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global, - &attr->mp_nexthop_local) != - 0) && - !CHECK_FLAG(attr->nh_flags, + if (!CHECK_FLAG(attr->nh_flags, BGP_ATTR_NH_MP_PREFER_GLOBAL)) json_object_boolean_true_add( json_nexthop_ll, "used"); From 04c220bedb63334a65677a46ef84938cc812221f Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 28 Mar 2024 13:58:33 +0100 Subject: [PATCH 021/472] tests: ipv6 global removal in bgp_nexthop_mp_ipv4_6 Test ipv6 global removal in bgp_nexthop_mp_ipv4_6 Signed-off-by: Louis Scalbert --- .../r1/bgp_ipv6_step2.json | 90 +++++++++++++++++++ .../r2/bgp_ipv6_step2.json | 48 ++++++++++ .../r3/bgp_ipv6_step2.json | 48 ++++++++++ .../r4/bgp_ipv6_step2.json | 49 ++++++++++ .../r5/bgp_ipv6_step2.json | 49 ++++++++++ .../r6/bgp_ipv6_step2.json | 48 ++++++++++ .../r7/bgp_ipv6_step2.json | 48 ++++++++++ .../r8/bgp_ipv6_step2.json | 48 ++++++++++ .../rr1/bgp_ipv6_step2.json | 62 +++++++++++++ .../test_nexthop_mp_ipv4_6.py | 52 +++++++++++ 10 files changed, 542 insertions(+) create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step2.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step2.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step2.json create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step2.json create mode 100755 tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step2.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step2.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step2.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step2.json create mode 100644 tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step2.json diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step2.json new file mode 100755 index 000000000000..f7c5c7c3b56a --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r1/bgp_ipv6_step2.json @@ -0,0 +1,90 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "::", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "multipath": true, + "path": "65000 65700", + "nexthops": [ + { + "ip": "fd00:0:2::3", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "valid": true, + "bestpath": true, + "path": "65000 65700", + "nexthops": [ + { + "ip": "fd00:0:1::2", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "multipath": true, + "path": "65000 65800", + "nexthops": [ + { + "ip": "fd00:0:2::3", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + }, + { + "valid": true, + "bestpath": true, + "path": "65000 65800", + "nexthops": [ + { + "ip": "fd00:0:1::2", + "afi": "ipv6", + "scope": "global" + }, + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step2.json new file mode 100644 index 000000000000..21f36089b6dd --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r2/bgp_ipv6_step2.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step2.json new file mode 100644 index 000000000000..21f36089b6dd --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r3/bgp_ipv6_step2.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "afi": "ipv6", + "scope": "link-local", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step2.json new file mode 100755 index 000000000000..7d0786c0ef7b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r4/bgp_ipv6_step2.json @@ -0,0 +1,49 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "2001:db8::2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step2.json new file mode 100755 index 000000000000..7d0786c0ef7b --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r5/bgp_ipv6_step2.json @@ -0,0 +1,49 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "2001:db8::2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "scope": "global", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step2.json new file mode 100644 index 000000000000..55912dd74ca4 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r6/bgp_ipv6_step2.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "nexthops": [ + { + "ip": "2001:db8::2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step2.json new file mode 100644 index 000000000000..8fe5f7c1de48 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r7/bgp_ipv6_step2.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65000 65100", + "nexthops": [ + { + "ip": "fd00:0:9::6", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "::", + "afi": "ipv6", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step2.json new file mode 100644 index 000000000000..20f4940328f7 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/r8/bgp_ipv6_step2.json @@ -0,0 +1,48 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65000 65100", + "nexthops": [ + { + "ip": "fd00:0:9::6", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "", + "nexthops": [ + { + "ip": "::", + "afi": "ipv6", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step2.json b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step2.json new file mode 100644 index 000000000000..4ab0e1c2aec5 --- /dev/null +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/rr1/bgp_ipv6_step2.json @@ -0,0 +1,62 @@ +{ + "routes": { + "fd00:100::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65100", + "nexthops": [ + { + "ip": "2001:db8::2", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + }, + { + "valid": true, + "multipath": true, + "path": "65100", + "nexthops": [ + { + "ip": "2001:db8::3", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:700::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65700", + "nexthops": [ + { + "ip": "fd00:0:9::7", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ], + "fd00:800::/64": [ + { + "valid": true, + "bestpath": true, + "path": "65800", + "nexthops": [ + { + "ip": "fd00:0:9::8", + "afi": "ipv6", + "scope": "global", + "used": true + } + ] + } + ] + } +} diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py index a58debd3e286..0058f213da81 100644 --- a/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py @@ -226,6 +226,58 @@ def test_bgp_ping_ok_step1(): check_ping("h1", "fd00:800::1", True, 5, 1) +def test_bgp_ipv6_nexthop_step2(): + """ + Remove IPv6 global on r1 and r7 + Assert that BGP has correct ipv6 nexthops. + """ + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + tgen.gears["r1"].vtysh_cmd( + """ +configure +interface eth-r2 + no ipv6 address fd00:0:1::1/64 +! +interface eth-r3 + no ipv6 address fd00:0:2::1/64 +""" + ) + + for rname, router in tgen.routers().items(): + if "h" in rname: + # hosts + continue + if "rs1" in rname: + continue + ref_file = "{}/{}/bgp_ipv6_step2.json".format(CWD, rname) + expected = json.loads(open(ref_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show bgp ipv6 unicast json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = "{}: BGP IPv6 Nexthop failure".format(rname) + assert res is None, assertmsg + + +def test_bgp_ping_ok_step2(): + "Check that h1 pings h2 and h3" + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_ping("h1", "192.168.7.1", True, 5, 1) + check_ping("h1", "fd00:700::1", True, 5, 1) + check_ping("h1", "192.168.8.1", True, 5, 1) + check_ping("h1", "fd00:800::1", True, 5, 1) + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) From fc5a738409eac9ca938cbb398872ea77d9cc5023 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 29 Mar 2024 16:14:14 +0100 Subject: [PATCH 022/472] bgpd: set ipv4-mapped ipv6 for ipv4 with ipv6 nexthop The code was expected that no IPv6 global address was present but the previous commit was replacing nexthop.v6global by the link-local address instead of un-setting it in case of removal of the IPv6 global. Set also ipv4-mapped ipv6 address as nexthop when a link-local is found and it is an ipv4 prefix over ipv6 nexthop. Signed-off-by: Louis Scalbert --- bgpd/bgp_updgrp_packet.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 7502bf2ec6dc..1f691b6a9e19 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -523,11 +523,13 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, gnh_modified = 1; } - if (IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg)) { - if (peer->nexthop.v4.s_addr != INADDR_ANY) { - ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, - peer->nexthop.v4); - } + if (peer->nexthop.v4.s_addr != INADDR_ANY && + (IN6_IS_ADDR_UNSPECIFIED(mod_v6nhg) || + (IN6_IS_ADDR_LINKLOCAL(mod_v6nhg) && + peer->connection->su.sa.sa_family == AF_INET6 && + paf->afi == AFI_IP))) { + ipv4_to_ipv4_mapped_ipv6(mod_v6nhg, peer->nexthop.v4); + gnh_modified = 1; } if (IS_MAPPED_IPV6(&peer->nexthop.v6_global)) { From 5dd731af8421e8b3070eec0b3af4ad234c95c6bb Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 8 Apr 2024 13:18:20 +0200 Subject: [PATCH 023/472] bgpd: prefer link-local to a ipv4-mapped ipv6 global When a peer sends an IPv4-mapped IPv6 global and a IPv6 link-local nexthop, prefer the link-local unless a route-map tells to use the global. Signed-off-by: Louis Scalbert --- bgpd/bgp_nht.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 80ec9bcf7730..fcaf2aebe37b 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -320,11 +320,6 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, afi = BGP_ATTR_MP_NEXTHOP_LEN_IP6(pi->attr) ? AFI_IP6 : AFI_IP; - /* Validation for the ipv4 mapped ipv6 nexthop. */ - if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) { - afi = AFI_IP; - } - /* This will return true if the global IPv6 NH is a link local * addr */ if (make_prefix(afi, pi, &p) < 0) @@ -1043,19 +1038,11 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) p->u.prefix4 = p_orig->u.prefix4; p->prefixlen = p_orig->prefixlen; } else { - if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) { - ipv4_mapped_ipv6_to_ipv4( - &pi->attr->mp_nexthop_global, &ipv4); - p->u.prefix4 = ipv4; - p->prefixlen = IPV4_MAX_BITLEN; - } else { - if (p_orig->family == AF_EVPN) - p->u.prefix4 = - pi->attr->mp_nexthop_global_in; - else - p->u.prefix4 = pi->attr->nexthop; - p->prefixlen = IPV4_MAX_BITLEN; - } + if (p_orig->family == AF_EVPN) + p->u.prefix4 = pi->attr->mp_nexthop_global_in; + else + p->u.prefix4 = pi->attr->nexthop; + p->prefixlen = IPV4_MAX_BITLEN; } break; case AFI_IP6: @@ -1071,6 +1058,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) /* If we receive MP_REACH nexthop with ::(LL) * or LL(LL), use LL address as nexthop cache. */ + p->prefixlen = IPV6_MAX_BITLEN; if (pi->attr && pi->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL && @@ -1085,15 +1073,22 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) pi->attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { if (CHECK_FLAG(pi->attr->nh_flags, - BGP_ATTR_NH_MP_PREFER_GLOBAL)) - p->u.prefix6 = - pi->attr->mp_nexthop_global; - else + BGP_ATTR_NH_MP_PREFER_GLOBAL)) { + if (IS_MAPPED_IPV6( + &pi->attr->mp_nexthop_global)) { + ipv4_mapped_ipv6_to_ipv4( + &pi->attr->mp_nexthop_global, + &ipv4); + p->u.prefix4 = ipv4; + p->prefixlen = IPV4_MAX_BITLEN; + } else + p->u.prefix6 = + pi->attr->mp_nexthop_global; + } else p->u.prefix6 = pi->attr->mp_nexthop_local; } else p->u.prefix6 = pi->attr->mp_nexthop_global; - p->prefixlen = IPV6_MAX_BITLEN; } break; default: From f1b8364ab3784cebfc0689883efdb21ac7d06213 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Sat, 30 Mar 2024 11:32:32 +0100 Subject: [PATCH 024/472] topotests: update bgp_vrf_leaking_5549_routes Before the patch-set, ce1 was sending an IPv6 Link-local as global and link-local nexthop to pe1. Set bgp_vrf_leaking_5549_routes in accordance with the previous fixes. Signed-off-by: Louis Scalbert --- .../pe1/results/vrf10_ipv4_unicast.json | 7 ++++--- .../pe1/results/vrf20_ipv4_unicast.json | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf10_ipv4_unicast.json b/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf10_ipv4_unicast.json index 768bffbe9d71..f664bb6b526a 100644 --- a/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf10_ipv4_unicast.json +++ b/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf10_ipv4_unicast.json @@ -15,15 +15,16 @@ "origin": "incomplete", "nexthops": [ { + "ip": "::ffff:c000:202", "hostname": "ce1", "afi": "ipv6", - "scope": "global", - "used": true + "scope": "global" }, { "hostname": "ce1", "afi": "ipv6", - "scope": "link-local" + "scope": "link-local", + "used": true } ] } diff --git a/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf20_ipv4_unicast.json b/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf20_ipv4_unicast.json index 1e93715270cf..3498ed4326b4 100644 --- a/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf20_ipv4_unicast.json +++ b/tests/topotests/bgp_vrf_leaking_5549_routes/pe1/results/vrf20_ipv4_unicast.json @@ -17,15 +17,16 @@ "nhVrfName": "vrf10", "nexthops": [ { + "ip": "::ffff:c000:202", "hostname": "pe1", "afi": "ipv6", - "scope": "global", - "used": true + "scope": "global" }, { "hostname": "pe1", "afi": "ipv6", - "scope": "link-local" + "scope": "link-local", + "used": true } ] } From 57b9ecf3f96c0e87f3f759c067601731dcfaf5b8 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 10 Jan 2024 16:24:01 +0100 Subject: [PATCH 025/472] build: include our own copy of if.h and dependencies Import our a copy of Linux if.h and its dependencies (compiler_types.h and libc-compat.h) from the above links. In "if.h", "#include " has been replaced by "#include ". libc-compat.h is needed to avoid conflicts with glibc. Include "linux/if.h" in "zebra.h" when compiling on Linux. De-reference "net/if.h" in C files. Note that "net/if.h" is still needed. It is even included in many Linux kernel files. "linux/if.h" provides additional definitions. Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/linux/if.h?h=v5.5 Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/linux/libc-compat.h?h=v5.5 Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/linux/compiler_types.h?h=v5.5 Link: https://patchwork.ozlabs.org/project/glibc/patch/1461512707-23058-1-git-send-email-mikko.rapeli@iki.fi/ Signed-off-by: Louis Scalbert --- include/linux/compiler_types.h | 246 +++++++++++++++++++++++++++ include/linux/if.h | 296 +++++++++++++++++++++++++++++++++ include/linux/libc-compat.h | 267 +++++++++++++++++++++++++++++ include/subdir.am | 3 + lib/if.c | 6 + 5 files changed, 818 insertions(+) create mode 100644 include/linux/compiler_types.h create mode 100644 include/linux/if.h create mode 100644 include/linux/libc-compat.h diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h new file mode 100644 index 000000000000..72393a8c1a6c --- /dev/null +++ b/include/linux/compiler_types.h @@ -0,0 +1,246 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __LINUX_COMPILER_TYPES_H +#define __LINUX_COMPILER_TYPES_H + +#ifndef __ASSEMBLY__ + +#ifdef __CHECKER__ +# define __user __attribute__((noderef, address_space(1))) +# define __kernel __attribute__((address_space(0))) +# define __safe __attribute__((safe)) +# define __force __attribute__((force)) +# define __nocast __attribute__((nocast)) +# define __iomem __attribute__((noderef, address_space(2))) +# define __must_hold(x) __attribute__((context(x,1,1))) +# define __acquires(x) __attribute__((context(x,0,1))) +# define __releases(x) __attribute__((context(x,1,0))) +# define __acquire(x) __context__(x,1) +# define __release(x) __context__(x,-1) +# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) +# define __percpu __attribute__((noderef, address_space(3))) +# define __rcu __attribute__((noderef, address_space(4))) +# define __private __attribute__((noderef)) +extern void __chk_user_ptr(const volatile void __user *); +extern void __chk_io_ptr(const volatile void __iomem *); +# define ACCESS_PRIVATE(p, member) (*((typeof((p)->member) __force *) &(p)->member)) +#else /* __CHECKER__ */ +# ifdef STRUCTLEAK_PLUGIN +# define __user __attribute__((user)) +# else +# define __user +# endif +# define __kernel +# define __safe +# define __force +# define __nocast +# define __iomem +# define __chk_user_ptr(x) (void)0 +# define __chk_io_ptr(x) (void)0 +# define __builtin_warning(x, y...) (1) +# define __must_hold(x) +# define __acquires(x) +# define __releases(x) +# define __acquire(x) (void)0 +# define __release(x) (void)0 +# define __cond_lock(x,c) (c) +# define __percpu +# define __rcu +# define __private +# define ACCESS_PRIVATE(p, member) ((p)->member) +#endif /* __CHECKER__ */ + +/* Indirect macros required for expanded argument pasting, eg. __LINE__. */ +#define ___PASTE(a,b) a##b +#define __PASTE(a,b) ___PASTE(a,b) + +#ifdef __KERNEL__ + +/* Attributes */ +#include + +/* Compiler specific macros. */ +#ifdef __clang__ +#include +#elif defined(__INTEL_COMPILER) +#include +#elif defined(__GNUC__) +/* The above compilers also define __GNUC__, so order is important here. */ +#include +#else +#error "Unknown compiler" +#endif + +/* + * Some architectures need to provide custom definitions of macros provided + * by linux/compiler-*.h, and can do so using asm/compiler.h. We include that + * conditionally rather than using an asm-generic wrapper in order to avoid + * build failures if any C compilation, which will include this file via an + * -include argument in c_flags, occurs prior to the asm-generic wrappers being + * generated. + */ +#ifdef CONFIG_HAVE_ARCH_COMPILER_H +#include +#endif + +struct ftrace_branch_data { + const char *func; + const char *file; + unsigned line; + union { + struct { + unsigned long correct; + unsigned long incorrect; + }; + struct { + unsigned long miss; + unsigned long hit; + }; + unsigned long miss_hit[2]; + }; +}; + +struct ftrace_likely_data { + struct ftrace_branch_data data; + unsigned long constant; +}; + +#ifdef CONFIG_ENABLE_MUST_CHECK +#define __must_check __attribute__((__warn_unused_result__)) +#else +#define __must_check +#endif + +#if defined(CC_USING_HOTPATCH) +#define notrace __attribute__((hotpatch(0, 0))) +#elif defined(CC_USING_PATCHABLE_FUNCTION_ENTRY) +#define notrace __attribute__((patchable_function_entry(0, 0))) +#else +#define notrace __attribute__((__no_instrument_function__)) +#endif + +/* + * it doesn't make sense on ARM (currently the only user of __naked) + * to trace naked functions because then mcount is called without + * stack and frame pointer being set up and there is no chance to + * restore the lr register to the value before mcount was called. + */ +#define __naked __attribute__((__naked__)) notrace + +#define __compiler_offsetof(a, b) __builtin_offsetof(a, b) + +/* + * Force always-inline if the user requests it so via the .config. + * Prefer gnu_inline, so that extern inline functions do not emit an + * externally visible function. This makes extern inline behave as per gnu89 + * semantics rather than c99. This prevents multiple symbol definition errors + * of extern inline functions at link time. + * A lot of inline functions can cause havoc with function tracing. + * Do not use __always_inline here, since currently it expands to inline again + * (which would break users of __always_inline). + */ +#if !defined(CONFIG_OPTIMIZE_INLINING) +#define inline inline __attribute__((__always_inline__)) __gnu_inline \ + __inline_maybe_unused notrace +#else +#define inline inline __gnu_inline \ + __inline_maybe_unused notrace +#endif + +/* + * gcc provides both __inline__ and __inline as alternate spellings of + * the inline keyword, though the latter is undocumented. New kernel + * code should only use the inline spelling, but some existing code + * uses __inline__. Since we #define inline above, to ensure + * __inline__ has the same semantics, we need this #define. + * + * However, the spelling __inline is strictly reserved for referring + * to the bare keyword. + */ +#define __inline__ inline + +/* + * GCC does not warn about unused static inline functions for -Wunused-function. + * Suppress the warning in clang as well by using __maybe_unused, but enable it + * for W=1 build. This will allow clang to find unused functions. Remove the + * __inline_maybe_unused entirely after fixing most of -Wunused-function warnings. + */ +#ifdef KBUILD_EXTRA_WARN1 +#define __inline_maybe_unused +#else +#define __inline_maybe_unused __maybe_unused +#endif + +/* + * Rather then using noinline to prevent stack consumption, use + * noinline_for_stack instead. For documentation reasons. + */ +#define noinline_for_stack noinline + +#endif /* __KERNEL__ */ + +#endif /* __ASSEMBLY__ */ + +/* + * The below symbols may be defined for one or more, but not ALL, of the above + * compilers. We don't consider that to be an error, so set them to nothing. + * For example, some of them are for compiler specific plugins. + */ +#ifndef __latent_entropy +# define __latent_entropy +#endif + +#ifndef __randomize_layout +# define __randomize_layout __designated_init +#endif + +#ifndef __no_randomize_layout +# define __no_randomize_layout +#endif + +#ifndef randomized_struct_fields_start +# define randomized_struct_fields_start +# define randomized_struct_fields_end +#endif + +#ifndef asm_volatile_goto +#define asm_volatile_goto(x...) asm goto(x) +#endif + +#ifdef CONFIG_CC_HAS_ASM_INLINE +#define asm_inline asm __inline +#else +#define asm_inline asm +#endif + +#ifndef __no_fgcse +# define __no_fgcse +#endif + +/* Are two types/vars the same type (ignoring qualifiers)? */ +#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) + +/* Is this type a native word size -- useful for atomic operations */ +#define __native_word(t) \ + (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \ + sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) + +/* Helpers for emitting diagnostics in pragmas. */ +#ifndef __diag +#define __diag(string) +#endif + +#ifndef __diag_GCC +#define __diag_GCC(version, severity, string) +#endif + +#define __diag_push() __diag(push) +#define __diag_pop() __diag(pop) + +#define __diag_ignore(compiler, version, option, comment) \ + __diag_ ## compiler(version, ignore, option) +#define __diag_warn(compiler, version, option, comment) \ + __diag_ ## compiler(version, warn, option) +#define __diag_error(compiler, version, option, comment) \ + __diag_ ## compiler(version, error, option) + +#endif /* __LINUX_COMPILER_TYPES_H */ diff --git a/include/linux/if.h b/include/linux/if.h new file mode 100644 index 000000000000..a8ccf6d171e9 --- /dev/null +++ b/include/linux/if.h @@ -0,0 +1,296 @@ +/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Global definitions for the INET interface module. + * + * Version: @(#)if.h 1.0.2 04/18/93 + * + * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988 + * Ross Biro + * Fred N. van Kempen, + * + * 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. + */ +#ifndef _LINUX_IF_H +#define _LINUX_IF_H + +#include /* for compatibility with glibc */ +#include /* for "__kernel_caddr_t" et al */ +#include /* for "struct sockaddr" et al */ +#include /* for "__user" et al */ + +#ifndef __KERNEL__ +#include /* for struct sockaddr. */ +#endif + +#if __UAPI_DEF_IF_IFNAMSIZ +#define IFNAMSIZ 16 +#endif /* __UAPI_DEF_IF_IFNAMSIZ */ +#define IFALIASZ 256 +#define ALTIFNAMSIZ 128 +#include + +/* For glibc compatibility. An empty enum does not compile. */ +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || \ + __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 +/** + * enum net_device_flags - &struct net_device flags + * + * These are the &struct net_device flags, they can be set by drivers, the + * kernel and some can be triggered by userspace. Userspace can query and + * set these flags using userspace utilities but there is also a sysfs + * entry available for all dev flags which can be queried and set. These flags + * are shared for all types of net_devices. The sysfs entries are available + * via /sys/class/net//flags. Flags which can be toggled through sysfs + * are annotated below, note that only a few flags can be toggled and some + * other flags are always preserved from the original net_device flags + * even if you try to set them via sysfs. Flags which are always preserved + * are kept under the flag grouping @IFF_VOLATILE. Flags which are volatile + * are annotated below as such. + * + * You should have a pretty good reason to be extending these flags. + * + * @IFF_UP: interface is up. Can be toggled through sysfs. + * @IFF_BROADCAST: broadcast address valid. Volatile. + * @IFF_DEBUG: turn on debugging. Can be toggled through sysfs. + * @IFF_LOOPBACK: is a loopback net. Volatile. + * @IFF_POINTOPOINT: interface is has p-p link. Volatile. + * @IFF_NOTRAILERS: avoid use of trailers. Can be toggled through sysfs. + * Volatile. + * @IFF_RUNNING: interface RFC2863 OPER_UP. Volatile. + * @IFF_NOARP: no ARP protocol. Can be toggled through sysfs. Volatile. + * @IFF_PROMISC: receive all packets. Can be toggled through sysfs. + * @IFF_ALLMULTI: receive all multicast packets. Can be toggled through + * sysfs. + * @IFF_MASTER: master of a load balancer. Volatile. + * @IFF_SLAVE: slave of a load balancer. Volatile. + * @IFF_MULTICAST: Supports multicast. Can be toggled through sysfs. + * @IFF_PORTSEL: can set media type. Can be toggled through sysfs. + * @IFF_AUTOMEDIA: auto media select active. Can be toggled through sysfs. + * @IFF_DYNAMIC: dialup device with changing addresses. Can be toggled + * through sysfs. + * @IFF_LOWER_UP: driver signals L1 up. Volatile. + * @IFF_DORMANT: driver signals dormant. Volatile. + * @IFF_ECHO: echo sent packets. Volatile. + */ +enum net_device_flags { +/* for compatibility with glibc net/if.h */ +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS + IFF_UP = 1<<0, /* sysfs */ + IFF_BROADCAST = 1<<1, /* volatile */ + IFF_DEBUG = 1<<2, /* sysfs */ + IFF_LOOPBACK = 1<<3, /* volatile */ + IFF_POINTOPOINT = 1<<4, /* volatile */ + IFF_NOTRAILERS = 1<<5, /* sysfs */ + IFF_RUNNING = 1<<6, /* volatile */ + IFF_NOARP = 1<<7, /* sysfs */ + IFF_PROMISC = 1<<8, /* sysfs */ + IFF_ALLMULTI = 1<<9, /* sysfs */ + IFF_MASTER = 1<<10, /* volatile */ + IFF_SLAVE = 1<<11, /* volatile */ + IFF_MULTICAST = 1<<12, /* sysfs */ + IFF_PORTSEL = 1<<13, /* sysfs */ + IFF_AUTOMEDIA = 1<<14, /* sysfs */ + IFF_DYNAMIC = 1<<15, /* sysfs */ +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */ +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO + IFF_LOWER_UP = 1<<16, /* volatile */ + IFF_DORMANT = 1<<17, /* volatile */ + IFF_ECHO = 1<<18, /* volatile */ +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ +}; +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO != 0 || __UAPI_DEF_IF_NET_DEVICE_FLAGS != 0 */ + +/* for compatibility with glibc net/if.h */ +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS +#define IFF_UP IFF_UP +#define IFF_BROADCAST IFF_BROADCAST +#define IFF_DEBUG IFF_DEBUG +#define IFF_LOOPBACK IFF_LOOPBACK +#define IFF_POINTOPOINT IFF_POINTOPOINT +#define IFF_NOTRAILERS IFF_NOTRAILERS +#define IFF_RUNNING IFF_RUNNING +#define IFF_NOARP IFF_NOARP +#define IFF_PROMISC IFF_PROMISC +#define IFF_ALLMULTI IFF_ALLMULTI +#define IFF_MASTER IFF_MASTER +#define IFF_SLAVE IFF_SLAVE +#define IFF_MULTICAST IFF_MULTICAST +#define IFF_PORTSEL IFF_PORTSEL +#define IFF_AUTOMEDIA IFF_AUTOMEDIA +#define IFF_DYNAMIC IFF_DYNAMIC +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS */ + +#if __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO +#define IFF_LOWER_UP IFF_LOWER_UP +#define IFF_DORMANT IFF_DORMANT +#define IFF_ECHO IFF_ECHO +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ + +#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\ + IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT) + +#define IF_GET_IFACE 0x0001 /* for querying only */ +#define IF_GET_PROTO 0x0002 + +/* For definitions see hdlc.h */ +#define IF_IFACE_V35 0x1000 /* V.35 serial interface */ +#define IF_IFACE_V24 0x1001 /* V.24 serial interface */ +#define IF_IFACE_X21 0x1002 /* X.21 serial interface */ +#define IF_IFACE_T1 0x1003 /* T1 telco serial interface */ +#define IF_IFACE_E1 0x1004 /* E1 telco serial interface */ +#define IF_IFACE_SYNC_SERIAL 0x1005 /* can't be set by software */ +#define IF_IFACE_X21D 0x1006 /* X.21 Dual Clocking (FarSite) */ + +/* For definitions see hdlc.h */ +#define IF_PROTO_HDLC 0x2000 /* raw HDLC protocol */ +#define IF_PROTO_PPP 0x2001 /* PPP protocol */ +#define IF_PROTO_CISCO 0x2002 /* Cisco HDLC protocol */ +#define IF_PROTO_FR 0x2003 /* Frame Relay protocol */ +#define IF_PROTO_FR_ADD_PVC 0x2004 /* Create FR PVC */ +#define IF_PROTO_FR_DEL_PVC 0x2005 /* Delete FR PVC */ +#define IF_PROTO_X25 0x2006 /* X.25 */ +#define IF_PROTO_HDLC_ETH 0x2007 /* raw HDLC, Ethernet emulation */ +#define IF_PROTO_FR_ADD_ETH_PVC 0x2008 /* Create FR Ethernet-bridged PVC */ +#define IF_PROTO_FR_DEL_ETH_PVC 0x2009 /* Delete FR Ethernet-bridged PVC */ +#define IF_PROTO_FR_PVC 0x200A /* for reading PVC status */ +#define IF_PROTO_FR_ETH_PVC 0x200B +#define IF_PROTO_RAW 0x200C /* RAW Socket */ + +/* RFC 2863 operational status */ +enum { + IF_OPER_UNKNOWN, + IF_OPER_NOTPRESENT, + IF_OPER_DOWN, + IF_OPER_LOWERLAYERDOWN, + IF_OPER_TESTING, + IF_OPER_DORMANT, + IF_OPER_UP, +}; + +/* link modes */ +enum { + IF_LINK_MODE_DEFAULT, + IF_LINK_MODE_DORMANT, /* limit upward transition to dormant */ +}; + +/* + * Device mapping structure. I'd just gone off and designed a + * beautiful scheme using only loadable modules with arguments + * for driver options and along come the PCMCIA people 8) + * + * Ah well. The get() side of this is good for WDSETUP, and it'll + * be handy for debugging things. The set side is fine for now and + * being very small might be worth keeping for clean configuration. + */ + +/* for compatibility with glibc net/if.h */ +#if __UAPI_DEF_IF_IFMAP +struct ifmap { + unsigned long mem_start; + unsigned long mem_end; + unsigned short base_addr; + unsigned char irq; + unsigned char dma; + unsigned char port; + /* 3 bytes spare */ +}; +#endif /* __UAPI_DEF_IF_IFMAP */ + +struct if_settings { + unsigned int type; /* Type of physical device or protocol */ + unsigned int size; /* Size of the data allocated by the caller */ + union { + /* {atm/eth/dsl}_settings anyone ? */ + raw_hdlc_proto __user *raw_hdlc; + cisco_proto __user *cisco; + fr_proto __user *fr; + fr_proto_pvc __user *fr_pvc; + fr_proto_pvc_info __user *fr_pvc_info; + + /* interface settings */ + sync_serial_settings __user *sync; + te1_settings __user *te1; + } ifs_ifsu; +}; + +/* + * Interface request structure used for socket + * ioctl's. All interface ioctl's must have parameter + * definitions which begin with ifr_name. The + * remainder may be interface specific. + */ + +/* for compatibility with glibc net/if.h */ +#if __UAPI_DEF_IF_IFREQ +struct ifreq { +#define IFHWADDRLEN 6 + union + { + char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */ + } ifr_ifrn; + + union { + struct sockaddr ifru_addr; + struct sockaddr ifru_dstaddr; + struct sockaddr ifru_broadaddr; + struct sockaddr ifru_netmask; + struct sockaddr ifru_hwaddr; + short ifru_flags; + int ifru_ivalue; + int ifru_mtu; + struct ifmap ifru_map; + char ifru_slave[IFNAMSIZ]; /* Just fits the size */ + char ifru_newname[IFNAMSIZ]; + void __user * ifru_data; + struct if_settings ifru_settings; + } ifr_ifru; +}; +#endif /* __UAPI_DEF_IF_IFREQ */ + +#define ifr_name ifr_ifrn.ifrn_name /* interface name */ +#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ +#define ifr_addr ifr_ifru.ifru_addr /* address */ +#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */ +#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */ +#define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */ +#define ifr_flags ifr_ifru.ifru_flags /* flags */ +#define ifr_metric ifr_ifru.ifru_ivalue /* metric */ +#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */ +#define ifr_map ifr_ifru.ifru_map /* device map */ +#define ifr_slave ifr_ifru.ifru_slave /* slave device */ +#define ifr_data ifr_ifru.ifru_data /* for use by interface */ +#define ifr_ifindex ifr_ifru.ifru_ivalue /* interface index */ +#define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */ +#define ifr_qlen ifr_ifru.ifru_ivalue /* Queue length */ +#define ifr_newname ifr_ifru.ifru_newname /* New name */ +#define ifr_settings ifr_ifru.ifru_settings /* Device/proto settings*/ + +/* + * Structure used in SIOCGIFCONF request. + * Used to retrieve interface configuration + * for machine (useful for programs which + * must know all networks accessible). + */ + +/* for compatibility with glibc net/if.h */ +#if __UAPI_DEF_IF_IFCONF +struct ifconf { + int ifc_len; /* size of buffer */ + union { + char __user *ifcu_buf; + struct ifreq __user *ifcu_req; + } ifc_ifcu; +}; +#endif /* __UAPI_DEF_IF_IFCONF */ + +#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */ +#define ifc_req ifc_ifcu.ifcu_req /* array of structures */ + +#endif /* _LINUX_IF_H */ diff --git a/include/linux/libc-compat.h b/include/linux/libc-compat.h new file mode 100644 index 000000000000..8254c937c9f4 --- /dev/null +++ b/include/linux/libc-compat.h @@ -0,0 +1,267 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Compatibility interface for userspace libc header coordination: + * + * Define compatibility macros that are used to control the inclusion or + * exclusion of UAPI structures and definitions in coordination with another + * userspace C library. + * + * This header is intended to solve the problem of UAPI definitions that + * conflict with userspace definitions. If a UAPI header has such conflicting + * definitions then the solution is as follows: + * + * * Synchronize the UAPI header and the libc headers so either one can be + * used and such that the ABI is preserved. If this is not possible then + * no simple compatibility interface exists (you need to write translating + * wrappers and rename things) and you can't use this interface. + * + * Then follow this process: + * + * (a) Include libc-compat.h in the UAPI header. + * e.g. #include + * This include must be as early as possible. + * + * (b) In libc-compat.h add enough code to detect that the comflicting + * userspace libc header has been included first. + * + * (c) If the userspace libc header has been included first define a set of + * guard macros of the form __UAPI_DEF_FOO and set their values to 1, else + * set their values to 0. + * + * (d) Back in the UAPI header with the conflicting definitions, guard the + * definitions with: + * #if __UAPI_DEF_FOO + * ... + * #endif + * + * This fixes the situation where the linux headers are included *after* the + * libc headers. To fix the problem with the inclusion in the other order the + * userspace libc headers must be fixed like this: + * + * * For all definitions that conflict with kernel definitions wrap those + * defines in the following: + * #if !__UAPI_DEF_FOO + * ... + * #endif + * + * This prevents the redefinition of a construct already defined by the kernel. + */ +#ifndef _UAPI_LIBC_COMPAT_H +#define _UAPI_LIBC_COMPAT_H + +/* We have included glibc headers... */ +#if defined(__GLIBC__) + +/* Coordinate with glibc net/if.h header. */ +#if defined(_NET_IF_H) && defined(__USE_MISC) + +/* GLIBC headers included first so don't define anything + * that would already be defined. */ + +#define __UAPI_DEF_IF_IFCONF 0 +#define __UAPI_DEF_IF_IFMAP 0 +#define __UAPI_DEF_IF_IFNAMSIZ 0 +#define __UAPI_DEF_IF_IFREQ 0 +/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0 +/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ +#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 +#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ + +#else /* _NET_IF_H */ + +/* Linux headers included first, and we must define everything + * we need. The expectation is that glibc will check the + * __UAPI_DEF_* defines and adjust appropriately. */ + +#define __UAPI_DEF_IF_IFCONF 1 +#define __UAPI_DEF_IF_IFMAP 1 +#define __UAPI_DEF_IF_IFNAMSIZ 1 +#define __UAPI_DEF_IF_IFREQ 1 +/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 +/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 + +#endif /* _NET_IF_H */ + +/* Coordinate with glibc netinet/in.h header. */ +#if defined(_NETINET_IN_H) + +/* GLIBC headers included first so don't define anything + * that would already be defined. */ +#define __UAPI_DEF_IN_ADDR 0 +#define __UAPI_DEF_IN_IPPROTO 0 +#define __UAPI_DEF_IN_PKTINFO 0 +#define __UAPI_DEF_IP_MREQ 0 +#define __UAPI_DEF_SOCKADDR_IN 0 +#define __UAPI_DEF_IN_CLASS 0 + +#define __UAPI_DEF_IN6_ADDR 0 +/* The exception is the in6_addr macros which must be defined + * if the glibc code didn't define them. This guard matches + * the guard in glibc/inet/netinet/in.h which defines the + * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */ +#if defined(__USE_MISC) || defined (__USE_GNU) +#define __UAPI_DEF_IN6_ADDR_ALT 0 +#else +#define __UAPI_DEF_IN6_ADDR_ALT 1 +#endif +#define __UAPI_DEF_SOCKADDR_IN6 0 +#define __UAPI_DEF_IPV6_MREQ 0 +#define __UAPI_DEF_IPPROTO_V6 0 +#define __UAPI_DEF_IPV6_OPTIONS 0 +#define __UAPI_DEF_IN6_PKTINFO 0 +#define __UAPI_DEF_IP6_MTUINFO 0 + +#else + +/* Linux headers included first, and we must define everything + * we need. The expectation is that glibc will check the + * __UAPI_DEF_* defines and adjust appropriately. */ +#define __UAPI_DEF_IN_ADDR 1 +#define __UAPI_DEF_IN_IPPROTO 1 +#define __UAPI_DEF_IN_PKTINFO 1 +#define __UAPI_DEF_IP_MREQ 1 +#define __UAPI_DEF_SOCKADDR_IN 1 +#define __UAPI_DEF_IN_CLASS 1 + +#define __UAPI_DEF_IN6_ADDR 1 +/* We unconditionally define the in6_addr macros and glibc must + * coordinate. */ +#define __UAPI_DEF_IN6_ADDR_ALT 1 +#define __UAPI_DEF_SOCKADDR_IN6 1 +#define __UAPI_DEF_IPV6_MREQ 1 +#define __UAPI_DEF_IPPROTO_V6 1 +#define __UAPI_DEF_IPV6_OPTIONS 1 +#define __UAPI_DEF_IN6_PKTINFO 1 +#define __UAPI_DEF_IP6_MTUINFO 1 + +#endif /* _NETINET_IN_H */ + +/* Coordinate with glibc netipx/ipx.h header. */ +#if defined(__NETIPX_IPX_H) + +#define __UAPI_DEF_SOCKADDR_IPX 0 +#define __UAPI_DEF_IPX_ROUTE_DEFINITION 0 +#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0 +#define __UAPI_DEF_IPX_CONFIG_DATA 0 +#define __UAPI_DEF_IPX_ROUTE_DEF 0 + +#else /* defined(__NETIPX_IPX_H) */ + +#define __UAPI_DEF_SOCKADDR_IPX 1 +#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 +#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 +#define __UAPI_DEF_IPX_CONFIG_DATA 1 +#define __UAPI_DEF_IPX_ROUTE_DEF 1 + +#endif /* defined(__NETIPX_IPX_H) */ + +/* Definitions for xattr.h */ +#if defined(_SYS_XATTR_H) +#define __UAPI_DEF_XATTR 0 +#else +#define __UAPI_DEF_XATTR 1 +#endif + +/* If we did not see any headers from any supported C libraries, + * or we are being included in the kernel, then define everything + * that we need. Check for previous __UAPI_* definitions to give + * unsupported C libraries a way to opt out of any kernel definition. */ +#else /* !defined(__GLIBC__) */ + +/* Definitions for if.h */ +#ifndef __UAPI_DEF_IF_IFCONF +#define __UAPI_DEF_IF_IFCONF 1 +#endif +#ifndef __UAPI_DEF_IF_IFMAP +#define __UAPI_DEF_IF_IFMAP 1 +#endif +#ifndef __UAPI_DEF_IF_IFNAMSIZ +#define __UAPI_DEF_IF_IFNAMSIZ 1 +#endif +#ifndef __UAPI_DEF_IF_IFREQ +#define __UAPI_DEF_IF_IFREQ 1 +#endif +/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ +#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 +#endif +/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ +#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO +#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 +#endif + +/* Definitions for in.h */ +#ifndef __UAPI_DEF_IN_ADDR +#define __UAPI_DEF_IN_ADDR 1 +#endif +#ifndef __UAPI_DEF_IN_IPPROTO +#define __UAPI_DEF_IN_IPPROTO 1 +#endif +#ifndef __UAPI_DEF_IN_PKTINFO +#define __UAPI_DEF_IN_PKTINFO 1 +#endif +#ifndef __UAPI_DEF_IP_MREQ +#define __UAPI_DEF_IP_MREQ 1 +#endif +#ifndef __UAPI_DEF_SOCKADDR_IN +#define __UAPI_DEF_SOCKADDR_IN 1 +#endif +#ifndef __UAPI_DEF_IN_CLASS +#define __UAPI_DEF_IN_CLASS 1 +#endif + +/* Definitions for in6.h */ +#ifndef __UAPI_DEF_IN6_ADDR +#define __UAPI_DEF_IN6_ADDR 1 +#endif +#ifndef __UAPI_DEF_IN6_ADDR_ALT +#define __UAPI_DEF_IN6_ADDR_ALT 1 +#endif +#ifndef __UAPI_DEF_SOCKADDR_IN6 +#define __UAPI_DEF_SOCKADDR_IN6 1 +#endif +#ifndef __UAPI_DEF_IPV6_MREQ +#define __UAPI_DEF_IPV6_MREQ 1 +#endif +#ifndef __UAPI_DEF_IPPROTO_V6 +#define __UAPI_DEF_IPPROTO_V6 1 +#endif +#ifndef __UAPI_DEF_IPV6_OPTIONS +#define __UAPI_DEF_IPV6_OPTIONS 1 +#endif +#ifndef __UAPI_DEF_IN6_PKTINFO +#define __UAPI_DEF_IN6_PKTINFO 1 +#endif +#ifndef __UAPI_DEF_IP6_MTUINFO +#define __UAPI_DEF_IP6_MTUINFO 1 +#endif + +/* Definitions for ipx.h */ +#ifndef __UAPI_DEF_SOCKADDR_IPX +#define __UAPI_DEF_SOCKADDR_IPX 1 +#endif +#ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION +#define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 +#endif +#ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION +#define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 +#endif +#ifndef __UAPI_DEF_IPX_CONFIG_DATA +#define __UAPI_DEF_IPX_CONFIG_DATA 1 +#endif +#ifndef __UAPI_DEF_IPX_ROUTE_DEF +#define __UAPI_DEF_IPX_ROUTE_DEF 1 +#endif + +/* Definitions for xattr.h */ +#ifndef __UAPI_DEF_XATTR +#define __UAPI_DEF_XATTR 1 +#endif + +#endif /* __GLIBC__ */ + +#endif /* _UAPI_LIBC_COMPAT_H */ diff --git a/include/subdir.am b/include/subdir.am index 6f07b6bf103d..bcf3ef7b9bf8 100644 --- a/include/subdir.am +++ b/include/subdir.am @@ -1,4 +1,7 @@ noinst_HEADERS += \ + include/linux/compiler_types.h \ + include/linux/libc-compat.h \ + include/linux/if.h \ include/linux/if_addr.h \ include/linux/if_bridge.h \ include/linux/if_link.h \ diff --git a/lib/if.c b/lib/if.c index a8ceac72432b..612b28464fc1 100644 --- a/lib/if.c +++ b/lib/if.c @@ -6,6 +6,12 @@ #include +#include + +#ifdef GNU_LINUX +#include +#endif /* GNU_LINUX */ + #include "linklist.h" #include "vector.h" #include "lib_errors.h" From c85ce39fe039b9f46c1b0304cf1b1c7e1d077084 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 10 Jan 2024 16:47:03 +0100 Subject: [PATCH 026/472] lib: take into account the iff_lower_up flag In Linux, a network driver can set the interface flags IFF_UP and IFF_RUNNING although the IFF_LOWER_UP flag is down, which means the interface is ready but the carrier is down: > These values contain interface state: > > ifinfomsg::if_flags & IFF_UP: > Interface is admin up > ifinfomsg::if_flags & IFF_RUNNING: > Interface is in RFC2863 operational state UP or UNKNOWN. This is for > backward compatibility, routing daemons, dhcp clients can use this > flag to determine whether they should use the interface. > ifinfomsg::if_flags & IFF_LOWER_UP: > Driver has signaled netif_carrier_on() However, FRR considers an interface is operational as soon it is up (IFF_UP) and running (IFF_RUNNING), disregarding the IFF_LOWER_UP flag. This can lead to a scenario where FRR starts adding routes through an interface that is technically down at the carrier level, resulting in kernel errors. > Jan 02 18:07:18 dut-vm zebra[283731]: [WVJCK-PPMGD][EC 4043309093] netlink-dp (NS 0) error: Network is down, type=RTM_NEWNEXTHOP(104), seq=243, pid=3112881162 > Jan 02 18:07:18 dut-vm zebra[283731]: [X5XE1-RS0SW][EC 4043309074] Failed to install Nexthop (318[if 164]) into the kernel > Jan 02 18:07:18 dut-vm zebra[283731]: [HSYZM-HV7HF] Extended Error: Carrier for nexthop device is down > Jan 02 18:07:18 dut-vm zebra[283731]: [WVJCK-PPMGD][EC 4043309093] netlink-dp (NS 0) error: Network is down, type=RTM_NEWNEXTHOP(104), seq=245, pid=3112881162 > Jan 02 18:07:18 dut-vm zebra[283731]: [HSYZM-HV7HF] Extended Error: Nexthop id does not exist > Jan 02 18:07:18 dut-vm zebra[283731]: [WVJCK-PPMGD][EC 4043309093] netlink-dp (NS 0) error: Invalid argument, type=RTM_NEWROUTE(24), seq=246, pid=3112881162 > Jan 02 18:07:18 dut-vm zebra[283731]: [X5XE1-RS0SW][EC 4043309074] Failed to install Nexthop (320[10.125.0.2 if 164]) into the kernel > Jan 02 18:07:18 dut-vm zebra[283731]: [VYKYC-709DP] default(0:254):0.0.0.0/0: Route install failed Consider an interface is operational when it has the IFF_UP, IFF_RUNNING and IFF_LOWER_UP flags. Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/networking/operstates.rst?h=v6.7-rc8#n29 Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/ipv4/nexthop.c?h=v6.7-rc8#n2886 Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/netdevice.h?h=v6.7-rc8#n4198 Signed-off-by: Louis Scalbert --- lib/if.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/if.c b/lib/if.c index 612b28464fc1..17e0b3ff8f83 100644 --- a/lib/if.c +++ b/lib/if.c @@ -674,21 +674,26 @@ int if_is_running(const struct interface *ifp) if ptm checking is enabled, then ptm check has passed */ int if_is_operative(const struct interface *ifp) { - return ((ifp->flags & IFF_UP) - && (((ifp->flags & IFF_RUNNING) - && (ifp->ptm_status || !ifp->ptm_enable)) - || !CHECK_FLAG(ifp->status, - ZEBRA_INTERFACE_LINKDETECTION))); + return ((ifp->flags & IFF_UP) && + (((ifp->flags & IFF_RUNNING) +#ifdef IFF_LOWER_UP + && (ifp->flags & IFF_LOWER_UP) +#endif /* IFF_LOWER_UP */ + && (ifp->ptm_status || !ifp->ptm_enable)) || + !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))); } /* Is the interface operative, eg. either UP & RUNNING or UP & !ZEBRA_INTERFACE_LINK_DETECTION, without PTM check */ int if_is_no_ptm_operative(const struct interface *ifp) { - return ((ifp->flags & IFF_UP) - && ((ifp->flags & IFF_RUNNING) - || !CHECK_FLAG(ifp->status, - ZEBRA_INTERFACE_LINKDETECTION))); + return ((ifp->flags & IFF_UP) && + (((ifp->flags & IFF_RUNNING) +#ifdef IFF_LOWER_UP + && (ifp->flags & IFF_LOWER_UP) +#endif /* IFF_LOWER_UP */ + ) || + !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))); } /* Is this loopback interface ? */ @@ -750,6 +755,9 @@ const char *if_flag_dump(unsigned long flag) strlcpy(logbuf, "<", BUFSIZ); IFF_OUT_LOG(IFF_UP, "UP"); +#ifdef IFF_LOWER_UP + IFF_OUT_LOG(IFF_LOWER_UP, "LOWER_UP"); +#endif /* IFF_LOWER_UP */ IFF_OUT_LOG(IFF_BROADCAST, "BROADCAST"); IFF_OUT_LOG(IFF_DEBUG, "DEBUG"); IFF_OUT_LOG(IFF_LOOPBACK, "LOOPBACK"); From efbf2345107202e8315507f4c8da8c39305174db Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 11 Jan 2024 11:19:21 +0100 Subject: [PATCH 027/472] topotests: add lower_up to expected interface flags Add lower_up to expected interface flags. Signed-off-by: Louis Scalbert --- .../all_protocol_startup/r1/show_ip_ospf_interface.ref | 4 ++-- tests/topotests/nhrp_topo/test_nhrp_topo.py | 2 +- .../ospf_basic_functionality/test_ospf_single_area.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref b/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref index 7e28f04e1c91..f52b51d9d8b6 100644 --- a/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref +++ b/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref @@ -1,5 +1,5 @@ r1-eth0 is up - ifindex X, MTU 1500 bytes, BW XX Mbit + ifindex X, MTU 1500 bytes, BW XX Mbit Internet Address 192.168.0.1/24, Broadcast 192.168.0.255, Area 0.0.0.0 MTU mismatch detection: enabled Router ID 192.168.0.1, Network Type BROADCAST, Cost: 10 @@ -12,7 +12,7 @@ r1-eth0 is up Neighbor Count is 0, Adjacent neighbor count is 0 Graceful Restart hello delay: 10s r1-eth3 is up - ifindex X, MTU 1500 bytes, BW XX Mbit + ifindex X, MTU 1500 bytes, BW XX Mbit Internet Address 192.168.3.1/26, Broadcast 192.168.3.63, Area 0.0.0.0 MTU mismatch detection: enabled Router ID 192.168.0.1, Network Type BROADCAST, Cost: 10 diff --git a/tests/topotests/nhrp_topo/test_nhrp_topo.py b/tests/topotests/nhrp_topo/test_nhrp_topo.py index 26115de2b866..284c58a8e781 100644 --- a/tests/topotests/nhrp_topo/test_nhrp_topo.py +++ b/tests/topotests/nhrp_topo/test_nhrp_topo.py @@ -189,7 +189,7 @@ def test_protocols_convergence(): expected = { "{}-gre0".format(rname): { - "flags": "", + "flags": "", } } test_func = partial( diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py index 757d6fb1d581..85f08e1a3989 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py @@ -607,7 +607,7 @@ def test_ospf_show_p1(request): "r0": { "ospf": { "ifUp": True, - "ifFlags": "", + "ifFlags": "", "ospfEnabled": True, "ipAddressPrefixlen": 24, "ospfIfType": "Broadcast", From bb46027596524707480a423bd6ef63bad0a8ce0e Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 23 Apr 2024 14:05:16 +0200 Subject: [PATCH 028/472] zebra: fix fpm_listener compilation I don't know why it appears only now. > ../sdist/zebra/fpm_listener.c:420:8: error: comparison of integers of different signs: 'int' and 'size_t' (aka 'unsigned long') [-Werror,-Wsign-compare] > if (!RTNH_OK(rtnh, len)) { > ^~~~~~~~~~~~~~~~~~ > ../sdist/include/linux/rtnetlink.h:437:31: note: expanded from macro 'RTNH_OK' > ((int)(rtnh)->rtnh_len) <= (len)) len is set with RTA_PAYLOAD and should be an integer. > len = RTA_PAYLOAD(mpath_rtattr); > #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0)) Signed-off-by: Louis Scalbert --- zebra/fpm_listener.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c index 5ffc0561bb1a..65067d2ddacc 100644 --- a/zebra/fpm_listener.c +++ b/zebra/fpm_listener.c @@ -405,7 +405,7 @@ static int netlink_msg_ctx_add_nh(struct netlink_msg_ctx *ctx, int if_index, static int parse_multipath_attr(struct netlink_msg_ctx *ctx, struct rtattr *mpath_rtattr) { - size_t len; + int len; struct rtnexthop *rtnh; struct rtattr *rtattrs[RTA_MAX + 1]; struct rtattr *gateway; From 1badd1941b5392462f47975608a46c77454e1869 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 29 Apr 2024 17:28:55 +0200 Subject: [PATCH 029/472] python: add tool to expand typesafe definitions This can be used to get less cryptic error/warnings from GCC when dealing with something typesafe container related. Signed-off-by: David Lamparter --- .gitignore | 1 + lib/atomlist.h | 2 + lib/typerb.h | 2 + lib/typesafe.h | 2 + python/tsexpand.py | 131 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+) create mode 100644 python/tsexpand.py diff --git a/.gitignore b/.gitignore index 07cdb11a21c8..60b41899520e 100644 --- a/.gitignore +++ b/.gitignore @@ -62,6 +62,7 @@ *.cg.dot *.cg.svg *.xref +*_tsexpand.h ### gcov outputs diff --git a/lib/atomlist.h b/lib/atomlist.h index 2b6a3a176f94..faf1d7324e58 100644 --- a/lib/atomlist.h +++ b/lib/atomlist.h @@ -6,8 +6,10 @@ #ifndef _FRR_ATOMLIST_H #define _FRR_ATOMLIST_H +#ifndef _TYPESAFE_EXPAND_MACROS #include "typesafe.h" #include "frratomic.h" +#endif /* _TYPESAFE_EXPAND_MACROS */ #ifdef __cplusplus extern "C" { diff --git a/lib/typerb.h b/lib/typerb.h index b020a665f624..93370e1012c8 100644 --- a/lib/typerb.h +++ b/lib/typerb.h @@ -9,8 +9,10 @@ #ifndef _FRR_TYPERB_H #define _FRR_TYPERB_H +#ifndef _TYPESAFE_EXPAND_MACROS #include #include "typesafe.h" +#endif /* _TYPESAFE_EXPAND_MACROS */ #ifdef __cplusplus extern "C" { diff --git a/lib/typesafe.h b/lib/typesafe.h index 93258c595410..fc028049a458 100644 --- a/lib/typesafe.h +++ b/lib/typesafe.h @@ -6,10 +6,12 @@ #ifndef _FRR_TYPESAFE_H #define _FRR_TYPESAFE_H +#ifndef _TYPESAFE_EXPAND_MACROS #include #include #include #include "compiler.h" +#endif /* _TYPESAFE_EXPAND_MACROS */ #ifdef __cplusplus extern "C" { diff --git a/python/tsexpand.py b/python/tsexpand.py new file mode 100644 index 000000000000..5d6099750fb9 --- /dev/null +++ b/python/tsexpand.py @@ -0,0 +1,131 @@ +#!/usr/bin/python3 +# SPDX-License-Identifier: MIT +# +# 2024 by David Lamparter +# +# this tool edits an FRR source .c file to expand the typesafe DECLARE_DLIST +# et al. definitions. This can be helpful to get better warnings/errors from +# GCC when something re. a typesafe container is involved. You can also use +# it on .h files. +# The actual expansions created by this tool are written to separate files +# called something like "lib/cspf__visited_tsexpand.h" (for a container named +# "visited") +# +# THIS TOOL EDITS THE FILE IN PLACE. MAKE A BACKUP IF YOU HAVE UNSAVED WORK +# IN PROGRESS (which is likely because you're debugging a typesafe container +# problem!) +# +# The PREDECL_XYZ is irrelevant for this tool, it needs to be run on the file +# that has the DECLARE_XYZ (can be .c or .h) +# +# the lines added by this tool all have /* $ts_expand: remove$ */ at the end +# you can undo the effects of this tool by calling sed: +# +# sed -e '/\$ts_expand: remove\$/ d' -i.orig filename.c + +import os +import sys +import re +import subprocess +import shlex + +decl_re = re.compile( + r"""(?<=\n)[ \t]*DECLARE_(LIST|ATOMLIST|DLIST|HEAP|HASH|(SORTLIST|SKIPLIST|RBTREE|ATOMSORT)_(NON)?UNIQ)\(\s*(?P[^, \t\n]+)\s*,[^)]+\)\s*;[ \t]*\n""" +) +kill_re = re.compile(r"""(?<=\n)[^\n]*/\* \$ts_expand: remove\$ \*/\n""") + +src_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + +# some files may be compiled with different CPPFLAGS, that's not supported +# here... +cpp = subprocess.check_output( + ["make", "var-CPP", "var-AM_CPPFLAGS", "var-DEFS"], cwd=src_root +) +cpp = shlex.split(cpp.decode("UTF-8")) + + +def process_file(filename): + with open(filename, "r") as ifd: + data = ifd.read() + + data = kill_re.sub("", data) + + before = 0 + + dirname = os.path.dirname(filename) + basename = os.path.basename(filename).removesuffix(".c").removesuffix(".h") + + xname = filename + ".exp" + with open(filename + ".exp", "w") as ofd: + for m in decl_re.finditer(data): + s = m.start() + e = m.end() + ofd.write(data[before:s]) + + # start gcc/clang with some "magic" options to make it expand the + # typesafe macros, but nothing else. + # -P removes the "#line" markers (which are useless because + # everything ends up on one line anyway) + # -D_TYPESAFE_EXPAND_MACROS prevents the system header files + # (stddef.h, stdint.h, etc.) from being included and expanded + # -imacros loads the macro definitions from typesafe.h, but + # doesn't include any of the "plain text" (i.e. prototypes + # and outside-macro struct definitions) from it + # atomlist.h is sufficient because it includes typesafe.h which + # includes typerb.h, that's all of them + p_expand = subprocess.Popen( + cpp + + [ + "-P", + "-D_TYPESAFE_EXPAND_MACROS", + "-imacros", + "lib/atomlist.h", + "-", + ], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + cwd=src_root, + ) + # the output will look like shit, all on one line. format it. + p_format = subprocess.Popen( + ["clang-format", "-"], + stdin=p_expand.stdout, + stdout=subprocess.PIPE, + cwd=src_root, + ) + # pipe between cpp & clang-format needs to be closed + p_expand.stdout.close() + + # ... and finally, write the DECLARE_XYZ statement, and ONLY that + # statements. No headers, no other definitions. + p_expand.stdin.write(data[s:e].encode("UTF-8")) + p_expand.stdin.close() + + odata = b"" + while rd := p_format.stdout.read(): + odata = odata + rd + + p_expand.wait() + p_format.wait() + + # and now that we have the expanded text, write it out, put an + # #include in the .c file, and put "#if 0" around the original + # DECLARE_XYZ statement (otherwise it'll be duplicate...) + newname = os.path.join(dirname, f"{basename}__{m.group('name')}_tsexpand.h") + with open(newname, "wb") as nfd: + nfd.write(odata) + + ofd.write(f'#include "{newname}" /* $ts_expand: remove$ */\n') + ofd.write("#if 0 /* $ts_expand: remove$ */\n") + ofd.write(data[s:e]) + ofd.write("#endif /* $ts_expand: remove$ */\n") + before = e + + ofd.write(data[before:]) + + os.rename(xname, filename) + + +if __name__ == "__main__": + for filename in sys.argv[1:]: + process_file(filename) From 7b5595b61dfbd27ba05b8f5416882514a1e2f94f Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 30 Apr 2024 13:38:54 +0300 Subject: [PATCH 030/472] bgpd: Print old/new states of graceful restart FSM To better debug what's going on before/after. Signed-off-by: Donatas Abraitis --- bgpd/bgp_fsm.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 7866adbdcdb8..ef1e0646cc27 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -2915,19 +2915,22 @@ int bgp_neighbor_graceful_restart(struct peer *peer, peer_old_state = bgp_peer_gr_mode_get(peer); - if (peer_old_state == PEER_INVALID) { - zlog_debug("[BGP_GR] peer_old_state == Invalid state !"); + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) + zlog_debug("%s [BGP_GR] peer_old_state: %d", __func__, + peer_old_state); + + if (peer_old_state == PEER_INVALID) return BGP_ERR_GR_OPERATION_FAILED; - } peer_state = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd]; peer_new_state = peer_state.next_state; - if (peer_new_state == PEER_INVALID) { - zlog_debug( - "[BGP_GR] Invalid bgp graceful restart command used !"); + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) + zlog_debug("%s [BGP_GR] peer_new_state: %d", __func__, + peer_new_state); + + if (peer_new_state == PEER_INVALID) return BGP_ERR_GR_INVALID_CMD; - } if (peer_new_state != peer_old_state) { result = peer_state.action_fun(peer, peer_old_state, From 9ebdb8e80d83a9087deaffee93df4bc90ab6e7ee Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 30 Apr 2024 13:40:08 +0300 Subject: [PATCH 031/472] bgpd: Apply NOOP when doing negative commands for GR operations E.g.: ``` % The Graceful Restart command used is not valid at this moment. zsh: exit 1 vtysh -c configure -c 'router bgp' -c 'no neighbor 127.0.0.1 graceful-restart 1 ``` This does not make sense frr-reload to fail. Instead, just ignore such requests if they are just NOOP. Signed-off-by: Donatas Abraitis --- bgpd/bgpd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index a7564da8b39a..f4f9b258c510 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1446,11 +1446,11 @@ int bgp_peer_gr_init(struct peer *peer) { /* PEER_GLOBAL_INHERIT Mode */ /* Event-> */ /* PEER_GR_CMD */ /* NO_PEER_GR_CMD */ - { PEER_GR, bgp_peer_gr_action }, { PEER_INVALID, NULL }, + { PEER_GR, bgp_peer_gr_action }, { PEER_GLOBAL_INHERIT, NULL }, /* Event-> */ /* PEER_DISABLE_CMD */ /* NO_PEER_DISABLE_CMD */ - { PEER_DISABLE, bgp_peer_gr_action}, { PEER_INVALID, NULL }, + { PEER_DISABLE, bgp_peer_gr_action }, { PEER_GLOBAL_INHERIT, NULL }, /* Event-> */ /* PEER_HELPER_cmd */ /* NO_PEER_HELPER_CMD */ - { PEER_HELPER, bgp_peer_gr_action }, { PEER_INVALID, NULL } + { PEER_HELPER, bgp_peer_gr_action }, { PEER_GLOBAL_INHERIT, NULL } } }; memcpy(&peer->PEER_GR_FSM, local_Peer_GR_FSM, From d733fe2c048cd75948d9f30ced77ed828e92ee18 Mon Sep 17 00:00:00 2001 From: Bing Shui <652023330037@smail.nju.edu.cn> Date: Thu, 25 Apr 2024 16:02:26 +0000 Subject: [PATCH 032/472] ospfd:fix the bug where ip_ospf_dead-interval_minimal_hello-multiplier did not reset hello timer Signed-off-by: Bing Shui <652023330037@smail.nju.edu.cn> --- ospfd/ospf_vty.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index e2f4f64d816b..0f5efa320868 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -8208,6 +8208,8 @@ static int ospf_vty_dead_interval_set(struct vty *vty, const char *interval_str, ospf_nbr_timer_update(oi); } + if (params->fast_hello != OSPF_FAST_HELLO_DEFAULT) + ospf_reset_hello_timer(ifp, addr, false); return CMD_SUCCESS; } From 342400e7c6630c12287fb35e475ea98da4b85eb1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 30 Apr 2024 11:52:37 +0200 Subject: [PATCH 033/472] build: link libatomic if available It'll generally exist but be empty on systems that don't need it. (Some 32bit platforms now need it due to 64bit time_t, and the platform may not have 64bit atomic ops.) Signed-off-by: David Lamparter --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index f11b345cf6ef..795417cd291d 100644 --- a/configure.ac +++ b/configure.ac @@ -1095,6 +1095,8 @@ dnl ------------------------- AC_CHECK_HEADERS([stropts.h sys/ksym.h \ linux/version.h asm/types.h endian.h sys/endian.h]) +AC_CHECK_LIB([atomic], [main], [LIBS="$LIBS -latomic"], [], []) + ac_stdatomic_ok=false AC_DEFINE([FRR_AUTOCONF_ATOMIC], [1], [did autoconf checks for atomic funcs]) AC_CHECK_HEADER([stdatomic.h],[ From 714e5be9a0804c0da2c9429bead274bbaefc9939 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 1 May 2024 16:01:38 +0300 Subject: [PATCH 034/472] bgpd: Ignore validating the attribute flags if path-attribute is configured E.g. Cisco sends AIGP attribute as transitive, but it's wrong. Hence, the session is teared down, because of this bgp_attr_flag_invalid() test. Relax this check if we have `neighbor X path-attribute ` configured. Signed-off-by: Donatas Abraitis --- bgpd/bgp_attr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 913634bf5914..71f02a7f83a2 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -1526,6 +1526,7 @@ static bool bgp_attr_flag_invalid(struct bgp_attr_parser_args *args) uint8_t mask = BGP_ATTR_FLAG_EXTLEN; const uint8_t flags = args->flags; const uint8_t attr_code = args->type; + struct peer *peer = args->peer; /* there may be attributes we don't know about */ if (attr_code > attr_flags_values_max) @@ -1533,6 +1534,14 @@ static bool bgp_attr_flag_invalid(struct bgp_attr_parser_args *args) if (attr_flags_values[attr_code] == 0) return false; + /* If `neighbor X path-attribute ` is + * configured, then ignore checking optional, trasitive flags. + * The attribute/route will be discarded/withdrawned later instead + * of dropping the session. + */ + if (peer->discard_attrs[attr_code] || peer->withdraw_attrs[attr_code]) + return false; + /* RFC4271, "For well-known attributes, the Transitive bit MUST be set * to * 1." From f58227c91e4aaf3b54929634b310de86c0202a6e Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 1 May 2024 16:33:52 +0300 Subject: [PATCH 035/472] tests: Check if iBGP session can drop invalid AIGP attribute Signed-off-by: Donatas Abraitis --- .../peer1/exabgp.cfg | 29 +++++++++++---- .../bgp_path_attribute_discard/r1/bgpd.conf | 6 --- .../bgp_path_attribute_discard/r1/frr.conf | 9 +++++ .../bgp_path_attribute_discard/r1/zebra.conf | 4 -- .../bgp_path_attribute_discard/r2/frr.conf | 10 +++++ .../test_bgp_path_attribute_discard.py | 37 ++++++++++++++++--- 6 files changed, 72 insertions(+), 23 deletions(-) delete mode 100644 tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf create mode 100644 tests/topotests/bgp_path_attribute_discard/r1/frr.conf delete mode 100644 tests/topotests/bgp_path_attribute_discard/r1/zebra.conf create mode 100644 tests/topotests/bgp_path_attribute_discard/r2/frr.conf diff --git a/tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg b/tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg index 7fb9210ecf6e..dccec7d15428 100644 --- a/tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg +++ b/tests/topotests/bgp_path_attribute_discard/peer1/exabgp.cfg @@ -1,8 +1,8 @@ neighbor 10.0.0.1 { - router-id 10.0.0.2; - local-address 10.0.0.2; - local-as 65001; - peer-as 65002; + router-id 10.0.0.254; + local-address 10.0.0.254; + local-as 65254; + peer-as 65001; capability { route-refresh; @@ -12,13 +12,28 @@ neighbor 10.0.0.1 { route 192.168.100.101/32 { atomic-aggregate; community 65001:101; - next-hop 10.0.0.2; + next-hop 10.0.0.254; } route 192.168.100.102/32 { - originator-id 10.0.0.2; + originator-id 10.0.0.254; community 65001:102; - next-hop 10.0.0.2; + next-hop 10.0.0.254; + } + } +} + +neighbor 10.0.0.2 { + router-id 10.0.0.254; + local-address 10.0.0.254; + local-as 65254; + peer-as 65254; + + static { + route 192.168.100.101/32 { + # AIGP invalid attribute: flagged as transitive + optional. + attribute [0x1a 0xc0 0x00000064]; + next-hop 10.0.0.254; } } } diff --git a/tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf b/tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf deleted file mode 100644 index c96f354cc597..000000000000 --- a/tests/topotests/bgp_path_attribute_discard/r1/bgpd.conf +++ /dev/null @@ -1,6 +0,0 @@ -! -router bgp 65002 - no bgp ebgp-requires-policy - neighbor 10.0.0.2 remote-as external - neighbor 10.0.0.2 timers 3 10 -! diff --git a/tests/topotests/bgp_path_attribute_discard/r1/frr.conf b/tests/topotests/bgp_path_attribute_discard/r1/frr.conf new file mode 100644 index 000000000000..ae7fbdd9a93a --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/r1/frr.conf @@ -0,0 +1,9 @@ +! +interface r1-eth0 + ip address 10.0.0.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 10.0.0.254 remote-as external + neighbor 10.0.0.254 timers 3 10 +! diff --git a/tests/topotests/bgp_path_attribute_discard/r1/zebra.conf b/tests/topotests/bgp_path_attribute_discard/r1/zebra.conf deleted file mode 100644 index 51a1b2657cd9..000000000000 --- a/tests/topotests/bgp_path_attribute_discard/r1/zebra.conf +++ /dev/null @@ -1,4 +0,0 @@ -! -interface r1-eth0 - ip address 10.0.0.1/24 -! diff --git a/tests/topotests/bgp_path_attribute_discard/r2/frr.conf b/tests/topotests/bgp_path_attribute_discard/r2/frr.conf new file mode 100644 index 000000000000..1dafbdd8e19f --- /dev/null +++ b/tests/topotests/bgp_path_attribute_discard/r2/frr.conf @@ -0,0 +1,10 @@ +! +interface r2-eth0 + ip address 10.0.0.2/24 +! +router bgp 65254 + no bgp ebgp-requires-policy + neighbor 10.0.0.254 remote-as internal + neighbor 10.0.0.254 timers 3 10 + neighbor 10.0.0.254 path-attribute discard 26 +! diff --git a/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py index c97cd0bddabd..bd8cd8e18a94 100644 --- a/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py +++ b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py @@ -31,10 +31,12 @@ def build_topo(tgen): r1 = tgen.add_router("r1") - peer1 = tgen.add_exabgp_peer("peer1", ip="10.0.0.2", defaultRoute="via 10.0.0.1") + r2 = tgen.add_router("r2") + peer1 = tgen.add_exabgp_peer("peer1", ip="10.0.0.254", defaultRoute="via 10.0.0.1") switch = tgen.add_switch("s1") switch.add_link(r1) + switch.add_link(r2) switch.add_link(peer1) @@ -42,10 +44,10 @@ def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) tgen.start_topology() - router = tgen.gears["r1"] - router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf")) - router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r1/bgpd.conf")) - router.start() + for _, (rname, router) in enumerate(tgen.routers().items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() peer = tgen.gears["peer1"] peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env")) @@ -63,6 +65,7 @@ def test_bgp_path_attribute_discard(): pytest.skip(tgen.errors) r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] def _bgp_converge(): output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast json detail")) @@ -103,7 +106,7 @@ def _bgp_converge(): """ configure terminal router bgp - neighbor 10.0.0.2 path-attribute discard 6 8 + neighbor 10.0.0.254 path-attribute discard 6 8 """ ) @@ -139,6 +142,28 @@ def _bgp_check_if_attributes_discarded(): result is None ), "Failed to discard path attributes (atomic-aggregate, community)" + def _bgp_check_if_aigp_invalid_attribute_discarded(): + output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast json detail")) + expected = { + "routes": { + "192.168.100.101/32": { + "paths": [ + { + "valid": True, + "aigpMetric": None, + } + ], + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_if_aigp_invalid_attribute_discarded) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert ( + result is None + ), "Failed to discard AIGP invalid path attribute (iBGP session)" + def test_memory_leak(): "Run the memory leak test and report results." From 552a0a3a284194dc4f9dac3d72259e9d622813e1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 30 Apr 2024 14:18:03 +0200 Subject: [PATCH 036/472] lib: fix `time_t` print without cast The gcc plugin wasn't warning about printing `suseconds_t` (which is `time_t`, but in `struct timeval`.) It needs to be printed with a cast, just like `time_t`. Luckily there is only one such usage. Signed-off-by: David Lamparter --- lib/northbound_oper.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/northbound_oper.c b/lib/northbound_oper.c index 7e7190f5a49e..5f38c970c77e 100644 --- a/lib/northbound_oper.c +++ b/lib/northbound_oper.c @@ -1556,8 +1556,9 @@ static enum nb_error nb_op_yield(struct nb_op_yield_state *ys) unsigned long min_us = MAX(1, NB_OP_WALK_INTERVAL_US / 50000); struct timeval tv = { .tv_sec = 0, .tv_usec = min_us }; - DEBUGD(&nb_dbg_events, "NB oper-state: yielding %s for %lus (should_batch %d)", - ys->xpath, tv.tv_usec, ys->should_batch); + DEBUGD(&nb_dbg_events, + "NB oper-state: yielding %s for %lldus (should_batch %d)", + ys->xpath, (long long)tv.tv_usec, ys->should_batch); if (ys->should_batch) { /* From da3677e7199e1911e55a70ab37b2a2ebac2db6a9 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 30 Apr 2024 14:13:22 +0200 Subject: [PATCH 037/472] tools/gcc-plugins: warn for `suseconds_t` format The plugin was already catching attempts to print `time_t` without casting it first (there is no valid printf specifier without a cast), but `__suseconds64_t` needs the same treatment. (Probably `__suseconds_t` too, if it exists, which I'm not sure it does - but that doesn't matter, the plugin ignores non-existing types.) Signed-off-by: David Lamparter --- tools/gcc-plugins/frr-format.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/gcc-plugins/frr-format.c b/tools/gcc-plugins/frr-format.c index 4e2c2d3ba9c2..963741e4798f 100644 --- a/tools/gcc-plugins/frr-format.c +++ b/tools/gcc-plugins/frr-format.c @@ -66,6 +66,8 @@ static GTY(()) tree local_pid_t_node; static GTY(()) tree local_uid_t_node; static GTY(()) tree local_gid_t_node; static GTY(()) tree local_time_t_node; +static GTY(()) tree local_suseconds_t_node; +static GTY(()) tree local_suseconds64_t_node; static GTY(()) tree local_socklen_t_node; static GTY(()) tree local_in_addr_t_node; @@ -85,6 +87,8 @@ static struct type_special { { &local_uid_t_node, NULL, &local_uid_t_node, }, { &local_gid_t_node, NULL, &local_gid_t_node, }, { &local_time_t_node, NULL, &local_time_t_node, }, + { &local_suseconds_t_node, NULL, &local_suseconds_t_node, }, + { &local_suseconds64_t_node, NULL, &local_suseconds64_t_node, }, { NULL, NULL, NULL, } }; @@ -4176,6 +4180,8 @@ handle_finish_parse (void *event_data, void *data) setup_type ("uid_t", &local_uid_t_node); setup_type ("gid_t", &local_gid_t_node); setup_type ("time_t", &local_time_t_node); + setup_type ("__suseconds_t", &local_suseconds_t_node); + setup_type ("__suseconds64_t", &local_suseconds64_t_node); setup_type ("socklen_t", &local_socklen_t_node); setup_type ("in_addr_t", &local_in_addr_t_node); From e069a1c8d52bb6e7808303df488d7ce912e4f652 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 2 May 2024 23:07:19 +0300 Subject: [PATCH 038/472] bgpd: Fix `no set as-path prepend ASNUM...` If entering `no set as-path prepend 1 2 3`, it's warned as unknown command. Now fixed, and the following combinations work fine: ``` no set as-path prepend no set as-path prepend last-as no set as-path prepend last-as 1 no set as-path prepend 1 no set as-path prepend 1 2 ``` Fixes: https://github.com/FRRouting/frr/issues/15912 Signed-off-by: Donatas Abraitis --- bgpd/bgp_routemap.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 4875697aa106..7eb97dae4d24 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -6288,13 +6288,12 @@ DEFPY_YANG( } DEFUN_YANG (no_set_aspath_prepend, - no_set_aspath_prepend_cmd, - "no set as-path prepend [ASNUM] [last-as [(1-10)]]", + no_set_aspath_prepend_last_as_cmd, + "no set as-path prepend [last-as [(1-10)]]", NO_STR SET_STR "Transform BGP AS_PATH attribute\n" "Prepend to the as-path\n" - AS_STR "Use the peers AS-number\n" "Number of times to insert\n") { @@ -6305,6 +6304,15 @@ DEFUN_YANG (no_set_aspath_prepend, return nb_cli_apply_changes(vty, NULL); } +ALIAS_YANG (no_set_aspath_prepend, + no_set_aspath_prepend_as_cmd, + "no set as-path prepend ASNUM...", + NO_STR + SET_STR + "Transform BGP AS_PATH attribute\n" + "Prepend to the as-path\n" + AS_STR) + DEFUN_YANG (set_aspath_exclude, set_aspath_exclude_cmd, "set as-path exclude ASNUM...", @@ -7981,7 +7989,8 @@ void bgp_route_map_init(void) install_element(RMAP_NODE, &set_aspath_exclude_access_list_cmd); install_element(RMAP_NODE, &set_aspath_replace_asn_cmd); install_element(RMAP_NODE, &set_aspath_replace_access_list_cmd); - install_element(RMAP_NODE, &no_set_aspath_prepend_cmd); + install_element(RMAP_NODE, &no_set_aspath_prepend_last_as_cmd); + install_element(RMAP_NODE, &no_set_aspath_prepend_as_cmd); install_element(RMAP_NODE, &no_set_aspath_exclude_cmd); install_element(RMAP_NODE, &no_set_aspath_exclude_all_cmd); install_element(RMAP_NODE, &no_set_aspath_exclude_access_list_cmd); From 3ca60d00b1a3ca3822db5fcf6ba46cf3ac0a6b0b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 2 May 2024 10:55:11 +0200 Subject: [PATCH 039/472] *: add XREF_SETUP() to libraries and utilites This is theoretically not needed if neither DEFUNs nor zlog_* calls are used, except I'm about to turn it into a build error to catch the cases where it _is_ necessary. Which is libmgmt_be_nb.la in this case, where it causes build failures on hppa. Signed-off-by: David Lamparter --- fpm/fpm_pb.c | 5 +++++ mgmtd/mgmt_be_nb.c | 6 ++++++ mgmtd/subdir.am | 1 + qpb/qpb.c | 5 +++++ zebra/fpm_listener.c | 2 ++ 5 files changed, 19 insertions(+) create mode 100644 mgmtd/mgmt_be_nb.c diff --git a/fpm/fpm_pb.c b/fpm/fpm_pb.c index e4c9395a84a6..0e8f618c4d3c 100644 --- a/fpm/fpm_pb.c +++ b/fpm/fpm_pb.c @@ -10,3 +10,8 @@ /* * Main file for the fpm_pb library. */ + +#include "config.h" +#include "xref.h" + +XREF_SETUP(); diff --git a/mgmtd/mgmt_be_nb.c b/mgmtd/mgmt_be_nb.c new file mode 100644 index 000000000000..613272d40728 --- /dev/null +++ b/mgmtd/mgmt_be_nb.c @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "config.h" +#include "xref.h" + +XREF_SETUP(); diff --git a/mgmtd/subdir.am b/mgmtd/subdir.am index 5182c4a47d37..14544c4f0507 100644 --- a/mgmtd/subdir.am +++ b/mgmtd/subdir.am @@ -16,6 +16,7 @@ clippy_scan += \ lib_LTLIBRARIES += mgmtd/libmgmt_be_nb.la mgmtd_libmgmt_be_nb_la_SOURCES = \ + mgmtd/mgmt_be_nb.c \ zebra/zebra_cli.c \ # end nodist_mgmtd_libmgmt_be_nb_la_SOURCES = \ diff --git a/qpb/qpb.c b/qpb/qpb.c index 63454f115666..625817857819 100644 --- a/qpb/qpb.c +++ b/qpb/qpb.c @@ -10,3 +10,8 @@ /* * Main file for the qpb library. */ + +#include "config.h" +#include "xref.h" + +XREF_SETUP(); diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c index b31c5f7ac66a..5533fa7f8be4 100644 --- a/zebra/fpm_listener.c +++ b/zebra/fpm_listener.c @@ -36,6 +36,8 @@ #include "fpm/fpm.h" #include "lib/libfrr.h" +XREF_SETUP(); + struct glob { int server_sock; int sock; From 85b09765c45e3fcfc1eb1400eff659454850a42f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 2 May 2024 10:57:31 +0200 Subject: [PATCH 040/472] build: warn/fail on missing `XREF_SETUP()` While clippy tries really, really hard to work under adverse conditions, and this catches missing XREF_SETUP() on almost all CPU architectures, this doesn't quite work on hppa. So, make it a warning on *all* platforms (or error for --enable-dev-build) in order to catch it before shipping off to Debian's buildd and blowing up there... Signed-off-by: David Lamparter --- lib/elf_py.c | 9 +++++++++ python/clippy/__init__.py | 1 + python/xrelfo.py | 15 ++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/elf_py.c b/lib/elf_py.c index 643495d8c76f..2b4fea373f03 100644 --- a/lib/elf_py.c +++ b/lib/elf_py.c @@ -1358,6 +1358,15 @@ bool elf_py_init(PyObject *pymod) (void)methods_elfpy; #endif +#if defined(HAVE_GELF_GETNOTE) && defined(HAVE_ELF_GETDATA_RAWCHUNK) + PyObject *elf_notes = Py_True; +#else + PyObject *elf_notes = Py_False; +#endif + Py_INCREF(elf_notes); + if (PyModule_AddObject(pymod, "elf_notes", elf_notes)) + Py_DECREF(elf_notes); + ELFFormatError = PyErr_NewException("_clippy.ELFFormatError", PyExc_ValueError, NULL); PyModule_AddObject(pymod, "ELFFormatError", ELFFormatError); diff --git a/python/clippy/__init__.py b/python/clippy/__init__.py index 60119fbac097..668724ab2ab8 100644 --- a/python/clippy/__init__.py +++ b/python/clippy/__init__.py @@ -20,6 +20,7 @@ CMD_ATTR_HIDDEN, CMD_ATTR_DEPRECATED, CMD_ATTR_NOSH, + elf_notes, ) diff --git a/python/xrelfo.py b/python/xrelfo.py index a40b19e5fb52..07cd74071f8e 100644 --- a/python/xrelfo.py +++ b/python/xrelfo.py @@ -22,7 +22,7 @@ from clippy.uidhash import uidhash from clippy.elf import * -from clippy import frr_top_src, CmdAttr +from clippy import frr_top_src, CmdAttr, elf_notes from tiabwarfo import FieldApplicator from xref2vtysh import CommandEntry @@ -327,6 +327,7 @@ def __init__(self): } ) self._xrefs = [] + self.note_warn = False def load_file(self, filename): orig_filename = filename @@ -395,6 +396,15 @@ def load_elf(self, filename, orig_filename): ptrs = edf.iter_data(XrefPtr, slice(start, end)) else: + if elf_notes: + self.note_warn = True + sys.stderr.write( + """%s: warning: binary has no FRRouting.XREF note +%s- one of FRR_MODULE_SETUP, FRR_DAEMON_INFO or XREF_SETUP must be used +""" + % (orig_filename, orig_filename) + ) + xrefarray = edf.get_section("xref_array") if xrefarray is None: raise ValueError("file has neither xref note nor xref_array section") @@ -471,6 +481,9 @@ def _main(args): sys.stderr.write("while processing %s:\n" % (fn)) traceback.print_exc() + if xrelfo.note_warn and args.Werror: + errors += 1 + for option in dir(args): if option.startswith("W") and option != "Werror": checks = sorted(xrelfo.check(args)) From 2e84c37460e2f0f3444afe6645620c556a5f209a Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 2 May 2024 11:00:17 +0200 Subject: [PATCH 041/472] build: hppa is weird hppa (yes, HP PA-RISC) apparently creates relocations that refer to ".init+0x12345" for everything, referencing way past the end of the .init section. While this is only fallback code hit when XREF_SETUP() is missing (i.e. the FRRouting.XREF ELF note is absent), try to make it work anyway. Signed-off-by: David Lamparter --- python/clippy/elf.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/python/clippy/elf.py b/python/clippy/elf.py index cc442eeda9aa..fd348428f0ad 100644 --- a/python/clippy/elf.py +++ b/python/clippy/elf.py @@ -458,7 +458,16 @@ def __getitem__(self, k): - `this[123:str]` - extract until null byte. The slice stop value is the `str` type (or, technically, `unicode`.) """ - return self._obj[k] + if k.start < getattr(self._obj, "len", float("+Inf")): + return self._obj[k] + + real_sect = self._elffile.get_section_addr(self._obj.sh_addr + k.start) + offs = self._obj.sh_addr - real_sect.sh_addr + if k.stop is str: + new_k = slice(k.start + offs, str) + else: + new_k = slice(k.start + offs, k.stop + offs) + return real_sect[new_k] def getreloc(self, offset): """ From e411988a86f1b719fb16ec4c30499bfc650b4ea7 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 3 May 2024 08:58:21 +0300 Subject: [PATCH 042/472] bgpd: Allow using optional table id for negative `no set table X` command Signed-off-by: Donatas Abraitis --- bgpd/bgp_routemap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 7eb97dae4d24..df5c2557bd26 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -5897,10 +5897,11 @@ DEFUN_YANG (set_table_id, DEFUN_YANG (no_set_table_id, no_set_table_id_cmd, - "no set table", + "no set table [(1-4294967295)]", NO_STR SET_STR - "export route to non-main kernel table\n") + "export route to non-main kernel table\n" + "Kernel routing table id\n") { const char *xpath = "./set-action[action='frr-bgp-route-map:table']"; nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); From 255b392093b73ab69bdf3a7bc8940184d1fbac1a Mon Sep 17 00:00:00 2001 From: David Schweizer Date: Mon, 2 Nov 2020 16:30:02 +0100 Subject: [PATCH 043/472] bgpd: vtysh commands for peer/group dampening profiles Additional cli commands to add dampening profiles to peers / peer groups and functions to save dampening configurations. Signed-off-by: David Schweizer --- bgpd/bgp_vty.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 5aedd6b82894..eb15d8b9ae25 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9468,6 +9468,92 @@ DEFPY(no_neighbor_path_attribute_treat_as_withdraw, return CMD_SUCCESS; } +DEFPY(neighbor_damp, + neighbor_damp_cmd, + "neighbor $neighbor dampening [(1-45)$half [(1-20000)$reuse (1-20000)$suppress (1-255)$max]]", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Enable neighbor route-flap dampening\n" + "Half-life time for the penalty\n" + "Value to start reusing a route\n" + "Value to start suppressing a route\n" + "Maximum duration to suppress a stable route\n") +{ + struct peer *peer = peer_and_group_lookup_vty(vty, neighbor); + + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + if (!half) + half = DEFAULT_HALF_LIFE; + if (!reuse) { + reuse = DEFAULT_REUSE; + suppress = DEFAULT_SUPPRESS; + max = half * 4; + } + if (suppress < reuse) { + vty_out(vty, "Suppress value cannot be less than reuse value\n"); + return CMD_WARNING_CONFIG_FAILED; + } + bgp_peer_damp_enable(peer, bgp_node_afi(vty), bgp_node_safi(vty), + half * 60, reuse, suppress, max * 60); + return CMD_SUCCESS; +} + +DEFPY(no_neighbor_damp, + no_neighbor_damp_cmd, + "no neighbor $neighbor dampening [HALF [REUSE SUPPRESS MAX]]", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Enable neighbor route-flap dampening\n" + "Half-life time for the penalty\n" + "Value to start reusing a route\n" + "Value to start suppressing a route\n" + "Maximum duration to suppress a stable route\n") +{ + struct peer *peer = peer_and_group_lookup_vty(vty, neighbor); + + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + bgp_peer_damp_disable(peer, bgp_node_afi(vty), bgp_node_safi(vty)); + return CMD_SUCCESS; +} + +DEFPY (show_ip_bgp_neighbor_damp_param, + show_ip_bgp_neighbor_damp_param_cmd, + "show [ip] bgp [ [unicast]] neighbors $neighbor dampening parameters [json]$json", + SHOW_STR + IP_STR + BGP_STR + BGP_AFI_HELP_STR + "Address Family modifier\n" + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Neighbor route-flap dampening information\n" + "Display detail of configured dampening parameters\n" + JSON_STR) +{ + bool use_json = false; + int idx = 0; + afi_t afi = AFI_IP; + safi_t safi = SAFI_UNICAST; + struct peer *peer; + + if (argv_find(argv, argc, "ip", &idx)) + afi = AFI_IP; + if (argv_find(argv, argc, "ipv4", &idx)) + afi = AFI_IP; + if (argv_find(argv, argc, "ipv6", &idx)) + afi = AFI_IP6; + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING; + if (json) + use_json = true; + bgp_show_peer_dampening_parameters(vty, peer, afi, safi, use_json); + return CMD_SUCCESS; +} + static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv, struct ecommunity **list, bool is_rt6) { @@ -19002,7 +19088,15 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, /* BGP flag dampening. */ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) - bgp_config_write_damp(vty, afi, safi); + bgp_config_write_damp(vty, bgp, afi, safi); + for (ALL_LIST_ELEMENTS_RO(bgp->group, node, group)) + if (peer_af_flag_check(group->conf, afi, safi, + PEER_FLAG_CONFIG_DAMPENING)) + bgp_config_write_peer_damp(vty, group->conf, afi, safi); + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) + if (peer_af_flag_check(peer, afi, safi, + PEER_FLAG_CONFIG_DAMPENING)) + bgp_config_write_peer_damp(vty, peer, afi, safi); for (ALL_LIST_ELEMENTS(bgp->group, node, nnode, group)) bgp_config_write_peer_af(vty, bgp, group->conf, afi, safi); @@ -21381,6 +21475,23 @@ void bgp_vty_init(void) install_element(BGP_EVPN_NODE, &neighbor_soo_cmd); install_element(BGP_EVPN_NODE, &no_neighbor_soo_cmd); + /* "neighbor dampening" commands. */ + install_element(BGP_NODE, &neighbor_damp_cmd); + install_element(BGP_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV4_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV4_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV4M_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV4M_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV4L_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV4L_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV6_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV6_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV6M_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV6M_NODE, &no_neighbor_damp_cmd); + install_element(BGP_IPV6L_NODE, &neighbor_damp_cmd); + install_element(BGP_IPV6L_NODE, &no_neighbor_damp_cmd); + install_element(VIEW_NODE, &show_ip_bgp_neighbor_damp_param_cmd); + /* address-family commands. */ install_element(BGP_NODE, &address_family_ipv4_safi_cmd); install_element(BGP_NODE, &address_family_ipv6_safi_cmd); From 22473c4014c00254557b26581e1ae5a8f39b5cc4 Mon Sep 17 00:00:00 2001 From: David Schweizer Date: Mon, 2 Nov 2020 16:30:01 +0100 Subject: [PATCH 044/472] bgpd: peer / peer group dampening profiles Changes implement dampening profiles for peers and peer groups. This is achieved by introducing the possibility to have multible existing dampening configurations with their own sets of parameters and lists of associated paths. Signed-off-by: Rafael Zalamena Signed-off-by: David Schweizer --- bgpd/bgp_damp.c | 548 ++++++++++++++++++++++++++++++++++------------ bgpd/bgp_damp.h | 51 +++-- bgpd/bgp_memory.c | 1 + bgpd/bgp_memory.h | 1 + bgpd/bgp_route.c | 50 +++-- bgpd/bgpd.c | 13 ++ bgpd/bgpd.h | 8 + 7 files changed, 494 insertions(+), 178 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 6b6387b1b517..123876ed5e6a 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -22,19 +22,113 @@ #include "bgpd/bgp_advertise.h" #include "bgpd/bgp_vty.h" -/* Global variable to access damping configuration */ -static struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; +static void bgp_reuselist_add(struct reuselist *list, struct bgp_damp_info *info) +{ + struct reuselist_node *new_node; + + assert(info); + new_node = XCALLOC(MTYPE_BGP_DAMP_REUSELIST, sizeof(*new_node)); + new_node->info = info; + SLIST_INSERT_HEAD(list, new_node, entry); +} + +static void bgp_reuselist_del(struct reuselist *list, + struct reuselist_node **node) +{ + if ((*node) == NULL) + return; + assert(list && node && *node); + SLIST_REMOVE(list, (*node), reuselist_node, entry); + XFREE(MTYPE_BGP_DAMP_REUSELIST, (*node)); + *node = NULL; +} + +static void bgp_reuselist_switch(struct reuselist *source, + struct reuselist_node *node, + struct reuselist *target) +{ + assert(source && target && node); + SLIST_REMOVE(source, node, reuselist_node, entry); + SLIST_INSERT_HEAD(target, node, entry); +} + +static void bgp_reuselist_free(struct reuselist *list) +{ + struct reuselist_node *rn; + + assert(list); + while ((rn = SLIST_FIRST(list)) != NULL) + bgp_reuselist_del(list, &rn); +} + +static struct reuselist_node *bgp_reuselist_find(struct reuselist *list, + struct bgp_damp_info *info) +{ + struct reuselist_node *rn; + + assert(list && info); + SLIST_FOREACH (rn, list, entry) { + if (rn->info == info) + return rn; + } + return NULL; +} + +static void bgp_damp_info_unclaim(struct bgp_damp_info *bdi) +{ + struct reuselist_node *node; + + assert(bdi && bdi->config); + if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) { + node = bgp_reuselist_find(&bdi->config->no_reuse_list, bdi); + if (node) + bgp_reuselist_del(&bdi->config->no_reuse_list, &node); + } else { + node = bgp_reuselist_find(&bdi->config->reuse_list[bdi->index], + bdi); + if (node) + bgp_reuselist_del(&bdi->config->reuse_list[bdi->index], + &node); + } + bdi->config = NULL; +} + +static void bgp_damp_info_claim(struct bgp_damp_info *bdi, + struct bgp_damp_config *bdc) +{ + assert(bdc && bdi); + if (bdi->config == NULL) { + bdi->config = bdc; + return; + } + bgp_damp_info_unclaim(bdi); + bdi->config = bdc; + bdi->afi = bdc->afi; + bdi->safi = bdc->safi; +} -/* Utility macro to add and delete BGP dampening information to no - used list. */ -#define BGP_DAMP_LIST_ADD(N, A) BGP_PATH_INFO_ADD(N, A, no_reuse_list) -#define BGP_DAMP_LIST_DEL(N, A) BGP_PATH_INFO_DEL(N, A, no_reuse_list) +struct bgp_damp_config *get_active_bdc_from_pi(struct bgp_path_info *pi, + afi_t afi, safi_t safi) +{ + if (!pi) + return NULL; + if (CHECK_FLAG(pi->peer->af_flags[afi][safi], + PEER_FLAG_CONFIG_DAMPENING)) + return &pi->peer->damp[afi][safi]; + if (peer_group_active(pi->peer)) + if (CHECK_FLAG(pi->peer->group->conf->af_flags[afi][safi], + PEER_FLAG_CONFIG_DAMPENING)) + return &pi->peer->group->conf->damp[afi][safi]; + if (CHECK_FLAG(pi->peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) + return &pi->peer->bgp->damp[afi][safi]; + return NULL; +} /* Calculate reuse list index by penalty value. */ static int bgp_reuse_index(int penalty, struct bgp_damp_config *bdc) { unsigned int i; - int index; + unsigned int index; /* * reuse_limit can't be zero, this is for Coverity @@ -57,27 +151,45 @@ static int bgp_reuse_index(int penalty, struct bgp_damp_config *bdc) static void bgp_reuse_list_add(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc) { - int index; - - index = bdi->index = bgp_reuse_index(bdi->penalty, bdc); - - bdi->prev = NULL; - bdi->next = bdc->reuse_list[index]; - if (bdc->reuse_list[index]) - bdc->reuse_list[index]->prev = bdi; - bdc->reuse_list[index] = bdi; + bgp_damp_info_claim(bdi, bdc); + bdi->index = bgp_reuse_index(bdi->penalty, bdc); + bgp_reuselist_add(&bdc->reuse_list[bdi->index], bdi); } /* Delete BGP dampening information from reuse list. */ static void bgp_reuse_list_delete(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc) { - if (bdi->next) - bdi->next->prev = bdi->prev; - if (bdi->prev) - bdi->prev->next = bdi->next; - else - bdc->reuse_list[bdi->index] = bdi->next; + struct reuselist *list; + struct reuselist_node *rn; + + list = &bdc->reuse_list[bdi->index]; + rn = bgp_reuselist_find(list, bdi); + bgp_damp_info_unclaim(bdi); + bgp_reuselist_del(list, &rn); +} + +static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi, + struct bgp_damp_config *bdc) +{ + bgp_damp_info_claim(bdi, bdc); + bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX; + bgp_reuselist_add(&bdc->no_reuse_list, bdi); +} + +static void bgp_no_reuse_list_delete(struct bgp_damp_info *bdi, + struct bgp_damp_config *bdc) +{ + struct reuselist_node *rn; + + assert(bdc && bdi); + if (bdi->config == NULL) { + bgp_damp_info_unclaim(bdi); + return; + } + bdi->config = NULL; + rn = bgp_reuselist_find(&bdc->no_reuse_list, bdi); + bgp_reuselist_del(&bdc->no_reuse_list, &rn); } /* Return decayed penalty value. */ @@ -101,9 +213,10 @@ int bgp_damp_decay(time_t tdiff, int penalty, struct bgp_damp_config *bdc) static void bgp_reuse_timer(struct event *t) { struct bgp_damp_info *bdi; - struct bgp_damp_info *next; + struct reuselist plist; + struct reuselist_node *node; + struct bgp *bgp; time_t t_now, t_diff; - struct bgp_damp_config *bdc = EVENT_ARG(t); bdc->t_reuse = NULL; @@ -112,20 +225,22 @@ static void bgp_reuse_timer(struct event *t) t_now = monotime(NULL); - /* 1. save a pointer to the current zeroth queue head and zero the - list head entry. */ - bdi = bdc->reuse_list[bdc->reuse_offset]; - bdc->reuse_list[bdc->reuse_offset] = NULL; + /* 1. save a pointer to the current queue head and zero the list head + * list head entry. */ + assert(bdc->reuse_offset < bdc->reuse_list_size); + plist = bdc->reuse_list[bdc->reuse_offset]; + node = SLIST_FIRST(&plist); + SLIST_INIT(&bdc->reuse_list[bdc->reuse_offset]); /* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby rotating the circular queue of list-heads. */ bdc->reuse_offset = (bdc->reuse_offset + 1) % bdc->reuse_list_size; + assert(bdc->reuse_offset < bdc->reuse_list_size); /* 3. if ( the saved list head pointer is non-empty ) */ - for (; bdi; bdi = next) { - struct bgp *bgp = bdi->path->peer->bgp; - - next = bdi->next; + while ((node = SLIST_FIRST(&plist)) != NULL) { + bdi = node->info; + bgp = bdi->path->peer->bgp; /* Set t-diff = t-now - t-updated. */ t_diff = t_now - bdi->t_updated; @@ -154,15 +269,26 @@ static void bgp_reuse_timer(struct event *t) bdi->safi); } - if (bdi->penalty <= bdc->reuse_limit / 2.0) - bgp_damp_info_free(bdi, 1, bdc->afi, bdc->safi); - else - BGP_DAMP_LIST_ADD(bdc, bdi); - } else + if (bdi->penalty <= bdc->reuse_limit / 2.0) { + bgp_damp_info_free(&bdi, bdc, 1, bdi->afi, + bdi->safi); + bgp_reuselist_del(&plist, &node); + } else { + node->info->index = + BGP_DAMP_NO_REUSE_LIST_INDEX; + bgp_reuselist_switch(&plist, node, + &bdc->no_reuse_list); + } + } else { /* Re-insert into another list (See RFC2439 Section * 4.8.6). */ - bgp_reuse_list_add(bdi, bdc); + bdi->index = bgp_reuse_index(bdi->penalty, bdc); + bgp_reuselist_switch(&plist, node, + &bdc->reuse_list[bdi->index]); + } } + + assert(SLIST_EMPTY(&plist)); } /* A route becomes unreachable (RFC2439 Section 4.8.2). */ @@ -172,10 +298,13 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, time_t t_now; struct bgp_damp_info *bdi = NULL; unsigned int last_penalty = 0; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; - t_now = monotime(NULL); + bdc = get_active_bdc_from_pi(path, afi, safi); + if (!bdc) + return BGP_DAMP_USED; + t_now = monotime(NULL); /* Processing Unreachable Messages. */ if (path->extra) bdi = path->extra->damp_info; @@ -197,12 +326,13 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, bdi->flap = 1; bdi->start_time = t_now; bdi->suppress_time = 0; - bdi->index = -1; + bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX; bdi->afi = afi; bdi->safi = safi; (bgp_path_info_extra_get(path))->damp_info = bdi; - BGP_DAMP_LIST_ADD(bdc, bdi); + bgp_no_reuse_list_add(bdi, bdc); } else { + bgp_damp_info_claim(bdi, bdc); last_penalty = bdi->penalty; /* 1. Set t-diff = t-now - t-updated. */ @@ -228,7 +358,7 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, /* Remove the route from a reuse list if it is on one. */ if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) { /* If decay rate isn't equal to 0, reinsert brn. */ - if (bdi->penalty != last_penalty && bdi->index >= 0) { + if (bdi->penalty != last_penalty) { bgp_reuse_list_delete(bdi, bdc); bgp_reuse_list_add(bdi, bdc); } @@ -240,10 +370,9 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, if (bdi->penalty >= bdc->suppress_value) { bgp_path_info_set_flag(dest, path, BGP_PATH_DAMPED); bdi->suppress_time = t_now; - BGP_DAMP_LIST_DEL(bdc, bdi); + bgp_no_reuse_list_delete(bdi, bdc); bgp_reuse_list_add(bdi, bdc); } - return BGP_DAMP_USED; } @@ -253,7 +382,10 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, time_t t_now; struct bgp_damp_info *bdi; int status; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; + + bdc = get_active_bdc_from_pi(path, afi, safi); + assert(bdc); if (!path->extra || !((bdi = path->extra->damp_info))) return BGP_DAMP_USED; @@ -272,7 +404,7 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, && (bdi->penalty < bdc->reuse_limit)) { bgp_path_info_unset_flag(dest, path, BGP_PATH_DAMPED); bgp_reuse_list_delete(bdi, bdc); - BGP_DAMP_LIST_ADD(bdc, bdi); + bgp_no_reuse_list_add(bdi, bdc); bdi->suppress_time = 0; status = BGP_DAMP_USED; } else @@ -280,35 +412,31 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, if (bdi->penalty > bdc->reuse_limit / 2.0) bdi->t_updated = t_now; - else - bgp_damp_info_free(bdi, 0, afi, safi); + else { + bgp_damp_info_unclaim(bdi); + bgp_damp_info_free(&bdi, bdc, 0, afi, safi); + } return status; } -void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw, afi_t afi, - safi_t safi) +void bgp_damp_info_free(struct bgp_damp_info **bdi, struct bgp_damp_config *bdc, + int withdraw, afi_t afi, safi_t safi) { - struct bgp_path_info *path; - struct bgp_damp_config *bdc = &damp[afi][safi]; + assert(bdc && bdi && *bdi); - if (!bdi) + if ((*bdi)->path == NULL) { + XFREE(MTYPE_BGP_DAMP_INFO, (*bdi)); return; + } - path = bdi->path; - path->extra->damp_info = NULL; - - if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) - bgp_reuse_list_delete(bdi, bdc); - else - BGP_DAMP_LIST_DEL(bdc, bdi); - - bgp_path_info_unset_flag(bdi->dest, path, + (*bdi)->path->extra->damp_info = NULL; + bgp_path_info_unset_flag((*bdi)->dest, (*bdi)->path, BGP_PATH_HISTORY | BGP_PATH_DAMPED); - if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) { - bgp_path_info_delete(bdi->dest, path); - bgp_process(path->peer->bgp, bdi->dest, path, afi, safi); + if ((*bdi)->lastrecord == BGP_RECORD_WITHDRAW && withdraw) { + bgp_path_info_delete((*bdi)->dest, (*bdi)->path); + bgp_process((*bdi)->path->peer->bgp, (*bdi)->dest, (*bdi)->path, afi, safi); } XFREE(MTYPE_BGP_DAMP_INFO, bdi); @@ -355,8 +483,7 @@ static void bgp_damp_parameter_set(time_t hlife, unsigned int reuse, bdc->reuse_list = XCALLOC(MTYPE_BGP_DAMP_ARRAY, - bdc->reuse_list_size * sizeof(struct bgp_reuse_node *)); - + bdc->reuse_list_size * sizeof(struct reuselist)); /* Reuse-array computations */ bdc->reuse_index = XCALLOC(MTYPE_BGP_DAMP_ARRAY, sizeof(int) * bdc->reuse_index_size); @@ -383,7 +510,7 @@ static void bgp_damp_parameter_set(time_t hlife, unsigned int reuse, int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, unsigned int reuse, unsigned int suppress, time_t max) { - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc = &bgp->damp[afi][safi]; if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) { if (bdc->half_life == half && bdc->reuse_limit == reuse @@ -395,6 +522,8 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, SET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); bgp_damp_parameter_set(half, reuse, suppress, max, bdc); + bdc->afi = afi; + bdc->safi = safi; /* Register reuse timer. */ event_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE, @@ -403,8 +532,30 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, return 0; } -static void bgp_damp_config_clean(struct bgp_damp_config *bdc) +/* Clean all the bgp_damp_info stored in reuse_list and no_reuse_list. */ +void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, safi_t safi) { + struct bgp_damp_info *bdi; + struct reuselist_node *rn; + struct reuselist *list; + unsigned int i; + + bdc->reuse_offset = 0; + for (i = 0; i < bdc->reuse_list_size; ++i) { + list = &bdc->reuse_list[i]; + while ((rn = SLIST_FIRST(list)) != NULL) { + bdi = rn->info; + bgp_reuselist_del(list, &rn); + bgp_damp_info_free(&bdi, bdc, 1, afi, safi); + } + } + + while ((rn = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) { + bdi = rn->info; + bgp_reuselist_del(&bdc->no_reuse_list, &rn); + bgp_damp_info_free(&bdi, bdc, 1, afi, safi); + } + /* Free decay array */ XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->decay_array); bdc->decay_array_size = 0; @@ -414,40 +565,28 @@ static void bgp_damp_config_clean(struct bgp_damp_config *bdc) bdc->reuse_index_size = 0; /* Free reuse list array. */ + for (i = 0; i < bdc->reuse_list_size; ++i) + bgp_reuselist_free(&bdc->reuse_list[i]); + XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_list); bdc->reuse_list_size = 0; -} - -/* Clean all the bgp_damp_info stored in reuse_list. */ -void bgp_damp_info_clean(afi_t afi, safi_t safi) -{ - unsigned int i; - struct bgp_damp_info *bdi, *next; - struct bgp_damp_config *bdc = &damp[afi][safi]; - - bdc->reuse_offset = 0; - - for (i = 0; i < bdc->reuse_list_size; i++) { - if (!bdc->reuse_list[i]) - continue; - - for (bdi = bdc->reuse_list[i]; bdi; bdi = next) { - next = bdi->next; - bgp_damp_info_free(bdi, 1, afi, safi); - } - bdc->reuse_list[i] = NULL; - } - for (bdi = bdc->no_reuse_list; bdi; bdi = next) { - next = bdi->next; - bgp_damp_info_free(bdi, 1, afi, safi); - } - bdc->no_reuse_list = NULL; + EVENT_OFF(bdc->t_reuse); } +/* Disable route flap dampening for a bgp instance. + * + * Please note that this function also gets used to free memory when deleting a + * bgp instance. + */ int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi) { - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; + + bdc = &bgp->damp[afi][safi]; + if (!bdc) + return 0; + /* If it wasn't enabled, there's nothing to do. */ if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) return 0; @@ -456,54 +595,51 @@ int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi) EVENT_OFF(bdc->t_reuse); /* Clean BGP dampening information. */ - bgp_damp_info_clean(afi, safi); - - /* Clear configuration */ - bgp_damp_config_clean(bdc); + bgp_damp_info_clean(bdc, afi, safi); UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); + return 0; } -void bgp_config_write_damp(struct vty *vty, afi_t afi, safi_t safi) +void bgp_config_write_damp(struct vty *vty, struct bgp *bgp, afi_t afi, + safi_t safi) { - if (damp[afi][safi].half_life == DEFAULT_HALF_LIFE * 60 - && damp[afi][safi].reuse_limit == DEFAULT_REUSE - && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS - && damp[afi][safi].max_suppress_time - == damp[afi][safi].half_life * 4) + struct bgp_damp_config *bdc; + + bdc = &bgp->damp[afi][safi]; + if (bdc->half_life == DEFAULT_HALF_LIFE * 60 && + bdc->reuse_limit == DEFAULT_REUSE && + bdc->suppress_value == DEFAULT_SUPPRESS && + bdc->max_suppress_time == bdc->half_life * 4) vty_out(vty, " bgp dampening\n"); - else if (damp[afi][safi].half_life != DEFAULT_HALF_LIFE * 60 - && damp[afi][safi].reuse_limit == DEFAULT_REUSE - && damp[afi][safi].suppress_value == DEFAULT_SUPPRESS - && damp[afi][safi].max_suppress_time - == damp[afi][safi].half_life * 4) - vty_out(vty, " bgp dampening %lld\n", - damp[afi][safi].half_life / 60LL); + else if (bdc->half_life != DEFAULT_HALF_LIFE * 60 && + bdc->reuse_limit == DEFAULT_REUSE && + bdc->suppress_value == DEFAULT_SUPPRESS && + bdc->max_suppress_time == bdc->half_life * 4) + vty_out(vty, " bgp dampening %lld\n", bdc->half_life / 60LL); else vty_out(vty, " bgp dampening %lld %d %d %lld\n", - damp[afi][safi].half_life / 60LL, - damp[afi][safi].reuse_limit, - damp[afi][safi].suppress_value, - damp[afi][safi].max_suppress_time / 60LL); + bdc->half_life / 60LL, bdc->reuse_limit, + bdc->suppress_value, bdc->max_suppress_time / 60LL); } -static const char *bgp_get_reuse_time(unsigned int penalty, char *buf, - size_t len, afi_t afi, safi_t safi, - bool use_json, json_object *json) +static const char *bgp_get_reuse_time(struct bgp_damp_config *bdc, + unsigned int penalty, char *buf, + size_t len, bool use_json, + json_object *json) { time_t reuse_time = 0; struct tm tm; int time_store = 0; - if (penalty > damp[afi][safi].reuse_limit) { - reuse_time = (int)(DELTA_T - * ((log((double)damp[afi][safi].reuse_limit - / penalty)) - / (log(damp[afi][safi].decay_array[1])))); + if (penalty > bdc->reuse_limit) { + reuse_time = (int)(DELTA_T * + ((log((double)bdc->reuse_limit / penalty)) / + (log(bdc->decay_array[1])))); - if (reuse_time > damp[afi][safi].max_suppress_time) - reuse_time = damp[afi][safi].max_suppress_time; + if (reuse_time > bdc->max_suppress_time) + reuse_time = bdc->max_suppress_time; gmtime_r(&reuse_time, &tm); } else @@ -555,14 +691,15 @@ static const char *bgp_get_reuse_time(unsigned int penalty, char *buf, return buf; } -void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, afi_t afi, - safi_t safi, json_object *json_path) +void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp, + struct bgp_path_info *path, afi_t afi, safi_t safi, + json_object *json_path) { struct bgp_damp_info *bdi; time_t t_now, t_diff; char timebuf[BGP_UPTIME_LEN] = {}; int penalty; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc = &bgp->damp[afi][safi]; if (!path->extra) return; @@ -590,8 +727,8 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, afi_t afi, if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED) && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) - bgp_get_reuse_time(penalty, timebuf, BGP_UPTIME_LEN, - afi, safi, 1, json_path); + bgp_get_reuse_time(bdc, penalty, timebuf, + BGP_UPTIME_LEN, 1, json_path); } else { vty_out(vty, " Dampinfo: penalty %d, flapped %d times in %s", @@ -602,14 +739,15 @@ void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, afi_t afi, if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED) && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) vty_out(vty, ", reuse in %s", - bgp_get_reuse_time(penalty, timebuf, - BGP_UPTIME_LEN, afi, safi, 0, + bgp_get_reuse_time(bdc, penalty, timebuf, + BGP_UPTIME_LEN, 0, json_path)); vty_out(vty, "\n"); } } + const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, char *timebuf, size_t len, afi_t afi, safi_t safi, bool use_json, @@ -618,7 +756,11 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, struct bgp_damp_info *bdi; time_t t_now, t_diff; int penalty; - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc; + + bdc = get_active_bdc_from_pi(path, afi, safi); + if (!bdc) + return NULL; if (!path->extra) return NULL; @@ -638,15 +780,15 @@ const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, t_diff = t_now - bdi->t_updated; penalty = bgp_damp_decay(t_diff, bdi->penalty, bdc); - return bgp_get_reuse_time(penalty, timebuf, len, afi, safi, use_json, - json); + return bgp_get_reuse_time(bdc, penalty, timebuf, len, use_json, json); } + static int bgp_print_dampening_parameters(struct bgp *bgp, struct vty *vty, afi_t afi, safi_t safi, bool use_json) { if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)) { - struct bgp_damp_config *bdc = &damp[afi][safi]; + struct bgp_damp_config *bdc = &bgp->damp[afi][safi]; if (use_json) { json_object *json = json_object_new_object(); @@ -689,7 +831,6 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi, bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); bgp = bgp_get_default(); - if (bgp == NULL) { vty_out(vty, "No BGP process is configured\n"); return CMD_WARNING; @@ -731,3 +872,130 @@ int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi, } return CMD_SUCCESS; } + +void bgp_peer_damp_enable(struct peer *peer, afi_t afi, safi_t safi, time_t half, + unsigned int reuse, unsigned int suppress, time_t max) +{ + struct bgp_damp_config *bdc; + + if (!peer) + return; + bdc = &peer->damp[afi][safi]; + if (peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING)) { + if (bdc->half_life == half && bdc->reuse_limit == reuse && + bdc->suppress_value == suppress && + bdc->max_suppress_time == max) + return; + bgp_peer_damp_disable(peer, afi, safi); + } + SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING); + bgp_damp_parameter_set(half, reuse, suppress, max, bdc); + bdc->afi = afi; + bdc->safi = safi; + event_add_timer(bm->master, bgp_reuse_timer, bdc, DELTA_REUSE, + &bdc->t_reuse); +} + +/* Disable route flap dampening for a peer. + * + * Please note that this function also gets used to free memory when deleting a + * peer or peer group. + */ +void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp_damp_config *bdc; + + if (!peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING)) + return; + bdc = &peer->damp[afi][safi]; + if (!bdc) + return; + bgp_damp_info_clean(bdc, afi, safi); + UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING); +} + +void bgp_config_write_peer_damp(struct vty *vty, struct peer *peer, afi_t afi, + safi_t safi) +{ + struct bgp_damp_config *bdc; + + bdc = &peer->damp[afi][safi]; + if (bdc->half_life == DEFAULT_HALF_LIFE * 60 && + bdc->reuse_limit == DEFAULT_REUSE && + bdc->suppress_value == DEFAULT_SUPPRESS && + bdc->max_suppress_time == bdc->half_life * 4) + vty_out(vty, " neighbor %s dampening\n", peer->host); + else if (bdc->half_life != DEFAULT_HALF_LIFE * 60 && + bdc->reuse_limit == DEFAULT_REUSE && + bdc->suppress_value == DEFAULT_SUPPRESS && + bdc->max_suppress_time == bdc->half_life * 4) + vty_out(vty, " neighbor %s dampening %lld\n", peer->host, + bdc->half_life / 60LL); + else + vty_out(vty, " neighbor %s dampening %lld %d %d %lld\n", + peer->host, bdc->half_life / 60LL, bdc->reuse_limit, + bdc->suppress_value, bdc->max_suppress_time / 60LL); +} + +static void bgp_print_peer_dampening_parameters(struct vty *vty, + struct peer *peer, afi_t afi, + safi_t safi, bool use_json, + json_object *json) +{ + struct bgp_damp_config *bdc; + + if (!peer) + return; + if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING)) { + bdc = &peer->damp[afi][safi]; + if (!bdc) + return; + if (use_json) { + json_object_int_add(json, "halfLifeSecs", + bdc->half_life); + json_object_int_add(json, "reusePenalty", + bdc->reuse_limit); + json_object_int_add(json, "suppressPenalty", + bdc->suppress_value); + json_object_int_add(json, "maxSuppressTimeSecs", + bdc->max_suppress_time); + json_object_int_add(json, "maxSuppressPenalty", + bdc->ceiling); + } else { + vty_out(vty, "Half-life time: %lld min\n", + (long long)bdc->half_life / 60); + vty_out(vty, "Reuse penalty: %d\n", bdc->reuse_limit); + vty_out(vty, "Suppress penalty: %d\n", + bdc->suppress_value); + vty_out(vty, "Max suppress time: %lld min\n", + (long long)bdc->max_suppress_time / 60); + vty_out(vty, "Max suppress penalty: %u\n", bdc->ceiling); + vty_out(vty, "\n"); + } + } else if (!use_json) + vty_out(vty, "neighbor dampening not enabled for %s\n", + get_afi_safi_str(afi, safi, false)); +} + +void bgp_show_peer_dampening_parameters(struct vty *vty, struct peer *peer, + afi_t afi, safi_t safi, bool use_json) +{ + json_object *json; + + if (use_json) { + json = json_object_new_object(); + json_object_string_add(json, "addressFamily", + get_afi_safi_str(afi, safi, false)); + bgp_print_peer_dampening_parameters(vty, peer, afi, safi, true, + json); + vty_out(vty, "%s\n", + json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } else { + vty_out(vty, "\nFor address family: %s\n", + get_afi_safi_str(afi, safi, false)); + bgp_print_peer_dampening_parameters(vty, peer, afi, safi, false, + NULL); + } +} diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index 6033c34bfdc8..0e99d21d6206 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -10,11 +10,6 @@ /* Structure maintained on a per-route basis. */ struct bgp_damp_info { - /* Doubly linked list. This information must be linked to - reuse_list or no_reuse_list. */ - struct bgp_damp_info *next; - struct bgp_damp_info *prev; - /* Figure-of-merit. */ unsigned int penalty; @@ -30,6 +25,9 @@ struct bgp_damp_info { /* Time of route start to be suppressed. */ time_t suppress_time; + /* Back reference to associated dampening configuration. */ + struct bgp_damp_config *config; + /* Back reference to bgp_path_info. */ struct bgp_path_info *path; @@ -38,6 +36,8 @@ struct bgp_damp_info { /* Current index in the reuse_list. */ int index; +#define BGP_DAMP_NO_REUSE_LIST_INDEX \ + (-1) /* index for elements on no_reuse_list */ /* Last time message type. */ uint8_t lastrecord; @@ -48,6 +48,13 @@ struct bgp_damp_info { safi_t safi; }; +struct reuselist_node { + SLIST_ENTRY(reuselist_node) entry; + struct bgp_damp_info *info; +}; + +SLIST_HEAD(reuselist, reuselist_node); + /* Specified parameter set configuration. */ struct bgp_damp_config { /* Value over which routes suppressed. */ @@ -84,12 +91,12 @@ struct bgp_damp_config { int *reuse_index; /* Reuse list array per-set based. */ - struct bgp_damp_info **reuse_list; - int reuse_offset; + struct reuselist *reuse_list; + unsigned int reuse_offset; safi_t safi; /* All dampening information which is not on reuse list. */ - struct bgp_damp_info *no_reuse_list; + struct reuselist no_reuse_list; /* Reuse timer thread per-set base. */ struct event *t_reuse; @@ -116,6 +123,8 @@ struct bgp_damp_config { #define REUSE_LIST_SIZE 256 #define REUSE_ARRAY_SIZE 1024 +extern struct bgp_damp_config *get_active_bdc_from_pi(struct bgp_path_info *pi, + afi_t afi, safi_t safi); extern int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, unsigned int reuse, unsigned int suppress, time_t max); @@ -124,14 +133,19 @@ extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t safi, int attr_change); extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t saff); -extern void bgp_damp_info_free(struct bgp_damp_info *path, int withdraw, +extern void bgp_damp_info_free(struct bgp_damp_info **path, + struct bgp_damp_config *bdc, int withdraw, afi_t afi, safi_t safi); -extern void bgp_damp_info_clean(afi_t afi, safi_t safi); +extern void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, + safi_t safi); +extern void bgp_damp_config_clean(struct bgp_damp_config *bdc); extern int bgp_damp_decay(time_t tdiff, int penalty, - struct bgp_damp_config *damp); -extern void bgp_config_write_damp(struct vty *vty, afi_t afi, safi_t safi); -extern void bgp_damp_info_vty(struct vty *vty, struct bgp_path_info *path, - afi_t afi, safi_t safi, json_object *json_path); + struct bgp_damp_config *bdc); +extern void bgp_config_write_damp(struct vty *vty, struct bgp *bgp, afi_t afi, + safi_t safi); +extern void bgp_damp_info_vty(struct vty *vty, struct bgp *bgp, + struct bgp_path_info *path, afi_t afi, + safi_t safi, json_object *json_path); extern const char *bgp_damp_reuse_time_vty(struct vty *vty, struct bgp_path_info *path, char *timebuf, size_t len, afi_t afi, @@ -139,5 +153,14 @@ extern const char *bgp_damp_reuse_time_vty(struct vty *vty, json_object *json); extern int bgp_show_dampening_parameters(struct vty *vty, afi_t afi, safi_t safi, uint16_t show_flags); +extern void bgp_peer_damp_enable(struct peer *peer, afi_t afi, safi_t safi, + time_t half, unsigned int reuse, + unsigned int suppress, time_t max); +extern void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi); +extern void bgp_config_write_peer_damp(struct vty *vty, struct peer *peer, + afi_t afi, safi_t safi); +extern void bgp_show_peer_dampening_parameters(struct vty *vty, + struct peer *peer, afi_t afi, + safi_t safi, bool use_json); #endif /* _QUAGGA_BGP_DAMP_H */ diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index 0764f1ed181d..53c03d8102ea 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -91,6 +91,7 @@ DEFINE_MTYPE(BGPD, PEER_UPDATE_SOURCE, "BGP peer update interface"); DEFINE_MTYPE(BGPD, PEER_CONF_IF, "BGP peer config interface"); DEFINE_MTYPE(BGPD, BGP_DAMP_INFO, "Dampening info"); DEFINE_MTYPE(BGPD, BGP_DAMP_ARRAY, "BGP Dampening array"); +DEFINE_MTYPE(BGPD, BGP_DAMP_REUSELIST, "BGP Dampening reuse list"); DEFINE_MTYPE(BGPD, BGP_REGEXP, "BGP regexp"); DEFINE_MTYPE(BGPD, BGP_AGGREGATE, "BGP aggregate"); DEFINE_MTYPE(BGPD, BGP_ADDR, "BGP own address"); diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index 29584cd78054..865c5880db58 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -87,6 +87,7 @@ DECLARE_MTYPE(PEER_UPDATE_SOURCE); DECLARE_MTYPE(PEER_CONF_IF); DECLARE_MTYPE(BGP_DAMP_INFO); DECLARE_MTYPE(BGP_DAMP_ARRAY); +DECLARE_MTYPE(BGP_DAMP_REUSELIST); DECLARE_MTYPE(BGP_REGEXP); DECLARE_MTYPE(BGP_AGGREGATE); DECLARE_MTYPE(BGP_ADDR); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5f6ef5ae0774..2e7faa57c26a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -249,9 +249,6 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) return; e = *extra; - if (e->damp_info) - bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi, - e->damp_info->safi); e->damp_info = NULL; if (e->vrfleak && e->vrfleak->parent) { @@ -4279,14 +4276,16 @@ static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi, /* apply dampening, if result is suppressed, we'll be retaining * the bgp_path_info in the RIB for historical reference. */ - if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) - && peer->sort == BGP_PEER_EBGP) - if ((bgp_damp_withdraw(pi, dest, afi, safi, 0)) - == BGP_DAMP_SUPPRESSED) { - bgp_aggregate_decrement(peer->bgp, p, pi, afi, - safi); - return; + if (peer->sort == BGP_PEER_EBGP) { + if (get_active_bdc_from_pi(pi, afi, safi)) { + if (bgp_damp_withdraw(pi, dest, afi, safi, 0) == + BGP_DAMP_SUPPRESSED) { + bgp_aggregate_decrement(peer->bgp, p, pi, afi, + safi); + return; + } } + } #ifdef ENABLE_BGP_VNC if (safi == SAFI_MPLS_VPN) { @@ -4855,10 +4854,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_labels_same((const mpls_label_t *)pi->extra->label, pi->extra->num_labels, label, num_labels)))) { - if (CHECK_FLAG(bgp->af_flags[afi][safi], - BGP_CONFIG_DAMPENING) - && peer->sort == BGP_PEER_EBGP - && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { + if (get_active_bdc_from_pi(pi, afi, safi) && + peer->sort == BGP_PEER_EBGP && + CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, @@ -4959,11 +4957,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED); /* Update bgp route dampening information. */ - if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) - && peer->sort == BGP_PEER_EBGP) { + if (get_active_bdc_from_pi(pi, afi, safi) && + peer->sort == BGP_PEER_EBGP) { /* This is implicit withdraw so we should update - dampening - information. */ + * dampening information. + */ if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) bgp_damp_withdraw(pi, dest, afi, safi, 1); } @@ -5074,8 +5072,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, #endif /* Update bgp route dampening information. */ - if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) - && peer->sort == BGP_PEER_EBGP) { + if (get_active_bdc_from_pi(pi, afi, safi) && + peer->sort == BGP_PEER_EBGP) { /* Now we do normal update dampening. */ ret = bgp_damp_update(pi, dest, afi, safi); if (ret == BGP_DAMP_SUPPRESSED) { @@ -11275,7 +11273,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } if (path->extra && path->extra->damp_info) - bgp_damp_info_vty(vty, path, afi, safi, json_path); + bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path); /* Remote Label */ if (path->extra && bgp_is_valid_label(&path->extra->label[0]) @@ -15828,7 +15826,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, if (pi->extra && pi->extra->damp_info) { pi_temp = pi->next; bgp_damp_info_free( - pi->extra->damp_info, + &pi->extra->damp_info, + &bgp->damp[afi][safi], 1, afi, safi); pi = pi_temp; } else @@ -15850,7 +15849,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, if (pi->extra && pi->extra->damp_info) { pi_temp = pi->next; bgp_damp_info_free( - pi->extra->damp_info, + &pi->extra->damp_info, + &bgp->damp[afi][safi], 1, afi, safi); pi = pi_temp; } else @@ -15873,7 +15873,9 @@ DEFUN (clear_ip_bgp_dampening, BGP_STR "Clear route flap dampening information\n") { - bgp_damp_info_clean(AFI_IP, SAFI_UNICAST); + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp_damp_info_clean(&bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP, + SAFI_UNICAST); return CMD_SUCCESS; } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index ff17dc9f5e3e..e519f2667698 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2685,6 +2685,14 @@ int peer_delete(struct peer *peer) if (peer->bfd_config) bgp_peer_remove_bfd_config(peer); + /* Delete peer route flap dampening configuration. This needs to happen + * before removing the peer from peer groups. + */ + FOREACH_AFI_SAFI (afi, safi) + if (peer_af_flag_check(peer, afi, safi, + PEER_FLAG_CONFIG_DAMPENING)) + bgp_peer_damp_disable(peer, afi, safi); + /* If this peer belongs to peer group, clear up the relationship. */ if (peer->group) { @@ -3937,6 +3945,11 @@ int bgp_delete(struct bgp *bgp) EVENT_OFF(gr_info->t_route_select); } + /* Delete route flap dampening configuration */ + FOREACH_AFI_SAFI (afi, safi) { + bgp_damp_disable(bgp, afi, safi); + } + if (BGP_DEBUG(zebra, ZEBRA)) { if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) zlog_debug("Deleting Default VRF"); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index f577a6e5f357..ad749ba67675 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -33,6 +33,7 @@ PREDECL_LIST(zebra_announce); #include "bgp_addpath_types.h" #include "bgp_nexthop.h" #include "bgp_io.h" +#include "bgp_damp.h" #include "lib/bfd.h" @@ -834,6 +835,9 @@ struct bgp { enum asnotation_mode asnotation; + /* BGP route flap dampening configuration */ + struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; + QOBJ_FIELDS; }; DECLARE_QOBJ_TYPE(bgp); @@ -1508,6 +1512,9 @@ struct peer { /* Last update packet sent time */ time_t pkt_stime[AFI_MAX][SAFI_MAX]; + /* Peer / peer group route flap dampening configuration */ + struct bgp_damp_config damp[AFI_MAX][SAFI_MAX]; + /* Peer Per AF flags */ /* * Please consult the comments for *flags_override*, *flags_invert* and @@ -1549,6 +1556,7 @@ struct peer { #define PEER_FLAG_SOO (1ULL << 28) #define PEER_FLAG_SEND_EXT_COMMUNITY_RPKI (1ULL << 29) #define PEER_FLAG_ADDPATH_RX_PATHS_LIMIT (1ULL << 30) +#define PEER_FLAG_CONFIG_DAMPENING (1U << 31) #define PEER_FLAG_ACCEPT_OWN (1ULL << 63) enum bgp_addpath_strat addpath_type[AFI_MAX][SAFI_MAX]; From b29ef1082daa3e03959c530d848881ae038dafe4 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 23 Apr 2021 13:45:44 -0400 Subject: [PATCH 045/472] bgpd: Do not output peer doppleganger dampened output When we are cycling through all peers and looking for dampening data to dump, do not consider non-configed peers( dopplegangers ). Signed-off-by: Donald Sharp --- bgpd/bgp_vty.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index eb15d8b9ae25..cb94eefebaa5 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -19094,7 +19094,8 @@ static void bgp_config_write_family(struct vty *vty, struct bgp *bgp, afi_t afi, PEER_FLAG_CONFIG_DAMPENING)) bgp_config_write_peer_damp(vty, group->conf, afi, safi); for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) - if (peer_af_flag_check(peer, afi, safi, + if (CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE) && + peer_af_flag_check(peer, afi, safi, PEER_FLAG_CONFIG_DAMPENING)) bgp_config_write_peer_damp(vty, peer, afi, safi); From debe0f528ceb11b2bb2bc4a9fe080cecb6f23554 Mon Sep 17 00:00:00 2001 From: sudhanshukumar22 Date: Mon, 2 Nov 2020 22:36:31 -0800 Subject: [PATCH 046/472] bgpd: clear ip bgp dampening was not triggering the route calculation for the prefix Description: clear ip bgp dampening was not triggering the route calculation for the prefix, Due to this prefix are not install in RIB(Zebra) and not adv to neighbor Problem Description/Summary : clear ip bgp dampening was not triggering the route calculation for the prefix, Due to this prefix are not install in RIB(Zebra) and not adv to neighbor Fix: When clear ip bgp dampening, route are put for route-calculation as that it is install in the Zebra and adv to neighbor. Signed-off-by: sudhanshukumar22 --- bgpd/bgp_damp.c | 14 +++++++++++--- bgpd/bgp_damp.h | 4 ++-- bgpd/bgp_route.c | 17 ++++++++++++++++- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 123876ed5e6a..c9aa4fff25e2 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -533,7 +533,8 @@ int bgp_damp_enable(struct bgp *bgp, afi_t afi, safi_t safi, time_t half, } /* Clean all the bgp_damp_info stored in reuse_list and no_reuse_list. */ -void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, safi_t safi) +void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, + afi_t afi, safi_t safi) { struct bgp_damp_info *bdi; struct reuselist_node *rn; @@ -545,6 +546,13 @@ void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, safi_t safi) list = &bdc->reuse_list[i]; while ((rn = SLIST_FIRST(list)) != NULL) { bdi = rn->info; + if (bdi->lastrecord == BGP_RECORD_UPDATE) { + bgp_aggregate_increment(bgp, &bdi->dest->p, + bdi->path, bdi->afi, + bdi->safi); + bgp_process(bgp, bdi->dest, bdi->afi, + bdi->safi); + } bgp_reuselist_del(list, &rn); bgp_damp_info_free(&bdi, bdc, 1, afi, safi); } @@ -595,7 +603,7 @@ int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi) EVENT_OFF(bdc->t_reuse); /* Clean BGP dampening information. */ - bgp_damp_info_clean(bdc, afi, safi); + bgp_damp_info_clean(bgp, bdc, afi, safi); UNSET_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING); @@ -910,7 +918,7 @@ void bgp_peer_damp_disable(struct peer *peer, afi_t afi, safi_t safi) bdc = &peer->damp[afi][safi]; if (!bdc) return; - bgp_damp_info_clean(bdc, afi, safi); + bgp_damp_info_clean(peer->bgp, bdc, afi, safi); UNSET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_CONFIG_DAMPENING); } diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index 0e99d21d6206..ae057a01f7f3 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -136,8 +136,8 @@ extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, extern void bgp_damp_info_free(struct bgp_damp_info **path, struct bgp_damp_config *bdc, int withdraw, afi_t afi, safi_t safi); -extern void bgp_damp_info_clean(struct bgp_damp_config *bdc, afi_t afi, - safi_t safi); +extern void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, + afi_t afi, safi_t safi); extern void bgp_damp_config_clean(struct bgp_damp_config *bdc); extern int bgp_damp_decay(time_t tdiff, int penalty, struct bgp_damp_config *bdc); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 2e7faa57c26a..81a99604efe2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -15848,6 +15848,21 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, while (pi) { if (pi->extra && pi->extra->damp_info) { pi_temp = pi->next; + struct bgp_damp_info *bdi = + pi->extra->damp_info; + if (bdi->lastrecord + == BGP_RECORD_UPDATE) { + bgp_aggregate_increment( + bgp, + &bdi->dest->p, + bdi->path, + bdi->afi, + bdi->safi); + bgp_process(bgp, + bdi->dest, + bdi->afi, + bdi->safi); + } bgp_damp_info_free( &pi->extra->damp_info, &bgp->damp[afi][safi], @@ -15874,7 +15889,7 @@ DEFUN (clear_ip_bgp_dampening, "Clear route flap dampening information\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); - bgp_damp_info_clean(&bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP, + bgp_damp_info_clean(bgp, &bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP, SAFI_UNICAST); return CMD_SUCCESS; } From 6b3486be116e68bcb386869198fc8d13cebfd8eb Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 11 Jun 2021 18:09:05 +0300 Subject: [PATCH 047/472] bgpd: Remove useless reuselist_node assignment before while loop Seems really not necessary pointing to initial value before while loop, where it's assigned anyway. Signed-off-by: Donatas Abraitis --- bgpd/bgp_damp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index c9aa4fff25e2..40fe5b8b5910 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -229,7 +229,6 @@ static void bgp_reuse_timer(struct event *t) * list head entry. */ assert(bdc->reuse_offset < bdc->reuse_list_size); plist = bdc->reuse_list[bdc->reuse_offset]; - node = SLIST_FIRST(&plist); SLIST_INIT(&bdc->reuse_list[bdc->reuse_offset]); /* 2. set offset = modulo reuse-list-size ( offset + 1 ), thereby From a1e49ec2c9edf4e4d2fc235c6f16657208d46654 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 29 Jul 2021 00:14:31 +0300 Subject: [PATCH 048/472] bgpd: fix double free in dampening code bgp_damp_info_unclaim already calls bgp_reuselist_del. We must not call it again here. Fixes #9046. Signed-off-by: Igor Ryzhov --- bgpd/bgp_damp.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 40fe5b8b5910..08859324af11 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -157,16 +157,9 @@ static void bgp_reuse_list_add(struct bgp_damp_info *bdi, } /* Delete BGP dampening information from reuse list. */ -static void bgp_reuse_list_delete(struct bgp_damp_info *bdi, - struct bgp_damp_config *bdc) +static void bgp_reuse_list_delete(struct bgp_damp_info *bdi) { - struct reuselist *list; - struct reuselist_node *rn; - - list = &bdc->reuse_list[bdi->index]; - rn = bgp_reuselist_find(list, bdi); bgp_damp_info_unclaim(bdi); - bgp_reuselist_del(list, &rn); } static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi, @@ -358,7 +351,7 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED)) { /* If decay rate isn't equal to 0, reinsert brn. */ if (bdi->penalty != last_penalty) { - bgp_reuse_list_delete(bdi, bdc); + bgp_reuse_list_delete(bdi); bgp_reuse_list_add(bdi, bdc); } return BGP_DAMP_SUPPRESSED; @@ -402,7 +395,7 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, else if (CHECK_FLAG(bdi->path->flags, BGP_PATH_DAMPED) && (bdi->penalty < bdc->reuse_limit)) { bgp_path_info_unset_flag(dest, path, BGP_PATH_DAMPED); - bgp_reuse_list_delete(bdi, bdc); + bgp_reuse_list_delete(bdi); bgp_no_reuse_list_add(bdi, bdc); bdi->suppress_time = 0; status = BGP_DAMP_USED; From 391b4fa7a657a34e6bba1ed70d8e7847bbdeb384 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 30 Apr 2024 10:52:46 +0300 Subject: [PATCH 049/472] bgpd: Drop double-pointer for bgp_damp_info_free() This causes a crash using `clear ip bgp dampening `. Signed-off-by: Donatas Abraitis Signed-off-by: Donatas Abraitis --- bgpd/bgp_damp.c | 32 +++++++++++++++++--------------- bgpd/bgp_damp.h | 2 +- bgpd/bgp_route.c | 8 +++++--- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 08859324af11..20d80eb5dbb6 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -262,7 +262,7 @@ static void bgp_reuse_timer(struct event *t) } if (bdi->penalty <= bdc->reuse_limit / 2.0) { - bgp_damp_info_free(&bdi, bdc, 1, bdi->afi, + bgp_damp_info_free(bdi, bdc, 1, bdi->afi, bdi->safi); bgp_reuselist_del(&plist, &node); } else { @@ -406,29 +406,29 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, bdi->t_updated = t_now; else { bgp_damp_info_unclaim(bdi); - bgp_damp_info_free(&bdi, bdc, 0, afi, safi); + bgp_damp_info_free(bdi, bdc, 0, afi, safi); } return status; } -void bgp_damp_info_free(struct bgp_damp_info **bdi, struct bgp_damp_config *bdc, +void bgp_damp_info_free(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc, int withdraw, afi_t afi, safi_t safi) { - assert(bdc && bdi && *bdi); + assert(bdc && bdi); - if ((*bdi)->path == NULL) { - XFREE(MTYPE_BGP_DAMP_INFO, (*bdi)); + if (bdi->path == NULL) { + XFREE(MTYPE_BGP_DAMP_INFO, bdi); return; } - (*bdi)->path->extra->damp_info = NULL; - bgp_path_info_unset_flag((*bdi)->dest, (*bdi)->path, + bdi->path->extra->damp_info = NULL; + bgp_path_info_unset_flag(bdi->dest, bdi->path, BGP_PATH_HISTORY | BGP_PATH_DAMPED); - if ((*bdi)->lastrecord == BGP_RECORD_WITHDRAW && withdraw) { - bgp_path_info_delete((*bdi)->dest, (*bdi)->path); - bgp_process((*bdi)->path->peer->bgp, (*bdi)->dest, (*bdi)->path, afi, safi); + if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) { + bgp_path_info_delete(bdi->dest, bdi->path); + bgp_process(bdi->path->peer->bgp, bdi->dest, bdi->path, afi, safi); } XFREE(MTYPE_BGP_DAMP_INFO, bdi); @@ -539,21 +539,23 @@ void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, while ((rn = SLIST_FIRST(list)) != NULL) { bdi = rn->info; if (bdi->lastrecord == BGP_RECORD_UPDATE) { - bgp_aggregate_increment(bgp, &bdi->dest->p, + bgp_aggregate_increment(bgp, + bgp_dest_get_prefix( + bdi->dest), bdi->path, bdi->afi, bdi->safi); - bgp_process(bgp, bdi->dest, bdi->afi, + bgp_process(bgp, bdi->dest, bdi->path, bdi->afi, bdi->safi); } bgp_reuselist_del(list, &rn); - bgp_damp_info_free(&bdi, bdc, 1, afi, safi); + bgp_damp_info_free(bdi, bdc, 1, afi, safi); } } while ((rn = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) { bdi = rn->info; bgp_reuselist_del(&bdc->no_reuse_list, &rn); - bgp_damp_info_free(&bdi, bdc, 1, afi, safi); + bgp_damp_info_free(bdi, bdc, 1, afi, safi); } /* Free decay array */ diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index ae057a01f7f3..22b2efebbca0 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -133,7 +133,7 @@ extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t safi, int attr_change); extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t saff); -extern void bgp_damp_info_free(struct bgp_damp_info **path, +extern void bgp_damp_info_free(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc, int withdraw, afi_t afi, safi_t safi); extern void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 81a99604efe2..ee255b59b837 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -15826,7 +15826,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, if (pi->extra && pi->extra->damp_info) { pi_temp = pi->next; bgp_damp_info_free( - &pi->extra->damp_info, + pi->extra->damp_info, &bgp->damp[afi][safi], 1, afi, safi); pi = pi_temp; @@ -15854,17 +15854,19 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, == BGP_RECORD_UPDATE) { bgp_aggregate_increment( bgp, - &bdi->dest->p, + bgp_dest_get_prefix( + bdi->dest), bdi->path, bdi->afi, bdi->safi); bgp_process(bgp, bdi->dest, + bdi->path, bdi->afi, bdi->safi); } bgp_damp_info_free( - &pi->extra->damp_info, + pi->extra->damp_info, &bgp->damp[afi][safi], 1, afi, safi); pi = pi_temp; From 4c500d6952ea597eb7422358e18788547eed92a6 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 29 Jul 2021 14:42:16 +0300 Subject: [PATCH 050/472] bgpd: fix missing list add in dampening One more crash in dampening code... When bgp_damp_withdraw is called, if there's already a BDI structure, bgp_damp_info_claim is called to re-assign the bdi->config in case it was changed. The problem is that bgp_damp_info_claim actually removes the BDI from the reuse list of the old config and never adds it to the reuse list of the new config. We must do this to prevent the crash because all the code assumes that BDI is always in some list. Signed-off-by: Igor Ryzhov --- bgpd/bgp_damp.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 20d80eb5dbb6..0c75f67a89d3 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -324,7 +324,14 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, (bgp_path_info_extra_get(path))->damp_info = bdi; bgp_no_reuse_list_add(bdi, bdc); } else { - bgp_damp_info_claim(bdi, bdc); + if (bdi->config != bdc) { + bgp_damp_info_claim(bdi, bdc); + if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) + bgp_reuselist_add(&bdc->no_reuse_list, bdi); + else + bgp_reuselist_add(&bdc->reuse_list[bdi->index], + bdi); + } last_penalty = bdi->penalty; /* 1. Set t-diff = t-now - t-updated. */ From 1d37871588b82ae17ee4c512c293ac87904883d6 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 29 Jul 2021 01:17:50 +0300 Subject: [PATCH 051/472] bgpd: fix incorrect usage of slist in dampening Current code is a complete misuse of SLIST structure. Instead of just adding a SLIST_ENTRY to struct bgp_damp_info, it allocates a separate structure to be a node in the list. Signed-off-by: Igor Ryzhov --- bgpd/bgp_damp.c | 108 +++++++++++------------------------------------- bgpd/bgp_damp.h | 7 +--- 2 files changed, 26 insertions(+), 89 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 0c75f67a89d3..34616ce9ca09 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -24,72 +24,32 @@ static void bgp_reuselist_add(struct reuselist *list, struct bgp_damp_info *info) { - struct reuselist_node *new_node; - assert(info); - new_node = XCALLOC(MTYPE_BGP_DAMP_REUSELIST, sizeof(*new_node)); - new_node->info = info; - SLIST_INSERT_HEAD(list, new_node, entry); + SLIST_INSERT_HEAD(list, info, entry); } -static void bgp_reuselist_del(struct reuselist *list, - struct reuselist_node **node) +static void bgp_reuselist_del(struct reuselist *list, struct bgp_damp_info *info) { - if ((*node) == NULL) - return; - assert(list && node && *node); - SLIST_REMOVE(list, (*node), reuselist_node, entry); - XFREE(MTYPE_BGP_DAMP_REUSELIST, (*node)); - *node = NULL; + assert(info); + SLIST_REMOVE(list, info, bgp_damp_info, entry); } static void bgp_reuselist_switch(struct reuselist *source, - struct reuselist_node *node, + struct bgp_damp_info *info, struct reuselist *target) { - assert(source && target && node); - SLIST_REMOVE(source, node, reuselist_node, entry); - SLIST_INSERT_HEAD(target, node, entry); -} - -static void bgp_reuselist_free(struct reuselist *list) -{ - struct reuselist_node *rn; - - assert(list); - while ((rn = SLIST_FIRST(list)) != NULL) - bgp_reuselist_del(list, &rn); -} - -static struct reuselist_node *bgp_reuselist_find(struct reuselist *list, - struct bgp_damp_info *info) -{ - struct reuselist_node *rn; - - assert(list && info); - SLIST_FOREACH (rn, list, entry) { - if (rn->info == info) - return rn; - } - return NULL; + assert(source && target && info); + SLIST_REMOVE(source, info, bgp_damp_info, entry); + SLIST_INSERT_HEAD(target, info, entry); } static void bgp_damp_info_unclaim(struct bgp_damp_info *bdi) { - struct reuselist_node *node; - assert(bdi && bdi->config); - if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) { - node = bgp_reuselist_find(&bdi->config->no_reuse_list, bdi); - if (node) - bgp_reuselist_del(&bdi->config->no_reuse_list, &node); - } else { - node = bgp_reuselist_find(&bdi->config->reuse_list[bdi->index], - bdi); - if (node) - bgp_reuselist_del(&bdi->config->reuse_list[bdi->index], - &node); - } + if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) + bgp_reuselist_del(&bdi->config->no_reuse_list, bdi); + else + bgp_reuselist_del(&bdi->config->reuse_list[bdi->index], bdi); bdi->config = NULL; } @@ -170,19 +130,9 @@ static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi, bgp_reuselist_add(&bdc->no_reuse_list, bdi); } -static void bgp_no_reuse_list_delete(struct bgp_damp_info *bdi, - struct bgp_damp_config *bdc) +static void bgp_no_reuse_list_delete(struct bgp_damp_info *bdi) { - struct reuselist_node *rn; - - assert(bdc && bdi); - if (bdi->config == NULL) { - bgp_damp_info_unclaim(bdi); - return; - } - bdi->config = NULL; - rn = bgp_reuselist_find(&bdc->no_reuse_list, bdi); - bgp_reuselist_del(&bdc->no_reuse_list, &rn); + bgp_damp_info_unclaim(bdi); } /* Return decayed penalty value. */ @@ -207,7 +157,6 @@ static void bgp_reuse_timer(struct event *t) { struct bgp_damp_info *bdi; struct reuselist plist; - struct reuselist_node *node; struct bgp *bgp; time_t t_now, t_diff; struct bgp_damp_config *bdc = EVENT_ARG(t); @@ -230,8 +179,7 @@ static void bgp_reuse_timer(struct event *t) assert(bdc->reuse_offset < bdc->reuse_list_size); /* 3. if ( the saved list head pointer is non-empty ) */ - while ((node = SLIST_FIRST(&plist)) != NULL) { - bdi = node->info; + while ((bdi = SLIST_FIRST(&plist)) != NULL) { bgp = bdi->path->peer->bgp; /* Set t-diff = t-now - t-updated. */ @@ -262,20 +210,19 @@ static void bgp_reuse_timer(struct event *t) } if (bdi->penalty <= bdc->reuse_limit / 2.0) { + bgp_reuselist_del(&plist, bdi); bgp_damp_info_free(bdi, bdc, 1, bdi->afi, bdi->safi); - bgp_reuselist_del(&plist, &node); } else { - node->info->index = - BGP_DAMP_NO_REUSE_LIST_INDEX; - bgp_reuselist_switch(&plist, node, + bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX; + bgp_reuselist_switch(&plist, bdi, &bdc->no_reuse_list); } } else { /* Re-insert into another list (See RFC2439 Section * 4.8.6). */ bdi->index = bgp_reuse_index(bdi->penalty, bdc); - bgp_reuselist_switch(&plist, node, + bgp_reuselist_switch(&plist, bdi, &bdc->reuse_list[bdi->index]); } } @@ -369,7 +316,7 @@ int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, if (bdi->penalty >= bdc->suppress_value) { bgp_path_info_set_flag(dest, path, BGP_PATH_DAMPED); bdi->suppress_time = t_now; - bgp_no_reuse_list_delete(bdi, bdc); + bgp_no_reuse_list_delete(bdi); bgp_reuse_list_add(bdi, bdc); } return BGP_DAMP_USED; @@ -536,15 +483,13 @@ void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, afi_t afi, safi_t safi) { struct bgp_damp_info *bdi; - struct reuselist_node *rn; struct reuselist *list; unsigned int i; bdc->reuse_offset = 0; for (i = 0; i < bdc->reuse_list_size; ++i) { list = &bdc->reuse_list[i]; - while ((rn = SLIST_FIRST(list)) != NULL) { - bdi = rn->info; + while ((bdi = SLIST_FIRST(list)) != NULL) { if (bdi->lastrecord == BGP_RECORD_UPDATE) { bgp_aggregate_increment(bgp, bgp_dest_get_prefix( @@ -554,14 +499,13 @@ void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, bgp_process(bgp, bdi->dest, bdi->path, bdi->afi, bdi->safi); } - bgp_reuselist_del(list, &rn); + bgp_reuselist_del(list, bdi); bgp_damp_info_free(bdi, bdc, 1, afi, safi); } } - while ((rn = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) { - bdi = rn->info; - bgp_reuselist_del(&bdc->no_reuse_list, &rn); + while ((bdi = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) { + bgp_reuselist_del(&bdc->no_reuse_list, bdi); bgp_damp_info_free(bdi, bdc, 1, afi, safi); } @@ -573,10 +517,6 @@ void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_index); bdc->reuse_index_size = 0; - /* Free reuse list array. */ - for (i = 0; i < bdc->reuse_list_size; ++i) - bgp_reuselist_free(&bdc->reuse_list[i]); - XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->reuse_list); bdc->reuse_list_size = 0; diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index 22b2efebbca0..ce3cb878370f 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -46,14 +46,11 @@ struct bgp_damp_info { afi_t afi; safi_t safi; -}; -struct reuselist_node { - SLIST_ENTRY(reuselist_node) entry; - struct bgp_damp_info *info; + SLIST_ENTRY(bgp_damp_info) entry; }; -SLIST_HEAD(reuselist, reuselist_node); +SLIST_HEAD(reuselist, bgp_damp_info); /* Specified parameter set configuration. */ struct bgp_damp_config { From ad97cd00a69e564ba25eff4c03bf65aadc4af78d Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Tue, 30 Apr 2024 10:56:33 +0300 Subject: [PATCH 052/472] bgpd: cleanup bgp_damp_info_free bgp_damp_config, afi and safi are never used. Signed-off-by: Igor Ryzhov Signed-off-by: Donatas Abraitis --- bgpd/bgp_damp.c | 18 +++++++----------- bgpd/bgp_damp.h | 4 +--- bgpd/bgp_route.c | 6 ++---- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 34616ce9ca09..cbeb2275a7fa 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -211,8 +211,7 @@ static void bgp_reuse_timer(struct event *t) if (bdi->penalty <= bdc->reuse_limit / 2.0) { bgp_reuselist_del(&plist, bdi); - bgp_damp_info_free(bdi, bdc, 1, bdi->afi, - bdi->safi); + bgp_damp_info_free(bdi, 1); } else { bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX; bgp_reuselist_switch(&plist, bdi, @@ -360,16 +359,15 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, bdi->t_updated = t_now; else { bgp_damp_info_unclaim(bdi); - bgp_damp_info_free(bdi, bdc, 0, afi, safi); + bgp_damp_info_free(bdi, 0); } return status; } -void bgp_damp_info_free(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc, - int withdraw, afi_t afi, safi_t safi) +void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw) { - assert(bdc && bdi); + assert(bdi); if (bdi->path == NULL) { XFREE(MTYPE_BGP_DAMP_INFO, bdi); @@ -380,10 +378,8 @@ void bgp_damp_info_free(struct bgp_damp_info *bdi, struct bgp_damp_config *bdc, bgp_path_info_unset_flag(bdi->dest, bdi->path, BGP_PATH_HISTORY | BGP_PATH_DAMPED); - if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) { + if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) bgp_path_info_delete(bdi->dest, bdi->path); - bgp_process(bdi->path->peer->bgp, bdi->dest, bdi->path, afi, safi); - } XFREE(MTYPE_BGP_DAMP_INFO, bdi); } @@ -500,13 +496,13 @@ void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, bdi->safi); } bgp_reuselist_del(list, bdi); - bgp_damp_info_free(bdi, bdc, 1, afi, safi); + bgp_damp_info_free(bdi, 1); } } while ((bdi = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) { bgp_reuselist_del(&bdc->no_reuse_list, bdi); - bgp_damp_info_free(bdi, bdc, 1, afi, safi); + bgp_damp_info_free(bdi, 1); } /* Free decay array */ diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index ce3cb878370f..2578e25954a4 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -130,9 +130,7 @@ extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t safi, int attr_change); extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t saff); -extern void bgp_damp_info_free(struct bgp_damp_info *bdi, - struct bgp_damp_config *bdc, int withdraw, - afi_t afi, safi_t safi); +extern void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw); extern void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, afi_t afi, safi_t safi); extern void bgp_damp_config_clean(struct bgp_damp_config *bdc); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ee255b59b837..fcf7216ce156 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -15827,8 +15827,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, pi_temp = pi->next; bgp_damp_info_free( pi->extra->damp_info, - &bgp->damp[afi][safi], - 1, afi, safi); + 1); pi = pi_temp; } else pi = pi->next; @@ -15867,8 +15866,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, } bgp_damp_info_free( pi->extra->damp_info, - &bgp->damp[afi][safi], - 1, afi, safi); + 1); pi = pi_temp; } else pi = pi->next; From 471e373c17fa8cf1e7e4a2f08bbd977b125cccd9 Mon Sep 17 00:00:00 2001 From: Igor Ryzhov Date: Thu, 29 Jul 2021 01:54:03 +0300 Subject: [PATCH 053/472] bgpd: fix missing damp info free when cleaning bgp path Signed-off-by: Igor Ryzhov --- bgpd/bgp_route.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index fcf7216ce156..9697245eeaab 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -250,6 +250,8 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) e = *extra; + if (e->damp_info) + bgp_damp_info_free(e->damp_info, 0); e->damp_info = NULL; if (e->vrfleak && e->vrfleak->parent) { struct bgp_path_info *bpi = From f8e6b7ce450f494c88fdddbd8822673579b6d9b4 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 24 Apr 2024 16:42:08 +0300 Subject: [PATCH 054/472] bgpd: Use SLIST_FOREACH_SAFE when iterating over the list in bgp_reuse_timer Signed-off-by: Donatas Abraitis --- bgpd/bgp_damp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index cbeb2275a7fa..ddf7e0db8f5a 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -155,7 +155,7 @@ int bgp_damp_decay(time_t tdiff, int penalty, struct bgp_damp_config *bdc) is evaluated. RFC2439 Section 4.8.7. */ static void bgp_reuse_timer(struct event *t) { - struct bgp_damp_info *bdi; + struct bgp_damp_info *bdi, *bdi_next; struct reuselist plist; struct bgp *bgp; time_t t_now, t_diff; @@ -179,7 +179,7 @@ static void bgp_reuse_timer(struct event *t) assert(bdc->reuse_offset < bdc->reuse_list_size); /* 3. if ( the saved list head pointer is non-empty ) */ - while ((bdi = SLIST_FIRST(&plist)) != NULL) { + SLIST_FOREACH_SAFE (bdi, &plist, entry, bdi_next) { bgp = bdi->path->peer->bgp; /* Set t-diff = t-now - t-updated. */ From 70ac630b399a007ae396eab42217d98638162a71 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 24 Apr 2024 16:59:25 +0300 Subject: [PATCH 055/472] bgpd: Pass the right reuse_list when handling it via bgp_reuse_timer thread This fixes the crash: ``` ==14759== Invalid read of size 8 ==14759== at 0x31032B: bgp_reuselist_del (bgp_damp.c:51) ==14759== by 0x310392: bgp_damp_info_unclaim (bgp_damp.c:69) ==14759== by 0x310CD6: bgp_damp_info_free (bgp_damp.c:387) ==14759== by 0x311016: bgp_reuse_timer (bgp_damp.c:230) ==14759== by 0x4F227CC: thread_call (thread.c:2008) ==14759== by 0x4EDB7D7: frr_run (libfrr.c:1216) ==14759== by 0x1EF748: main (bgp_main.c:525) ==14759== Address 0x48 is not stack'd, malloc'd or (recently) free'd ==14759== ==14759== ==14759== Process terminating with default action of signal 11 (SIGSEGV) ==14759== at 0x59CC7F5: raise (raise.c:46) ==14759== by 0x4F10CEB: core_handler (sigevent.c:261) ==14759== by 0x59CC97F: ??? (in /lib/x86_64-linux-gnu/libpthread-2.27.so) ==14759== by 0x31032A: bgp_reuselist_del (bgp_damp.c:51) ==14759== by 0x310392: bgp_damp_info_unclaim (bgp_damp.c:69) ==14759== by 0x310CD6: bgp_damp_info_free (bgp_damp.c:387) ==14759== by 0x311016: bgp_reuse_timer (bgp_damp.c:230) ==14759== by 0x4F227CC: thread_call (thread.c:2008) ==14759== by 0x4EDB7D7: frr_run (libfrr.c:1216) ==14759== by 0x1EF748: main (bgp_main.c:525) ``` Signed-off-by: Donatas Abraitis --- bgpd/bgp_damp.c | 39 +++++++++++++++++---------------------- bgpd/bgp_damp.h | 3 ++- bgpd/bgp_route.c | 12 +++++------- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index ddf7e0db8f5a..6b9b12dd4d6a 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -43,13 +43,16 @@ static void bgp_reuselist_switch(struct reuselist *source, SLIST_INSERT_HEAD(target, info, entry); } -static void bgp_damp_info_unclaim(struct bgp_damp_info *bdi) +static void bgp_damp_info_unclaim(struct bgp_damp_info *bdi, + struct reuselist *list) { assert(bdi && bdi->config); if (bdi->index == BGP_DAMP_NO_REUSE_LIST_INDEX) bgp_reuselist_del(&bdi->config->no_reuse_list, bdi); else - bgp_reuselist_del(&bdi->config->reuse_list[bdi->index], bdi); + bgp_reuselist_del(list ? list + : &bdi->config->reuse_list[bdi->index], + bdi); bdi->config = NULL; } @@ -61,7 +64,7 @@ static void bgp_damp_info_claim(struct bgp_damp_info *bdi, bdi->config = bdc; return; } - bgp_damp_info_unclaim(bdi); + bgp_damp_info_unclaim(bdi, NULL); bdi->config = bdc; bdi->afi = bdc->afi; bdi->safi = bdc->safi; @@ -119,7 +122,7 @@ static void bgp_reuse_list_add(struct bgp_damp_info *bdi, /* Delete BGP dampening information from reuse list. */ static void bgp_reuse_list_delete(struct bgp_damp_info *bdi) { - bgp_damp_info_unclaim(bdi); + bgp_damp_info_unclaim(bdi, NULL); } static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi, @@ -132,7 +135,7 @@ static void bgp_no_reuse_list_add(struct bgp_damp_info *bdi, static void bgp_no_reuse_list_delete(struct bgp_damp_info *bdi) { - bgp_damp_info_unclaim(bdi); + bgp_damp_info_unclaim(bdi, NULL); } /* Return decayed penalty value. */ @@ -210,8 +213,7 @@ static void bgp_reuse_timer(struct event *t) } if (bdi->penalty <= bdc->reuse_limit / 2.0) { - bgp_reuselist_del(&plist, bdi); - bgp_damp_info_free(bdi, 1); + bgp_damp_info_free(bdi, &plist, 1); } else { bdi->index = BGP_DAMP_NO_REUSE_LIST_INDEX; bgp_reuselist_switch(&plist, bdi, @@ -357,22 +359,18 @@ int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, if (bdi->penalty > bdc->reuse_limit / 2.0) bdi->t_updated = t_now; - else { - bgp_damp_info_unclaim(bdi); - bgp_damp_info_free(bdi, 0); - } + else + bgp_damp_info_free(bdi, NULL, 0); return status; } -void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw) +void bgp_damp_info_free(struct bgp_damp_info *bdi, struct reuselist *list, + int withdraw) { assert(bdi); - if (bdi->path == NULL) { - XFREE(MTYPE_BGP_DAMP_INFO, bdi); - return; - } + bgp_damp_info_unclaim(bdi, list); bdi->path->extra->damp_info = NULL; bgp_path_info_unset_flag(bdi->dest, bdi->path, @@ -495,15 +493,12 @@ void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, bgp_process(bgp, bdi->dest, bdi->path, bdi->afi, bdi->safi); } - bgp_reuselist_del(list, bdi); - bgp_damp_info_free(bdi, 1); + bgp_damp_info_free(bdi, list, 1); } } - while ((bdi = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) { - bgp_reuselist_del(&bdc->no_reuse_list, bdi); - bgp_damp_info_free(bdi, 1); - } + while ((bdi = SLIST_FIRST(&bdc->no_reuse_list)) != NULL) + bgp_damp_info_free(bdi, &bdc->no_reuse_list, 1); /* Free decay array */ XFREE(MTYPE_BGP_DAMP_ARRAY, bdc->decay_array); diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index 2578e25954a4..851c6f9e8548 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -130,7 +130,8 @@ extern int bgp_damp_withdraw(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t safi, int attr_change); extern int bgp_damp_update(struct bgp_path_info *path, struct bgp_dest *dest, afi_t afi, safi_t saff); -extern void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw); +extern void bgp_damp_info_free(struct bgp_damp_info *bdi, + struct reuselist *list, int withdraw); extern void bgp_damp_info_clean(struct bgp *bgp, struct bgp_damp_config *bdc, afi_t afi, safi_t safi); extern void bgp_damp_config_clean(struct bgp_damp_config *bdc); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 9697245eeaab..5022ba36abe0 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -251,7 +251,7 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) e = *extra; if (e->damp_info) - bgp_damp_info_free(e->damp_info, 0); + bgp_damp_info_free(e->damp_info, NULL, 0); e->damp_info = NULL; if (e->vrfleak && e->vrfleak->parent) { struct bgp_path_info *bpi = @@ -15827,9 +15827,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, while (pi) { if (pi->extra && pi->extra->damp_info) { pi_temp = pi->next; - bgp_damp_info_free( - pi->extra->damp_info, - 1); + bgp_damp_info_free(pi->extra->damp_info, + NULL, 1); pi = pi_temp; } else pi = pi->next; @@ -15866,9 +15865,8 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, bdi->afi, bdi->safi); } - bgp_damp_info_free( - pi->extra->damp_info, - 1); + bgp_damp_info_free(pi->extra->damp_info, + NULL, 1); pi = pi_temp; } else pi = pi->next; From 3921324346dae6665744fa854a082d1ce74fee32 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 24 Apr 2024 17:13:48 +0300 Subject: [PATCH 056/472] bgpd: Put dest into work queue when the path is really withdrawn by dampening Signed-off-by: Donatas Abraitis --- bgpd/bgp_damp.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 6b9b12dd4d6a..339bfae56d4c 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -370,14 +370,22 @@ void bgp_damp_info_free(struct bgp_damp_info *bdi, struct reuselist *list, { assert(bdi); - bgp_damp_info_unclaim(bdi, list); + afi_t afi = bdi->afi; + safi_t safi = bdi->safi; + struct bgp_path_info *bpi = bdi->path; + struct bgp_dest *dest = bdi->dest; + struct bgp *bgp = bpi->peer->bgp; + const struct prefix *p = bgp_dest_get_prefix(bdi->dest); - bdi->path->extra->damp_info = NULL; - bgp_path_info_unset_flag(bdi->dest, bdi->path, - BGP_PATH_HISTORY | BGP_PATH_DAMPED); + bgp_damp_info_unclaim(bdi, list); - if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) - bgp_path_info_delete(bdi->dest, bdi->path); + bpi->extra->damp_info = NULL; + bgp_path_info_unset_flag(dest, bpi, BGP_PATH_HISTORY | BGP_PATH_DAMPED); + if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) { + bgp_aggregate_decrement(bgp, p, bpi, afi, SAFI_UNICAST); + bgp_path_info_delete(dest, bpi); + bgp_process(bgp, dest, bpi, afi, safi); + } XFREE(MTYPE_BGP_DAMP_INFO, bdi); } From b07a21dd1a76f752d485b38a9a99cc7081768793 Mon Sep 17 00:00:00 2001 From: David Schweizer Date: Tue, 30 Apr 2024 11:15:40 +0300 Subject: [PATCH 057/472] doc: user doc for route-flap dampening commands Changes update the user documentation to include a description of the now available commands to enable/disable route-flap dampening for peers and peer groups. Signed-off-by: David Schweizer Signed-off-by: Donatas Abraitis --- doc/user/bgp.rst | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 1de677392295..ae342e4c1359 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -589,26 +589,52 @@ Route Flap Dampening .. clicmd:: bgp dampening (1-45) (1-20000) (1-50000) (1-255) - This command enables BGP route-flap dampening and specifies dampening parameters. + This command enables (with optionally specified dampening parameters) or + disables route-flap dampening for all routes of a BGP instance. + +.. clicmd:: neighbor PEER dampening [(1-45) [(1-20000) (1-20000) (1-255)]] + + This command enables (with optionally specified dampening parameters) or + disables route-flap dampening for all routes learned from a BGP peer. + +.. clicmd:: neighbor GROUP dampening [(1-45) [(1-20000) (1-20000) (1-255)]] + + This command enables (with optionally specified dampening parameters) or + disables route-flap dampening for all routes learned from peers of a peer + group. half-life - Half-life time for the penalty + Half-life time for the penalty in minutes (default value: 15). reuse-threshold - Value to start reusing a route + Value to start reusing a route (default value: 750). suppress-threshold - Value to start suppressing a route + Value to start suppressing a route (default value: 2000). max-suppress - Maximum duration to suppress a stable route + Maximum duration to suppress a stable route in minutes (default value: + 60). The route-flap damping algorithm is compatible with :rfc:`2439`. The use of - this command is not recommended nowadays. + these commands is not recommended nowadays. At the moment, route-flap dampening is not working per VRF and is working only for IPv4 unicast and multicast. + With different parameter sets configurable for BGP instances, peer groups and + peers, the active dampening profile for a route is chosen on the fly, + allowing for various changes in configuration (i.e. peer group memberships) + during runtime. The parameter sets are taking precedence in the following + order: + + 1. Peer + 2. Peer group + 3. BGP instance + + The negating commands do not allow to exclude a peer/peer group from a peer + group/BGP instances configuration. + .. seealso:: https://www.ripe.net/publications/docs/ripe-378 @@ -1335,7 +1361,7 @@ OSPFv3 into ``address-family ipv4 unicast`` as OSPFv3 supports IPv6. .. clicmd:: redistribute [metric (0-4294967295)] [route-map WORD] Redistribute routes from other protocols into BGP. - + Note - When redistributing a static route, or any better Admin Distance route, into BGP for which the same path is learned dynamically from another BGP speaker, if the redistribute path is more preferred from a BGP Best Path From 709bdcbb230a52d12822f605c8847439d05dd615 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 30 Apr 2024 12:14:23 +0300 Subject: [PATCH 058/472] tests: Check if dampening per-peer works Signed-off-by: Donatas Abraitis --- .../bgp_dampening_per_peer/__init__.py | 0 .../bgp_dampening_per_peer/r1/frr.conf | 15 ++ .../bgp_dampening_per_peer/r2/frr.conf | 17 ++ .../test_bgp_dampening_per_peer.py | 177 ++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 tests/topotests/bgp_dampening_per_peer/__init__.py create mode 100644 tests/topotests/bgp_dampening_per_peer/r1/frr.conf create mode 100644 tests/topotests/bgp_dampening_per_peer/r2/frr.conf create mode 100644 tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py diff --git a/tests/topotests/bgp_dampening_per_peer/__init__.py b/tests/topotests/bgp_dampening_per_peer/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_dampening_per_peer/r1/frr.conf b/tests/topotests/bgp_dampening_per_peer/r1/frr.conf new file mode 100644 index 000000000000..45899559cdad --- /dev/null +++ b/tests/topotests/bgp_dampening_per_peer/r1/frr.conf @@ -0,0 +1,15 @@ +! +int r1-eth0 + ip address 192.168.1.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as external + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + neighbor 192.168.1.2 capability dynamic + ! + address-family ipv4 unicast + neighbor 192.168.1.2 dampening 1 1 1 1 + exit-address-family +! diff --git a/tests/topotests/bgp_dampening_per_peer/r2/frr.conf b/tests/topotests/bgp_dampening_per_peer/r2/frr.conf new file mode 100644 index 000000000000..d68d13d07599 --- /dev/null +++ b/tests/topotests/bgp_dampening_per_peer/r2/frr.conf @@ -0,0 +1,17 @@ +! +int lo + ip address 10.10.10.10/32 +! +int r2-eth0 + ip address 192.168.1.2/24 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 + ! + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py b/tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py new file mode 100644 index 000000000000..2066d848d349 --- /dev/null +++ b/tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by +# Donatas Abraitis +# + +import os +import re +import sys +import json +import pytest +import functools + +pytestmark = [pytest.mark.bgpd] + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, get_topogen + + +def setup_module(mod): + topodef = {"s1": ("r1", "r2")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_dampening_per_peer(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge" + + #### + # Withdraw 10.10.10.10/32, and check if it's flagged as history. + #### + r2.vtysh_cmd( + """ + configure terminal + router bgp + address-family ipv4 unicast + no redistribute connected + """ + ) + + def _check_bgp_dampening_history(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "dampeningHistoryEntry": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _check_bgp_dampening_history, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "10.10.10.10/32 is not flagged as history entry" + + #### + # Reannounce 10.10.10.10/32, and check if it's flagged as dampened. + #### + r2.vtysh_cmd( + """ + configure terminal + router bgp + address-family ipv4 unicast + redistribute connected + """ + ) + + def _check_bgp_dampening_dampened(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "dampeningSuppressed": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _check_bgp_dampening_dampened, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "10.10.10.10/32 is not flagged as dampened entry" + + #### + # Check if the route becomes non-dampened again after some time. + #### + def _check_bgp_dampening_undampened(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "dampeningHistoryEntry": None, + "dampeningSuppressed": None, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _check_bgp_dampening_undampened, + ) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=10) + assert result is None, "10.10.10.10/32 is flagged as history/dampened" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From bf37877103d537b3b41fb7e32c6c8c465ab8a0eb Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 2 May 2024 22:48:19 +0300 Subject: [PATCH 059/472] bgpd: Reduce the nesting level for bgp_clear_damp_route() Signed-off-by: Donatas Abraitis --- bgpd/bgp_route.c | 60 ++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5022ba36abe0..8c24ff32b3b9 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -15839,42 +15839,38 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name, } } else { dest = bgp_node_match(bgp->rib[afi][safi], &match); - if (dest != NULL) { - const struct prefix *dest_p = bgp_dest_get_prefix(dest); + if (!dest) + return CMD_SUCCESS; - if (!prefix_check - || dest_p->prefixlen == match.prefixlen) { - pi = bgp_dest_get_bgp_path_info(dest); - while (pi) { - if (pi->extra && pi->extra->damp_info) { - pi_temp = pi->next; - struct bgp_damp_info *bdi = - pi->extra->damp_info; - if (bdi->lastrecord - == BGP_RECORD_UPDATE) { - bgp_aggregate_increment( - bgp, - bgp_dest_get_prefix( - bdi->dest), - bdi->path, - bdi->afi, - bdi->safi); - bgp_process(bgp, - bdi->dest, - bdi->path, - bdi->afi, - bdi->safi); - } - bgp_damp_info_free(pi->extra->damp_info, - NULL, 1); - pi = pi_temp; - } else - pi = pi->next; - } + const struct prefix *dest_p = bgp_dest_get_prefix(dest); + + if (prefix_check || dest_p->prefixlen != match.prefixlen) + return CMD_SUCCESS; + + pi = bgp_dest_get_bgp_path_info(dest); + while (pi) { + if (!(pi->extra && pi->extra->damp_info)) { + pi = pi->next; + continue; } - bgp_dest_unlock_node(dest); + pi_temp = pi->next; + struct bgp_damp_info *bdi = pi->extra->damp_info; + + if (bdi->lastrecord != BGP_RECORD_UPDATE) + continue; + + bgp_aggregate_increment(bgp, + bgp_dest_get_prefix(bdi->dest), + bdi->path, bdi->afi, bdi->safi); + bgp_process(bgp, bdi->dest, bdi->path, bdi->afi, + bdi->safi); + + bgp_damp_info_free(pi->extra->damp_info, NULL, 1); + pi = pi_temp; } + + bgp_dest_unlock_node(dest); } return CMD_SUCCESS; From b9255709819e68411fa8dc8456ceae8321231b49 Mon Sep 17 00:00:00 2001 From: Martin Buck Date: Mon, 22 Apr 2024 17:13:23 +0200 Subject: [PATCH 060/472] ospf6d: Fix nexthop computation for inter-area multi-ABR ECMP Pre-b74e965, we always merged nexthops of old (existing) and new (newly generated, based on a LSA update) routes, making it impossible to remove individual nexthops from a route. b74e965 replaced this by copying nexthops from the new route to the old route. This works as long as the old and new route are derived from the same LSA (e.g. multiple ECMP paths to the same ABR). However, in case of multiple parallel ABRs, each of them originates a LSA and the nexthops derived from them need to be combined to get the proper route nexthops. So instead of trying to incrementally update the route nexthops based on the old and new route nexthops, always recompute the route nexthops by merging all of its path nexthops (which we're already updating based on the LSA being processed). Fixes #15777. Signed-off-by: Martin Buck --- ospf6d/ospf6_abr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index f4202a4a29e7..d3ff759d33ed 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -1275,8 +1275,6 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) continue; } - list_delete_all_node(old_route->nh_list); - ospf6_route_copy_nexthops(old_route, route); old_entry_updated = true; for (ALL_LIST_ELEMENTS_RO(old_route->paths, anode, @@ -1330,6 +1328,15 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) } } + /* We added a path or updated a path's nexthops above, + * recompute (old) route nexthops by merging all path nexthops + */ + list_delete_all_node(old_route->nh_list); + for (ALL_LIST_ELEMENTS_RO(old_route->paths, anode, o_path)) { + ospf6_merge_nexthops(old_route->nh_list, + o_path->nh_list); + } + if (is_debug) zlog_debug( "%s: Update route: %s %p old cost %u new cost %u nh %u", From 217e505a67df1ac03483f7c9a97cf4947dd40707 Mon Sep 17 00:00:00 2001 From: Martin Buck Date: Mon, 22 Apr 2024 13:01:22 +0200 Subject: [PATCH 061/472] tests: Modify inter-area ECMP topotest to also test redundant ABRs So far, this test only convered redundant paths to one ABR, now it checks redundant paths to redundant ABRs, covering both cases. Useful as a regression test for #15777. Signed-off-by: Martin Buck --- .../ospf6_ecmp_inter_area/r5/ospf6d.conf | 22 +--- .../ospf6_ecmp_inter_area/r6/ospf6d.conf | 15 +++ .../ospf6_ecmp_inter_area/r7/ospf6d.conf | 15 ++- .../ospf6_ecmp_inter_area/r7/zebra.conf | 3 + .../ospf6_ecmp_inter_area/r8/ospf6d.conf | 13 ++ .../ospf6_ecmp_inter_area/r8/zebra.conf | 3 + .../ospf6_ecmp_inter_area/r9/ospf6d.conf | 11 -- .../ospf6_ecmp_inter_area/r9/zebra.conf | 5 - .../test_ospf6_ecmp_inter_area.py | 117 +++++++++++------- 9 files changed, 119 insertions(+), 85 deletions(-) delete mode 100644 tests/topotests/ospf6_ecmp_inter_area/r9/ospf6d.conf delete mode 100644 tests/topotests/ospf6_ecmp_inter_area/r9/zebra.conf diff --git a/tests/topotests/ospf6_ecmp_inter_area/r5/ospf6d.conf b/tests/topotests/ospf6_ecmp_inter_area/r5/ospf6d.conf index 2a6c9abd2e11..24cd3541184c 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r5/ospf6d.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r5/ospf6d.conf @@ -4,31 +4,11 @@ interface r5-eth0 ipv6 ospf6 dead-interval 10 ! interface r5-eth1 - ipv6 ospf6 area 0 - ipv6 ospf6 hello-interval 2 - ipv6 ospf6 dead-interval 10 -! -interface r5-eth2 - ipv6 ospf6 area 0 - ipv6 ospf6 hello-interval 2 - ipv6 ospf6 dead-interval 10 -! -interface r5-eth3 ipv6 ospf6 area 1 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 ! -interface r5-eth4 - ipv6 ospf6 area 1 - ipv6 ospf6 hello-interval 2 - ipv6 ospf6 dead-interval 10 -! -interface r5-eth5 - ipv6 ospf6 area 0 - ipv6 ospf6 hello-interval 2 - ipv6 ospf6 dead-interval 10 -! -interface r5-eth6 +interface r5-eth2 ipv6 ospf6 area 0 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 diff --git a/tests/topotests/ospf6_ecmp_inter_area/r6/ospf6d.conf b/tests/topotests/ospf6_ecmp_inter_area/r6/ospf6d.conf index a1f48b51a5d9..4efaa318a914 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r6/ospf6d.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r6/ospf6d.conf @@ -1,8 +1,23 @@ interface r6-eth0 + ipv6 ospf6 area 0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +interface r6-eth1 + ipv6 ospf6 area 0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +interface r6-eth2 ipv6 ospf6 area 1 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 ! +interface r6-eth3 + ipv6 ospf6 area 0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! router ospf6 ospf6 router-id 10.254.254.6 redistribute connected diff --git a/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf b/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf index 0e49b0df6c72..9b7756e838c1 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r7/ospf6d.conf @@ -1,11 +1,22 @@ -interface lo +interface r7-eth0 ipv6 ospf6 area 1 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 ! -interface r7-eth0 +interface r7-eth1 ipv6 ospf6 area 1 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 ! +interface r7-eth2 + ipv6 ospf6 area 1 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +interface r7-eth3 + shutdown +! router ospf6 ospf6 router-id 10.254.254.7 + redistribute connected ! diff --git a/tests/topotests/ospf6_ecmp_inter_area/r7/zebra.conf b/tests/topotests/ospf6_ecmp_inter_area/r7/zebra.conf index a410be8f7330..1608cad0b074 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r7/zebra.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r7/zebra.conf @@ -3,3 +3,6 @@ ipv6 forwarding interface lo ipv6 address 2001:db8:7::1/64 ! +interface r7-eth2 + ipv6 address 2001:db8:8007::1/64 +! diff --git a/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf b/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf index fb5483ce9968..33c64979ca6f 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r8/ospf6d.conf @@ -3,6 +3,19 @@ interface r8-eth0 ipv6 ospf6 hello-interval 2 ipv6 ospf6 dead-interval 10 ! +interface r8-eth1 + ipv6 ospf6 area 0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +interface r8-eth2 + ipv6 ospf6 area 0 + ipv6 ospf6 hello-interval 2 + ipv6 ospf6 dead-interval 10 +! +interface r8-eth3 + shutdown +! router ospf6 ospf6 router-id 10.254.254.8 redistribute connected diff --git a/tests/topotests/ospf6_ecmp_inter_area/r8/zebra.conf b/tests/topotests/ospf6_ecmp_inter_area/r8/zebra.conf index 8e343d8f452f..e756cd4b9545 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/r8/zebra.conf +++ b/tests/topotests/ospf6_ecmp_inter_area/r8/zebra.conf @@ -3,3 +3,6 @@ ipv6 forwarding interface lo ipv6 address 2001:db8:8::1/64 ! +interface r8-eth2 + ipv6 address 2001:db8:8008::1/64 +! diff --git a/tests/topotests/ospf6_ecmp_inter_area/r9/ospf6d.conf b/tests/topotests/ospf6_ecmp_inter_area/r9/ospf6d.conf deleted file mode 100644 index 57fa8e32ee9f..000000000000 --- a/tests/topotests/ospf6_ecmp_inter_area/r9/ospf6d.conf +++ /dev/null @@ -1,11 +0,0 @@ -interface lo - ipv6 ospf6 area 0 -! -interface r9-eth0 - ipv6 ospf6 area 0 - ipv6 ospf6 hello-interval 2 - ipv6 ospf6 dead-interval 10 -! -router ospf6 - ospf6 router-id 10.254.254.9 -! diff --git a/tests/topotests/ospf6_ecmp_inter_area/r9/zebra.conf b/tests/topotests/ospf6_ecmp_inter_area/r9/zebra.conf deleted file mode 100644 index e267496a9854..000000000000 --- a/tests/topotests/ospf6_ecmp_inter_area/r9/zebra.conf +++ /dev/null @@ -1,5 +0,0 @@ -ipv6 forwarding -! -interface lo - ipv6 address 2001:db8:9::1/64 -! diff --git a/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py b/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py index 2eaccb8348d0..adf289e2de20 100644 --- a/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py +++ b/tests/topotests/ospf6_ecmp_inter_area/test_ospf6_ecmp_inter_area.py @@ -3,7 +3,7 @@ # test_ospf6_ecmp_inter_area.py # -# Copyright (c) 2021, 2022 by Martin Buck +# Copyright (c) 2021, 2022, 2024 by Martin Buck # Copyright (c) 2016 by # Network Device Education Foundation, Inc. ("NetDEF") # @@ -11,35 +11,42 @@ r""" test_ospf6_ecmp_inter_area.py: Test OSPFv3 ECMP inter-area nexthop update -Check proper removal of ECMP nexthops after a path used by one nexthop -disappears. We remove a path by bringing down a link required by that -path which is not adjacent to the router being checked. This is important -because when bringing down adjacent links, the kernel might remove the -nexthops itself without ospf6d having to do anything. +Check proper addition and removal of ECMP nexthops in 2 cases: Parallel +paths to one ABR and parallel ABRs. We test nexthop removal triggered by +path removal by bringing down a link required by that path which is not +adjacent to the router being checked. This is important because when +bringing down adjacent links, the kernel might remove the nexthops itself +without ospf6d having to do anything. -Useful as a regression test for #9720. +Useful as a regression test for #9720 and #15777. Topology: - . - Area 0 . Area 1 - . - -- R2 -- . ---- R6 - / \ ./ -R1 -- R3 -- R5 ---- R7 Area 1 - \ / \\ .............. - -- R4 -- \--- R8 Area 0 - \ - -- R9 - -We check routes on R1, primarily those towards R6/7/8/9. Those to R6/7 are -inter-area routes with R5 being ABR, those to R8/9 are intra-area routes -and are used for reference. R6/R8 announce external routes, R7/R9 announce -internal routes. + . + Area 0 . Area 1 + . + -- R2 ------ R5 ----- + / .\ \ + / . | \ +R1 --- R3 ------ R6 ------ R7 + \ / |. | + \ / |. | + -- R4 ---- |. | + / ./ + R8 -- + . + +We check routes on R1, primarily those towards R7/8. Those to R7 are +inter-area routes with R5/6 being ABRs, those to R8 are intra-area routes +and are used for reference. R7/R8 announce one internal and one external +route each. With all links up, we expect 3 ECMP paths and 3 nexthops on R1 towards each -of R6/7/8/9. Then we bring down the R2-R5 link, causing only 2 remaining -paths and 2 nexthops on R1. The test is successful if the number of nexthops -for the routes on R1 is as expected. +of R7/8. Then we bring down the R3-R6 link, causing only 2 remaining +paths and 2 nexthops on R1. Then we bring down the R2-R5 link, causing only +1 remaining path and 1 nexthop on R1. + +The test is successful if the number of nexthops for the routes on R1 is as +expected. """ import os @@ -65,20 +72,24 @@ def build_topo(tgen): "Build function" - # Create 9 routers - for routern in range(1, 10): + # Create 8 routers + for routern in range(1, 9): tgen.add_router("r{}".format(routern)) - tgen.gears["r1"].add_link(tgen.gears["r2"]) tgen.gears["r1"].add_link(tgen.gears["r3"]) tgen.gears["r1"].add_link(tgen.gears["r4"]) tgen.gears["r2"].add_link(tgen.gears["r5"]) - tgen.gears["r3"].add_link(tgen.gears["r5"]) - tgen.gears["r4"].add_link(tgen.gears["r5"]) - tgen.gears["r5"].add_link(tgen.gears["r6"]) + tgen.gears["r3"].add_link(tgen.gears["r6"]) + tgen.gears["r4"].add_link(tgen.gears["r6"]) tgen.gears["r5"].add_link(tgen.gears["r7"]) tgen.gears["r5"].add_link(tgen.gears["r8"]) - tgen.gears["r5"].add_link(tgen.gears["r9"]) + tgen.gears["r6"].add_link(tgen.gears["r7"]) + tgen.gears["r6"].add_link(tgen.gears["r8"]) + # Additional "loopback" interfaces. Not used for communication, just to + # hold an address we use to inject intra-/inter-area routes (the one on + # the real "lo" loopback is used for external routes). + tgen.gears["r7"].add_link(tgen.gears["r7"]) + tgen.gears["r8"].add_link(tgen.gears["r8"]) def setup_module(mod): @@ -131,20 +142,19 @@ def expect_neighbor_full(router, neighbor): expect_neighbor_full("r2", "10.254.254.1") expect_neighbor_full("r2", "10.254.254.5") expect_neighbor_full("r3", "10.254.254.1") - expect_neighbor_full("r3", "10.254.254.5") + expect_neighbor_full("r3", "10.254.254.6") expect_neighbor_full("r4", "10.254.254.1") - expect_neighbor_full("r4", "10.254.254.5") + expect_neighbor_full("r4", "10.254.254.6") expect_neighbor_full("r5", "10.254.254.2") - expect_neighbor_full("r5", "10.254.254.3") - expect_neighbor_full("r5", "10.254.254.4") - expect_neighbor_full("r5", "10.254.254.6") expect_neighbor_full("r5", "10.254.254.7") expect_neighbor_full("r5", "10.254.254.8") - expect_neighbor_full("r5", "10.254.254.9") - expect_neighbor_full("r6", "10.254.254.5") + expect_neighbor_full("r6", "10.254.254.3") + expect_neighbor_full("r6", "10.254.254.7") + expect_neighbor_full("r6", "10.254.254.8") expect_neighbor_full("r7", "10.254.254.5") + expect_neighbor_full("r7", "10.254.254.6") expect_neighbor_full("r8", "10.254.254.5") - expect_neighbor_full("r9", "10.254.254.5") + expect_neighbor_full("r8", "10.254.254.6") def test_ecmp_inter_area(): @@ -154,9 +164,16 @@ def test_ecmp_inter_area(): pytest.skip(tgen.errors) def num_nexthops(router): - routes = tgen.gears[router].vtysh_cmd("show ipv6 ospf6 route json", isjson=True) - route_prefixes_infos = sorted(routes.get("routes", {}).items()) - return [len(ri.get("nextHops", [])) for rp, ri in route_prefixes_infos] + # Careful: "show ipv6 ospf6 route json" doesn't work here. It will + # only list one route type per prefix and that might not necessarily + # be the best/selected route. "show ipv6 route ospf6 json" only + # lists selected routes, so that's more useful in this case. + routes = tgen.gears[router].vtysh_cmd("show ipv6 route ospf6 json", isjson=True) + route_prefixes_infos = sorted(routes.items()) + # Note: ri may contain one entry per routing protocol, but since + # we've explicitly requested only ospf6 above, we can count on ri[0] + # being the entry we're looking for. + return [ri[0]["internalNextHopActiveNum"] for rp, ri in route_prefixes_infos] def expect_num_nexthops(router, expected_num_nexthops, count): "Wait until number of nexthops for routes matches expectation" @@ -174,14 +191,22 @@ def expect_num_nexthops(router, expected_num_nexthops, count): ), "'{}' wrong number of route nexthops".format(router) # Check nexthops pre link-down - expect_num_nexthops("r1", [1, 1, 1, 3, 3, 3, 3, 3, 3, 3], 4) + # tgen.mininet_cli() + expect_num_nexthops("r1", [1, 1, 1, 1, 2, 3, 3, 3, 3], 4) + + logger.info("triggering R3-R6 link down") + tgen.gears["r3"].run("ip link set r3-eth1 down") + + # tgen.mininet_cli() + # Check nexthops post link-down + expect_num_nexthops("r1", [1, 1, 1, 1, 1, 2, 2, 2, 2], 8) - logger.info("triggering R2-R4 link down") + logger.info("triggering R2-R5 link down") tgen.gears["r2"].run("ip link set r2-eth1 down") # tgen.mininet_cli() # Check nexthops post link-down - expect_num_nexthops("r1", [1, 1, 1, 2, 2, 2, 2, 2, 2, 2], 8) + expect_num_nexthops("r1", [1, 1, 1, 1, 1, 1, 1, 1, 1], 8) def teardown_module(_mod): From b4eb7a037414e453cf7377a08dbc38b3e616cb75 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 30 Apr 2024 13:51:38 +0200 Subject: [PATCH 062/472] =?UTF-8?q?build:=20get=20rid=20of=20"unrecognized?= =?UTF-8?q?=20=E2=80=A6=20anon-tag"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC only errors out on unrecognized _positive_ `-Wsomething` flags, negative ones it ignores... but then prints a "note" about whenever an unrelated(!) warning/error occurs. This is both annoying and confusing, since we now get a lot of: ``` cc1: note: unrecognized command-line option ‘-Wno-microsoft-anon-tag’ may have been intended to silence earlier diagnostics ``` Fix by checking for the positive flag in `AC_C_FLAG` instead, which will error out, and therefore `-Wno-microsoft-anon-tag` won't be added for GCC. (It only exists on clang.) Signed-off-by: David Lamparter --- configure.ac | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f11b345cf6ef..6d8e70bb86b2 100644 --- a/configure.ac +++ b/configure.ac @@ -275,7 +275,16 @@ AC_DEFUN([AC_C_FLAG], [{ AC_CACHE_CHECK([[whether $CC supports $1]], cachename, [ AC_LANG_PUSH([C]) ac_c_flag_save="$CFLAGS" - CFLAGS="$CFLAGS $1" + dnl GCC ignores unknown -Wno-whatever flags, but errors on -Wwhatever + dnl except when it ignores them it prints: + dnl cc1: note: unrecognized command-line option ‘-Wno-whatever’ may have been intended to silence earlier diagnostics + dnl which is annoying as hell. So check for the positive flag instead. + flag_add="$1" + if test "$flag_add" != "${flag_add#-Wno-}"; then + CFLAGS="$CFLAGS -W${flag_add#-Wno-}" + else + CFLAGS="$CFLAGS $flag_add" + fi AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[$4]])], [ From fa4ad1f347f03bf70a3a6df916811de7981ec718 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Fri, 3 May 2024 23:04:05 +0800 Subject: [PATCH 063/472] isisd: adjust the format of display command Before: ``` anlan# show isis neighbor Area xx: System Id Interface L State Holdtime SNPA 0023.0000.0000 enp1s0 2 Down Expiring2c53.4a30.0820 ``` After: ``` anlan# show isis neighbor Area xx: System Id Interface L State Holdtime SNPA 0023.0000.0000 enp1s0 2 Down Expiring 2c53.4a30.0820 ``` The `-` display format caused by no hello packet in `isis_adj_print_vty()` is same as that of above "Expiring". Signed-off-by: anlan_cs --- isisd/isis_adjacency.c | 4 ++-- isisd/isisd.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 7acd3a2b4e56..430bee92bf97 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -726,13 +726,13 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, now = time(NULL); if (adj->last_upd) { if (adj->last_upd + adj->hold_time < now) - vty_out(vty, " Expiring"); + vty_out(vty, " Expiring "); else vty_out(vty, " %-9llu", (unsigned long long)adj->last_upd + adj->hold_time - now); } else - vty_out(vty, "- "); + vty_out(vty, " - "); vty_out(vty, "%-10pSY", adj->snpa); vty_out(vty, "\n"); } diff --git a/isisd/isisd.c b/isisd/isisd.c index 772eb9708dfc..c1eda4822a43 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -1318,7 +1318,7 @@ static void isis_neighbor_common_vty(struct vty *vty, const char *id, if (detail == ISIS_UI_LEVEL_BRIEF) vty_out(vty, - " System Id Interface L State Holdtime SNPA\n"); + " System Id Interface L State Holdtime SNPA\n"); for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) { if (circuit->circ_type == CIRCUIT_T_BROADCAST) { From 07005288c2339677f08a61161d5cd9cdef772fc5 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Fri, 22 Mar 2024 13:25:18 -0700 Subject: [PATCH 064/472] zebra: bridge flap handle vlan membership update Upon bridge flap, the associated SVD case, VLAN membership is not updated correctly. When SVI comes up, the VNI could not associate with it as bridge VLAN membership was not updated. Ticket: #3821632 Testing: Before fix: ----------- tor-1:#ifdown br_l3vni ; sleep 1 ; ifup br_l3vni tor-1:# vtysh -c 'show evpn vni 8888' VNI: 8888 Type: L3 Tenant VRF: sym_1 Vlan: 490 Bridge: br_l3vni Local Vtep Ip: 27.0.0.9 Vxlan-Intf: vxlan99 SVI-If: None <<<<<< SVI not found State: Down <<<<<< status remained in down BGP is not informed VNI Filter: none System MAC: None Router MAC: None L2 VNIs: 1800 1801 1900 1901 After fix: ---------- tor-1:# ifdown br_l3vni; sleep 1; ifup br_l3vni tor-1:# vtysh Hello, this is FRRouting (version 8.4.3). Copyright 1996-2005 Kunihiro Ishiguro, et al. tor-1# show evpn vni 8888 VNI: 8888 Type: L3 Tenant VRF: sym_1 Vlan: 490 Bridge: br_l3vni Local Vtep Ip: 27.0.0.9 Vxlan-Intf: vxlan99 SVI-If: vlan490_l3 <<<<<< State: Up <<<<<< VNI Filter: none System MAC: 44:38:39:ff:ff:29 Router MAC: 44:38:39:ff:ff:29 L2 VNIs: 1800 1801 1900 1901 Signed-off-by: Chirag Shah --- zebra/zebra_evpn_mh.c | 37 +++++++++++++++++++++++++++++++------ zebra/zebra_evpn_mh.h | 3 ++- zebra/zebra_l2.c | 2 +- zebra/zebra_vxlan_if.c | 35 +++++++++++++++++++++++++++++------ 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 0d9d912f8366..5c19d226b16a 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -563,8 +563,9 @@ zebra_evpn_acc_vl_new(vlanid_t vid, struct interface *br_if) struct zebra_evpn_access_bd *acc_bd; struct interface *vlan_if; - if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("access vlan %d bridge %s add", vid, br_if->name); + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s access vlan %d bridge %s add", __func__, vid, + br_if->name); acc_bd = XCALLOC(MTYPE_ZACC_BD, sizeof(struct zebra_evpn_access_bd)); @@ -582,8 +583,8 @@ zebra_evpn_acc_vl_new(vlanid_t vid, struct interface *br_if) vlan_if = zvni_map_to_svi(vid, br_if); if (vlan_if) { if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("vlan %d bridge %s SVI %s set", vid, - br_if->name, vlan_if->name); + zlog_debug("%s vlan %d bridge %s SVI %s set", __func__, + vid, br_if->name, vlan_if->name); acc_bd->vlan_zif = vlan_if->info; } return acc_bd; @@ -731,6 +732,29 @@ static void zebra_evpn_acc_bd_evpn_set(struct zebra_evpn_access_bd *acc_bd, } } +/* Lookup API for VxLAN_IF's Bridge, VLAN in EVPN cache */ +int zebra_evpn_vl_vxl_bridge_lookup(uint16_t vid, struct zebra_if *vxlan_zif) +{ + struct interface *br_if; + struct zebra_evpn_access_bd *acc_bd; + + if (!vid) + return -1; + + br_if = vxlan_zif->brslave_info.br_if; + + if (!br_if) + return -1; + + acc_bd = zebra_evpn_acc_vl_find(vid, br_if); + + if (!acc_bd) + return 0; + + return 1; +} + + /* handle VLAN->VxLAN_IF association */ void zebra_evpn_vl_vxl_ref(uint16_t vid, vni_t vni_id, struct zebra_if *vxlan_zif) @@ -768,8 +792,9 @@ void zebra_evpn_vl_vxl_ref(uint16_t vid, vni_t vni_id, if (acc_bd->zevpn == old_zevpn) return; - if (IS_ZEBRA_DEBUG_EVPN_MH_ES) - zlog_debug("access vlan %d vni %u ref", acc_bd->vid, vni_id); + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s bridge %s access vlan %d vni %u ref", __func__, + br_if->name, acc_bd->vid, vni_id); if (old_zevpn) zebra_evpn_acc_bd_evpn_set(acc_bd, NULL, old_zevpn); diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 34ef79f1558e..f68e2eae6005 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -378,7 +378,8 @@ extern void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es, extern void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS); extern struct zebra_evpn_es_evi * zebra_evpn_es_evi_find(struct zebra_evpn_es *es, struct zebra_evpn *zevpn); - +extern int zebra_evpn_vl_vxl_bridge_lookup(uint16_t vid, + struct zebra_if *vxlan_zif); void zebra_build_type3_esi(uint32_t lid, struct ethaddr *mac, esi_t *esi); void zebra_evpn_es_sys_mac_update(struct zebra_if *zif, struct ethaddr *sysmac); diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 0f591810b926..240f674b0f55 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -384,7 +384,7 @@ void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp, return; old_access_vlan = zif->l2info.vxl.vni_info.vni.access_vlan; - ; + if (old_access_vlan == access_vlan) return; diff --git a/zebra/zebra_vxlan_if.c b/zebra/zebra_vxlan_if.c index 3cc7e499bf6b..f4b859b861f3 100644 --- a/zebra/zebra_vxlan_if.c +++ b/zebra/zebra_vxlan_if.c @@ -506,7 +506,7 @@ static int zebra_vxlan_if_add_update_vni(struct zebra_if *zif, if ((hashcount(ctx->old_vni_table) == 0) || !(old_vni = hash_release(ctx->old_vni_table, &vni_tmp))) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug("vxlan %s adding vni(%d, %d)", + zlog_debug("%s vxlan %s adding vni(%d, %d)", __func__, zif->ifp->name, vni->vni, vni->access_vlan); zebra_vxlan_if_vni_entry_add(zif, &vni_tmp); @@ -521,17 +521,39 @@ static int zebra_vxlan_if_add_update_vni(struct zebra_if *zif, if (old_vni->access_vlan != vni->access_vlan) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "vxlan %s updating vni(%d, %d) -> vni(%d, %d)", - zif->ifp->name, old_vni->vni, - old_vni->access_vlan, vni->vni, - vni->access_vlan); + zlog_debug("%s vxlan %s updating vni(%d, %d) -> vni(%d, %d)", + __func__, zif->ifp->name, old_vni->vni, + old_vni->access_vlan, vni->vni, + vni->access_vlan); zebra_evpn_vl_vxl_deref(old_vni->access_vlan, old_vni->vni, zif); zebra_evpn_vl_vxl_ref(vni->access_vlan, vni->vni, zif); zebra_vxlan_if_update_vni(zif->ifp, vni, ctx); zebra_vxlan_vni_free(old_vni); + } else { + int ret; + + ret = zebra_evpn_vl_vxl_bridge_lookup(vni->access_vlan, zif); + /* Here ret value 0 implied bridge vlan mapping is not present + * repopulated. Ignore ret value 1 as it means vlan mapping is + * present in bridge table. + */ + if (ret < 0) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s vxlan %s vni %u has error accessing bridge table.", + __func__, zif->ifp->name, vni->vni); + } else if (ret == 0) { + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s vxlan %s vni (%u, %u) not present in bridge table", + __func__, zif->ifp->name, vni->vni, + vni->access_vlan); + zebra_evpn_vl_vxl_deref(old_vni->access_vlan, + old_vni->vni, zif); + zebra_evpn_vl_vxl_ref(vni->access_vlan, vni->vni, zif); + zebra_vxlan_if_update_vni(zif->ifp, vni, ctx); + zebra_vxlan_vni_free(old_vni); + } } return 0; @@ -768,6 +790,7 @@ vni_t zebra_vxlan_if_access_vlan_vni_find(struct zebra_if *zif, return vni->vni; } +/* SVD VLAN-VNI mapping update */ int zebra_vxlan_if_vni_table_add_update(struct interface *ifp, struct hash *vni_table) { From fde6dd7bb9161cf58fdd8ca066cce77bad159c9d Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Thu, 2 May 2024 20:58:50 -0700 Subject: [PATCH 065/472] zebra: fix EVPN svd based remote nh neigh del In the context of SVD (Single VxLAN Device) for L3VNI, the remote VTEP's nexthop is programmed neighbor entry against SVD along with neighbor entry against SVI. However, when L3VNI is removed or the VRF is disabled, all SVI based remote nexthop neighbors are uninstalled and deleted. The SVD based neigh entries remains in Zebra and the Kernel. Subsequently, when reconfiguring L3VNI and relearning the same nexthop, the neighbor entry is not programmed is because it is not removed from Zebra SVD neighbor hash table, leading to the failure to reprogram the entry. With this fix, the SVD nexthop neigh entry is uninstalled and deleted from Zebra and Kernel. Ticket: #3729045 Testing: borderleaf:# ip neigh show 2.2.2.2 2.2.2.2 dev vlan2560_l3 lladdr 00:01:00:00:1d:09 extern_learn NOARP proto zebra 2.2.2.2 dev vxlan99 lladdr 00:01:00:00:1d:09 extern_learn NOARP proto zebra With the fix: Zebra log shows both enties SVD (vxlan99) and SVI (vlan2560_l3) neighbor entries are deleted. 2024/05/03 18:41:33.527125 ZEBRA: [NH6N7-54CD1] Tx RTM_DELNEIGH family ipv4 IF vxlan99(16) Neigh 2.2.2.2 MAC null flags 0x10 state 0x0 ext_flags 0x0 2024/05/03 18:41:33.527128 ZEBRA: [NH6N7-54CD1] Tx RTM_DELNEIGH family ipv4 IF vlan2560_l3(18) Neigh 2.2.2.2 MAC null flags 0x10 state 0x0 ext_flags 0x0 borderleaf:# ip neigh show 2.2.2.2 borderleaf:# Signed-off-by: Chirag Shah --- zebra/zebra_vxlan.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 89b43f6d2216..65dc6638bc32 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1759,9 +1759,9 @@ static int svd_remote_nh_add(struct zebra_l3vni *zl3vni, } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) { if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "SVD RMAC change(%pEA --> %pEA) for nexthop %pIA, prefix %pFX", - &nh->emac, rmac, vtep_ip, host_prefix); + zlog_debug("SVD RMAC change(%pEA --> %pEA) for nexthop %pIA, prefix %pFX refcnt %u", + &nh->emac, rmac, vtep_ip, host_prefix, + nh->refcnt); memcpy(&nh->emac, rmac, ETH_ALEN); /* install (update) the nh neigh in kernel */ @@ -2469,11 +2469,26 @@ static void zl3vni_del_rmac_hash_entry(struct hash_bucket *bucket, void *ctx) /* delete and uninstall nh hash entry */ static void zl3vni_del_nh_hash_entry(struct hash_bucket *bucket, void *ctx) { - struct zebra_neigh *n = NULL; + struct zebra_neigh *n = NULL, *svd_nh = NULL; struct zebra_l3vni *zl3vni = NULL; n = (struct zebra_neigh *)bucket->data; zl3vni = (struct zebra_l3vni *)ctx; + + /* remove SVD based remote nexthop neigh entry */ + svd_nh = svd_nh_lookup(&n->ip); + if (svd_nh) { + svd_nh->refcnt--; + if (IS_ZEBRA_DEBUG_VXLAN) + zlog_debug("%s L3VNI %u remove svd nh %pIA refcnt %u", + __func__, zl3vni->vni, &n->ip, + svd_nh->refcnt); + if (svd_nh->refcnt == 0) { + svd_nh_uninstall(zl3vni, svd_nh); + svd_nh_del(svd_nh); + } + } + zl3vni_nh_uninstall(zl3vni, n); zl3vni_nh_del(zl3vni, n); } From ae3241b96d7be08d627f142030a41031492ffaf5 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 3 May 2024 23:35:05 +0200 Subject: [PATCH 066/472] bgpd: Fix crash when deleting the SRv6 locator When BGP receives a `SRV6_LOCATOR_DEL` from zebra, it invokes `bgp_zebra_process_srv6_locator_delete` to process the message. `bgp_zebra_process_srv6_locator_delete` obtains a pointer to the default BGP instance and then dereferences this pointer. If the default BGP instance is not ready / not configured yet, this pointer this pointer is `NULL` and dereferencing it causes BGP to crash. This commit fix the issue by adding a a check to verify if the pointer is `NULL` and returning early if it is. Signed-off-by: Carmine Scarpitta --- bgpd/bgp_zebra.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 15ed98933e8d..ad3e59060ae1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -3408,6 +3408,9 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) struct in6_addr *tovpn_sid; struct prefix_ipv6 tmp_prefi; + if (!bgp) + return 0; + if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0) return -1; From 0a8d85aacffe048e8b026479dfc2c072f75e813e Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Fri, 2 Feb 2024 12:11:58 -0800 Subject: [PATCH 067/472] bgpd: [GR] fix mode change vtysh return code When a bgp neighbor graceful-restart config mode change is applied, after accepting the config if it does not take effect instead of throwing vtysh error code, return the success to vtysh and warn the user. The debug log is already present at critical code point where GR failure is seen during config apply. Ticket: #3761481 Testing Done: root@tor-1:# vtysh -c 'config t' -c 'router bgp 65564 vrf VRF2' -c 'neighbor 20.1.1.1 graceful-restart' As part of configuring graceful-restart, capability send to zebra failed root@tor-1:# echo $? 0 Signed-off-by: Chirag Shah --- bgpd/bgp_vty.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 5aedd6b82894..d5f12897ea93 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3347,7 +3347,7 @@ DEFUN (bgp_neighbor_graceful_restart_set, { int idx_peer = 1; struct peer *peer; - int ret = BGP_GR_FAILURE; + int result = BGP_GR_FAILURE, ret = BGP_GR_SUCCESS; VTY_BGP_GR_DEFINE_LOOP_VARIABLE; @@ -3359,8 +3359,8 @@ DEFUN (bgp_neighbor_graceful_restart_set, if (!peer) return CMD_WARNING_CONFIG_FAILED; - ret = bgp_neighbor_graceful_restart(peer, PEER_GR_CMD); - if (ret == BGP_GR_SUCCESS) { + result = bgp_neighbor_graceful_restart(peer, PEER_GR_CMD); + if (result == BGP_GR_SUCCESS) { VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer); VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret); vty_out(vty, @@ -3371,7 +3371,11 @@ DEFUN (bgp_neighbor_graceful_restart_set, zlog_debug( "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : END "); - return bgp_vty_return(vty, ret); + if (ret != BGP_GR_SUCCESS) + vty_out(vty, + "As part of configuring graceful-restart, capability send to zebra failed\n"); + + return bgp_vty_return(vty, result); } DEFUN (no_bgp_neighbor_graceful_restart, @@ -3384,7 +3388,7 @@ DEFUN (no_bgp_neighbor_graceful_restart, ) { int idx_peer = 2; - int ret = BGP_GR_FAILURE; + int result = BGP_GR_FAILURE, ret = BGP_GR_SUCCESS; struct peer *peer; VTY_BGP_GR_DEFINE_LOOP_VARIABLE; @@ -3397,7 +3401,7 @@ DEFUN (no_bgp_neighbor_graceful_restart, zlog_debug( "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : START "); - ret = bgp_neighbor_graceful_restart(peer, NO_PEER_GR_CMD); + result = bgp_neighbor_graceful_restart(peer, NO_PEER_GR_CMD); if (ret == BGP_GR_SUCCESS) { VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer); VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret); @@ -3409,7 +3413,11 @@ DEFUN (no_bgp_neighbor_graceful_restart, zlog_debug( "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : END "); - return bgp_vty_return(vty, ret); + if (ret != BGP_GR_SUCCESS) + vty_out(vty, + "As part of configuring graceful-restart, capability send to zebra failed\n"); + + return bgp_vty_return(vty, result); } DEFUN (bgp_neighbor_graceful_restart_helper_set, From bdc2c7bc5473b5582419702211c22e5d29bf0631 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sun, 5 May 2024 07:25:57 +0200 Subject: [PATCH 068/472] bgpd: Fix the order of NULL check and ZAPI decode When BGP receives an SRV6_LOCATOR_ADD message from zebra, it calls the `bgp_zebra_process_srv6_locator_add()` function to process the message. `bgp_zebra_process_srv6_locator_add()` decodes the message first, and then if the pointer to the default BGP instance is NULL (i.e. the default BGP instance is not configured yet), it returns early without doing anything and without using the decoded message information. This commit fixes the order of the operations executed by `bgp_zebra_process_srv6_locator_add()`. We first ensure that the default BGP instance is ready and we return early if it is not. Then, we decode the message and do something with the information contained in it. Signed-off-by: Carmine Scarpitta --- bgpd/bgp_zebra.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index ad3e59060ae1..52c75a3dc213 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -3385,12 +3385,12 @@ static int bgp_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS) struct bgp *bgp = bgp_get_default(); const char *loc_name = bgp->srv6_locator_name; - if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0) - return -1; - if (!bgp || !bgp->srv6_enabled) return 0; + if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0) + return -1; + if (bgp_zebra_srv6_manager_get_locator_chunk(loc_name) < 0) return -1; From 563fa1fdc496e9c1cee3ef3b053fc807baa982c5 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sat, 4 May 2024 22:56:21 +0800 Subject: [PATCH 069/472] isisd: remove unnecessary check for vrf The `vrf_name` is always non-NULL in `isisd` code, so remove the unnecesary check to make it clear. Signed-off-by: anlan_cs --- isisd/isis_spf.c | 123 +++++++++----------- isisd/isis_te.c | 51 ++++----- isisd/isisd.c | 293 +++++++++++++++++++++-------------------------- 3 files changed, 205 insertions(+), 262 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 294c03def1db..ffc4841c4120 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2469,37 +2469,33 @@ DEFUN(show_isis_topology, show_isis_topology_cmd, } ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { - if (all_algorithm) { - for (algorithm = SR_ALGORITHM_FLEX_MIN; - algorithm <= SR_ALGORITHM_FLEX_MAX; - algorithm++) - show_isis_topology_common( - vty, levels, isis, - (uint8_t)algorithm); - } else { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { + if (all_algorithm) { + for (algorithm = SR_ALGORITHM_FLEX_MIN; + algorithm <= SR_ALGORITHM_FLEX_MAX; + algorithm++) show_isis_topology_common( vty, levels, isis, (uint8_t)algorithm); - } - } - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis == NULL) - return CMD_SUCCESS; - if (all_algorithm) { - for (algorithm = SR_ALGORITHM_FLEX_MIN; - algorithm <= SR_ALGORITHM_FLEX_MAX; algorithm++) { + } else { show_isis_topology_common(vty, levels, isis, (uint8_t)algorithm); } - } else + } + return CMD_SUCCESS; + } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis == NULL) + return CMD_SUCCESS; + if (all_algorithm) { + for (algorithm = SR_ALGORITHM_FLEX_MIN; + algorithm <= SR_ALGORITHM_FLEX_MAX; algorithm++) { show_isis_topology_common(vty, levels, isis, (uint8_t)algorithm); - } + } + } else + show_isis_topology_common(vty, levels, isis, (uint8_t)algorithm); return CMD_SUCCESS; } @@ -2672,17 +2668,14 @@ DEFUN(show_isis_flex_algo, show_isis_flex_algo_cmd, ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) - show_isis_flex_algo_common(vty, isis, - flex_algo); - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) show_isis_flex_algo_common(vty, isis, flex_algo); + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) + show_isis_flex_algo_common(vty, isis, flex_algo); return CMD_SUCCESS; } @@ -3140,34 +3133,8 @@ DEFUN(show_isis_route, show_isis_route_cmd, if (uj) json = json_object_new_array(); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { - if (all_algorithm) - show_isis_route_all_algos(vty, levels, - isis, - prefix_sid, - backup, - uj ? &json_vrf - : NULL); - else - show_isis_route_common(vty, levels, - isis, prefix_sid, - backup, algorithm, - uj ? &json_vrf - : NULL); - if (uj) { - json_object_object_add( - json_vrf, "vrf_id", - json_object_new_int( - isis->vrf_id)); - json_object_array_add(json, json_vrf); - } - } - goto out; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { if (all_algorithm) show_isis_route_all_algos(vty, levels, isis, prefix_sid, backup, @@ -3178,12 +3145,28 @@ DEFUN(show_isis_route, show_isis_route_cmd, algorithm, uj ? &json_vrf : NULL); if (uj) { - json_object_object_add( - json_vrf, "vrf_id", - json_object_new_int(isis->vrf_id)); + json_object_object_add(json_vrf, "vrf_id", + json_object_new_int( + isis->vrf_id)); json_object_array_add(json, json_vrf); } } + goto out; + } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) { + if (all_algorithm) + show_isis_route_all_algos(vty, levels, isis, prefix_sid, + backup, uj ? &json_vrf : NULL); + else + show_isis_route_common(vty, levels, isis, prefix_sid, + backup, algorithm, + uj ? &json_vrf : NULL); + if (uj) { + json_object_object_add(json_vrf, "vrf_id", + json_object_new_int(isis->vrf_id)); + json_object_array_add(json, json_vrf); + } } out: @@ -3395,16 +3378,14 @@ DEFUN(show_isis_frr_summary, show_isis_frr_summary_cmd, } ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) - show_isis_frr_summary_common(vty, levels, isis); - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) show_isis_frr_summary_common(vty, levels, isis); + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) + show_isis_frr_summary_common(vty, levels, isis); return CMD_SUCCESS; } diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 61c3db7f053d..3683f7455821 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -1690,30 +1690,26 @@ DEFUN(show_isis_mpls_te_router, return CMD_SUCCESS; } ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { - for (ALL_LIST_ELEMENTS_RO(isis->area_list, - anode, area)) { - if (!IS_MPLS_TE(area->mta)) - continue; - - show_router_id(vty, area); - } - } - return 0; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) { - for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, - area)) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { if (!IS_MPLS_TE(area->mta)) continue; show_router_id(vty, area); } } + return 0; + } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { + if (!IS_MPLS_TE(area->mta)) + continue; + + show_router_id(vty, area); + } } return CMD_SUCCESS; @@ -2162,19 +2158,18 @@ DEFUN(show_isis_mpls_te_db, int rc = CMD_WARNING; ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { - rc = show_isis_ted(vty, argv, argc, isis); - if (rc != CMD_SUCCESS) - return rc; - } - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis) + + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { rc = show_isis_ted(vty, argv, argc, isis); + if (rc != CMD_SUCCESS) + return rc; + } + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis) + rc = show_isis_ted(vty, argv, argc, isis); return rc; } diff --git a/isisd/isisd.c b/isisd/isisd.c index c1eda4822a43..e059ce1977dd 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -988,63 +988,17 @@ int show_isis_interface_common_json(struct json_object *json, "no"); return CMD_SUCCESS; } - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { - areas_json = json_object_new_array(); - json_object_object_add(json, "areas", - areas_json); - for (ALL_LIST_ELEMENTS_RO(isis->area_list, - anode, area)) { - area_json = json_object_new_object(); - json_object_string_add( - area_json, "area", - area->area_tag ? area->area_tag - : "null"); - circuits_json = json_object_new_array(); - json_object_object_add(area_json, - "circuits", - circuits_json); - for (ALL_LIST_ELEMENTS_RO( - area->circuit_list, cnode, - circuit)) { - circuit_json = - json_object_new_object(); - json_object_int_add( - circuit_json, "circuit", - circuit->circuit_id); - if (!ifname) - isis_circuit_print_json( - circuit, - circuit_json, - detail); - else if (strcmp(circuit->interface->name, ifname) == 0) - isis_circuit_print_json( - circuit, - circuit_json, - detail); - json_object_array_add( - circuits_json, - circuit_json); - } - json_object_array_add(areas_json, - area_json); - } - } - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) { + + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { areas_json = json_object_new_array(); json_object_object_add(json, "areas", areas_json); - for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, - area)) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { area_json = json_object_new_object(); json_object_string_add(area_json, "area", area->area_tag ? area->area_tag : "null"); - circuits_json = json_object_new_array(); json_object_object_add(area_json, "circuits", circuits_json); @@ -1055,22 +1009,56 @@ int show_isis_interface_common_json(struct json_object *json, circuit_json, "circuit", circuit->circuit_id); if (!ifname) - isis_circuit_print_json( - circuit, circuit_json, - detail); - else if ( - strcmp(circuit->interface->name, - ifname) == 0) - isis_circuit_print_json( - circuit, circuit_json, - detail); + isis_circuit_print_json(circuit, + circuit_json, + detail); + else if (strcmp(circuit->interface->name, + ifname) == 0) + isis_circuit_print_json(circuit, + circuit_json, + detail); json_object_array_add(circuits_json, circuit_json); } json_object_array_add(areas_json, area_json); } } + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) { + areas_json = json_object_new_array(); + json_object_object_add(json, "areas", areas_json); + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { + area_json = json_object_new_object(); + json_object_string_add(area_json, "area", + area->area_tag ? area->area_tag + : "null"); + + circuits_json = json_object_new_array(); + json_object_object_add(area_json, "circuits", + circuits_json); + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, + circuit)) { + circuit_json = json_object_new_object(); + json_object_int_add(circuit_json, "circuit", + circuit->circuit_id); + if (!ifname) + isis_circuit_print_json(circuit, + circuit_json, + detail); + else if (strcmp(circuit->interface->name, + ifname) == 0) + isis_circuit_print_json(circuit, + circuit_json, + detail); + json_object_array_add(circuits_json, + circuit_json); + } + json_object_array_add(areas_json, area_json); + } + } + return CMD_SUCCESS; } @@ -1087,37 +1075,10 @@ int show_isis_interface_common_vty(struct vty *vty, const char *ifname, vty_out(vty, "IS-IS Routing Process not enabled\n"); return CMD_SUCCESS; } - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { - for (ALL_LIST_ELEMENTS_RO(isis->area_list, - anode, area)) { - vty_out(vty, "Area %s:\n", - area->area_tag); - if (detail == ISIS_UI_LEVEL_BRIEF) - vty_out(vty, - " Interface CircId State Type Level\n"); - - for (ALL_LIST_ELEMENTS_RO( - area->circuit_list, cnode, - circuit)) - if (!ifname) - isis_circuit_print_vty( - circuit, vty, - detail); - else if (strcmp(circuit->interface->name, ifname) == 0) - isis_circuit_print_vty( - circuit, vty, - detail); - } - } - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) { - for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, - area)) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { vty_out(vty, "Area %s:\n", area->area_tag); if (detail == ISIS_UI_LEVEL_BRIEF) @@ -1127,15 +1088,37 @@ int show_isis_interface_common_vty(struct vty *vty, const char *ifname, for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) if (!ifname) - isis_circuit_print_vty( - circuit, vty, detail); - else if ( - strcmp(circuit->interface->name, - ifname) == 0) - isis_circuit_print_vty( - circuit, vty, detail); + isis_circuit_print_vty(circuit, + vty, + detail); + else if (strcmp(circuit->interface->name, + ifname) == 0) + isis_circuit_print_vty(circuit, + vty, + detail); } } + return CMD_SUCCESS; + } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, anode, area)) { + vty_out(vty, "Area %s:\n", area->area_tag); + + if (detail == ISIS_UI_LEVEL_BRIEF) + vty_out(vty, + " Interface CircId State Type Level\n"); + + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, + circuit)) + if (!ifname) + isis_circuit_print_vty(circuit, vty, + detail); + else if (strcmp(circuit->interface->name, + ifname) == 0) + isis_circuit_print_vty(circuit, vty, + detail); + } } return CMD_SUCCESS; @@ -1376,28 +1359,23 @@ int show_isis_neighbor_common(struct vty *vty, struct json_object *json, return CMD_SUCCESS; } - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { - if (id_to_sysid(isis, id, sysid)) { - vty_out(vty, "Invalid system id %s\n", - id); - return CMD_SUCCESS; - } - isis_neighbor_common(vty, json, id, detail, - isis, sysid); - } - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { if (id_to_sysid(isis, id, sysid)) { vty_out(vty, "Invalid system id %s\n", id); return CMD_SUCCESS; } - isis_neighbor_common(vty, json, id, detail, isis, - sysid); + isis_neighbor_common(vty, json, id, detail, isis, sysid); + } + return CMD_SUCCESS; + } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) { + if (id_to_sysid(isis, id, sysid)) { + vty_out(vty, "Invalid system id %s\n", id); + return CMD_SUCCESS; } + isis_neighbor_common(vty, json, id, detail, isis, sysid); } return CMD_SUCCESS; @@ -1461,27 +1439,23 @@ int clear_isis_neighbor_common(struct vty *vty, const char *id, const char *vrf_ return CMD_SUCCESS; } - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { - if (id_to_sysid(isis, id, sysid)) { - vty_out(vty, "Invalid system id %s\n", - id); - return CMD_SUCCESS; - } - isis_neighbor_common_clear(vty, id, sysid, - isis); - } - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { if (id_to_sysid(isis, id, sysid)) { vty_out(vty, "Invalid system id %s\n", id); return CMD_SUCCESS; } isis_neighbor_common_clear(vty, id, sysid, isis); } + return CMD_SUCCESS; + } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) { + if (id_to_sysid(isis, id, sysid)) { + vty_out(vty, "Invalid system id %s\n", id); + return CMD_SUCCESS; + } + isis_neighbor_common_clear(vty, id, sysid, isis); } return CMD_SUCCESS; @@ -2234,17 +2208,16 @@ DEFUN (show_hostname, struct isis *isis; ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) - dynhn_print_all(vty, isis); - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) dynhn_print_all(vty, isis); + + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) + dynhn_print_all(vty, isis); return CMD_SUCCESS; } @@ -2307,17 +2280,15 @@ DEFUN(show_isis_spf_ietf, show_isis_spf_ietf_cmd, return CMD_SUCCESS; } - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) - isis_spf_ietf_common(vty, isis); - - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) isis_spf_ietf_common(vty, isis); + + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) + isis_spf_ietf_common(vty, isis); return CMD_SUCCESS; } @@ -2596,17 +2567,16 @@ DEFUN(show_isis_summary, show_isis_summary_cmd, } if (uj) json = json_object_new_object(); - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) - common_isis_summary(vty, json, isis); - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis != NULL) + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) common_isis_summary(vty, json, isis); + + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis != NULL) + common_isis_summary(vty, json, isis); if (uj) vty_json(vty, json); @@ -2828,19 +2798,16 @@ static int show_isis_database(struct vty *vty, struct json_object *json, const c struct listnode *node; struct isis *isis; - if (vrf_name) { - if (all_vrf) { - for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) - show_isis_database_common(vty, json, sysid_str, - ui_level, isis); - - return CMD_SUCCESS; - } - isis = isis_lookup_by_vrfname(vrf_name); - if (isis) + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) show_isis_database_common(vty, json, sysid_str, ui_level, isis); + + return CMD_SUCCESS; } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis) + show_isis_database_common(vty, json, sysid_str, ui_level, isis); return CMD_SUCCESS; } From 84d1285fc2c9b8944313cc4e8f0c74a5bf76bcf1 Mon Sep 17 00:00:00 2001 From: Alexander Rose Date: Thu, 11 Apr 2024 13:07:33 +0200 Subject: [PATCH 070/472] ospf6d: Redistribute metric for AS-external route When ospf6d originates an AS-external route that has been read from a kernel routing table, then the metric of that route was ignored until now. If a routemap is configured, then this metric will be redistributed from now on. Using metric increment and decrement in routemaps is supported by ospf6d now. Signed-off-by: Alexander Rose --- ospf6d/ospf6_abr.h | 5 +-- ospf6d/ospf6_asbr.c | 85 ++++++++++++++++++++++++++++++++++++-------- ospf6d/ospf6_asbr.h | 11 +++--- ospf6d/ospf6_route.h | 3 ++ ospf6d/ospf6_zebra.c | 2 +- 5 files changed, 85 insertions(+), 21 deletions(-) diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h index 7bb1619133c2..52686ed49fd1 100644 --- a/ospf6d/ospf6_abr.h +++ b/ospf6d/ospf6_abr.h @@ -33,11 +33,12 @@ struct ospf6_inter_router_lsa { uint32_t router_id; }; -#define OSPF6_ABR_SUMMARY_METRIC(E) (ntohl ((E)->metric & htonl (0x00ffffff))) +#define OSPF6_ABR_SUMMARY_METRIC(E) \ + (ntohl((E)->metric & htonl(OSPF6_EXT_PATH_METRIC_MAX))) #define OSPF6_ABR_SUMMARY_METRIC_SET(E, C) \ { \ (E)->metric &= htonl(0x00000000); \ - (E)->metric |= htonl(0x00ffffff) & htonl(C); \ + (E)->metric |= htonl(OSPF6_EXT_PATH_METRIC_MAX) & htonl(C); \ } #define OSPF6_ABR_RANGE_CLEAR_COST(range) (range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC) diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index d1c2b8bfc9a4..701704cdc80d 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -14,6 +14,7 @@ #include "table.h" #include "plist.h" #include "frrevent.h" +#include "frrstr.h" #include "linklist.h" #include "lib/northbound_cli.h" @@ -1426,10 +1427,9 @@ static void ospf6_external_lsa_fwd_addr_set(struct ospf6 *ospf6, } void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, - struct prefix *prefix, - unsigned int nexthop_num, - const struct in6_addr *nexthop, - route_tag_t tag, struct ospf6 *ospf6) + struct prefix *prefix, unsigned int nexthop_num, + const struct in6_addr *nexthop, route_tag_t tag, + struct ospf6 *ospf6, uint32_t metric) { route_map_result_t ret; struct ospf6_route troute; @@ -1472,6 +1472,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, if (ROUTEMAP(red)) { troute.route_option = &tinfo; troute.ospf6 = ospf6; + troute.path.redistribute_cost = metric; tinfo.ifindex = ifindex; tinfo.tag = tag; @@ -1924,7 +1925,7 @@ static void ospf6_redistribute_default_set(struct ospf6 *ospf6, int originate) case DEFAULT_ORIGINATE_ALWAYS: ospf6_asbr_redistribute_add(DEFAULT_ROUTE, 0, (struct prefix *)&p, 0, &nexthop, 0, - ospf6); + ospf6, 0); break; } } @@ -2153,25 +2154,81 @@ static const struct route_map_rule_cmd ospf6_routemap_rule_set_metric_type_free, }; +struct ospf6_metric { + enum { metric_increment, metric_decrement, metric_absolute } type; + bool used; + uint32_t metric; +}; + static enum route_map_cmd_result_t ospf6_routemap_rule_set_metric(void *rule, const struct prefix *prefix, void *object) { - char *metric = rule; - struct ospf6_route *route = object; + struct ospf6_metric *metric; + struct ospf6_route *route; + + /* Fetch routemap's rule information. */ + metric = rule; + route = object; + + /* Set metric out value. */ + if (!metric->used) + return RMAP_OKAY; + + if (route->path.redistribute_cost > OSPF6_EXT_PATH_METRIC_MAX) + route->path.redistribute_cost = OSPF6_EXT_PATH_METRIC_MAX; + + if (metric->type == metric_increment) { + route->path.cost = route->path.redistribute_cost + + metric->metric; + + /* Check overflow */ + if (route->path.cost > OSPF6_EXT_PATH_METRIC_MAX || + route->path.cost < metric->metric) + route->path.cost = OSPF6_EXT_PATH_METRIC_MAX; + } else if (metric->type == metric_decrement) { + route->path.cost = route->path.redistribute_cost - + metric->metric; + + /* Check overflow */ + if (route->path.cost == 0 || + route->path.cost > route->path.redistribute_cost) + route->path.cost = 1; + } else if (metric->type == metric_absolute) + route->path.cost = metric->metric; - route->path.cost = atoi(metric); return RMAP_OKAY; } static void *ospf6_routemap_rule_set_metric_compile(const char *arg) { - uint32_t metric; - char *endp; - metric = strtoul(arg, &endp, 0); - if (metric > OSPF_LS_INFINITY || *endp != '\0') - return NULL; - return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); + struct ospf6_metric *metric; + + metric = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(*metric)); + metric->used = false; + + if (all_digit(arg)) + metric->type = metric_absolute; + + if ((arg[0] == '+') && all_digit(arg + 1)) { + metric->type = metric_increment; + arg++; + } + + if ((arg[0] == '-') && all_digit(arg + 1)) { + metric->type = metric_decrement; + arg++; + } + + metric->metric = strtoul(arg, NULL, 10); + + if (metric->metric > OSPF6_EXT_PATH_METRIC_MAX) + metric->metric = OSPF6_EXT_PATH_METRIC_MAX; + + if (metric->metric) + metric->used = true; + + return metric; } static void ospf6_routemap_rule_set_metric_free(void *rule) diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index d63e46727890..21e6d898e828 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -94,11 +94,13 @@ struct ospf6_as_external_lsa { #define OSPF6_ASBR_BIT_F ntohl (0x02000000) #define OSPF6_ASBR_BIT_E ntohl (0x04000000) -#define OSPF6_ASBR_METRIC(E) (ntohl ((E)->bits_metric & htonl (0x00ffffff))) +#define OSPF6_ASBR_METRIC(E) \ + (ntohl((E)->bits_metric & htonl(OSPF6_EXT_PATH_METRIC_MAX))) #define OSPF6_ASBR_METRIC_SET(E, C) \ { \ - (E)->bits_metric &= htonl(0xff000000); \ - (E)->bits_metric |= htonl(0x00ffffff) & htonl(C); \ + (E)->bits_metric &= htonl(~OSPF6_EXT_PATH_METRIC_MAX); \ + (E)->bits_metric |= htonl(OSPF6_EXT_PATH_METRIC_MAX) & \ + htonl(C); \ } extern void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa); @@ -115,7 +117,8 @@ extern void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, struct prefix *prefix, unsigned int nexthop_num, const struct in6_addr *nexthop, - route_tag_t tag, struct ospf6 *ospf6); + route_tag_t tag, struct ospf6 *ospf6, + uint32_t metric); extern void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex, struct prefix *prefix, struct ospf6 *ospf6); diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index 2c1d17efc3f7..d3c1804658ff 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -115,6 +115,7 @@ struct ospf6_path { /* Cost */ uint8_t metric_type; uint32_t cost; + uint32_t redistribute_cost; struct prefix ls_prefix; @@ -139,6 +140,8 @@ struct ospf6_path { #define OSPF6_PATH_COST_IS_CONFIGURED(path) (path.u.cost_config != OSPF_AREA_RANGE_COST_UNSPEC) +#define OSPF6_EXT_PATH_METRIC_MAX 0x00ffffff + #include "prefix.h" #include "table.h" #include "bitfield.h" diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 3245578b07f2..911f3567d453 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -289,7 +289,7 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS) if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) ospf6_asbr_redistribute_add(api.type, ifindex, &api.prefix, api.nexthop_num, nexthop, api.tag, - ospf6); + ospf6, api.metric); else ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix, ospf6); From 9eda89a244d4c11d5285ba20707d5e87ebcb33ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sang?= Date: Mon, 6 May 2024 17:30:01 +0200 Subject: [PATCH 071/472] if: fix same connected address MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the same address with a different prefix length is not supported. If we configure two identical addresses with different netmasks 192.168.1.1/30 and then 192.168.1.1/29. Zebra sends '192.168.1.1' with a prefix length of 29. However, the function 'zebra_interface_address_read()' reads '192.168.1.1/30' because the prefix length is not checked. Using 'same_prefix()' is more convenient. Signed-off-by: Loïc Sang --- lib/if.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/lib/if.c b/lib/if.c index a8ceac72432b..bf14baaa5e44 100644 --- a/lib/if.c +++ b/lib/if.c @@ -885,21 +885,6 @@ nbr_connected_log(struct nbr_connected *connected, char *str) zlog_info("%s", logbuf); } -/* If two connected address has same prefix return 1. */ -static int connected_same_prefix(const struct prefix *p1, - const struct prefix *p2) -{ - if (p1->family == p2->family) { - if (p1->family == AF_INET - && IPV4_ADDR_SAME(&p1->u.prefix4, &p2->u.prefix4)) - return 1; - if (p1->family == AF_INET6 - && IPV6_ADDR_SAME(&p1->u.prefix6, &p2->u.prefix6)) - return 1; - } - return 0; -} - /* count the number of connected addresses that are in the given family */ unsigned int connected_count_by_family(struct interface *ifp, int family) { @@ -919,7 +904,7 @@ struct connected *connected_lookup_prefix_exact(struct interface *ifp, struct connected *ifc; frr_each (if_connected, ifp->connected, ifc) { - if (connected_same_prefix(ifc->address, p)) + if (prefix_same(ifc->address, p)) return ifc; } return NULL; @@ -932,7 +917,7 @@ struct connected *connected_delete_by_prefix(struct interface *ifp, /* In case of same prefix come, replace it with new one. */ frr_each_safe (if_connected, ifp->connected, ifc) { - if (connected_same_prefix(ifc->address, p)) { + if (prefix_same(ifc->address, p)) { if_connected_del(ifp->connected, ifc); return ifc; } From f185005b2f2f17d5bde3cc20c1f6b4799a46c0b2 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Tue, 7 May 2024 09:08:05 +0800 Subject: [PATCH 072/472] isisd: fix the display topology command The unconfigured flexible algorithm should not be displayed. Before: ``` anlan# show isis topology algorithm Area A: Algorithm 128 Area A:Area A:Area A:Area A:Area A:Area A:Area A:Area A:Area A:Area ... ...... anlan# ``` After: ``` anlan# show isis topology algorithm Area A: Algorithm 128 anlan# ``` Signed-off-by: anlan_cs --- isisd/isis_spf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 294c03def1db..dccff0f3cd45 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2343,9 +2343,6 @@ static void show_isis_topology_common(struct vty *vty, int levels, return; for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { - vty_out(vty, - "Area %s:", area->area_tag ? area->area_tag : "null"); - #ifndef FABRICD /* * The shapes of the flex algo spftree 2-dimensional array @@ -2361,6 +2358,9 @@ static void show_isis_topology_common(struct vty *vty, int levels, } else fa_data = NULL; + vty_out(vty, + "Area %s:", area->area_tag ? area->area_tag : "null"); + if (algo != SR_ALGORITHM_SPF) vty_out(vty, " Algorithm %hhu\n", algo); else From a727cc7d76442fc0e2801a4c51f557ced2a0709f Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 7 May 2024 02:37:52 +0000 Subject: [PATCH 073/472] mgmtd: rpc and action handling both should use rpc map. The previous idea of using config xpath registrations for actions b/c the config is the subject of the action is sub-optimal. It splits handling of YANG "actions" (Action and RPCs) between 2 different registartion maps for the same category of functionality. Signed-off-by: Christian Hopps --- mgmtd/mgmt_fe_adapter.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index b20e36ce0cd4..fc1bde0b38ae 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -1443,20 +1443,14 @@ static void fe_adapter_handle_rpc(struct mgmt_fe_session_ctx *session, return; } - if (snode->nodetype == LYS_RPC) - clients = - mgmt_be_interested_clients(xpath, - MGMT_BE_XPATH_SUBSCR_TYPE_RPC); - else if (snode->nodetype == LYS_ACTION) - clients = - mgmt_be_interested_clients(xpath, - MGMT_BE_XPATH_SUBSCR_TYPE_CFG); - else { + if (snode->nodetype != LYS_RPC && snode->nodetype != LYS_ACTION) { fe_adapter_send_error(session, req_id, false, -EINVAL, "Not an RPC or action path: %s", xpath); return; } + clients = mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_RPC); if (!clients) { __dbg("No backends implement xpath: %s for txn-id: %" PRIu64 " session-id: %" PRIu64, From 639d8027f166f1853d7a22e162c15355b7beec1b Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Tue, 7 May 2024 10:16:00 +0800 Subject: [PATCH 074/472] isisd: fix json display for database command The current json display lost a lot of LSPs, added them. Fixed the json format for two commands: "show isis database detail json" "show isis database json" Signed-off-by: anlan_cs --- isisd/isis_lsp.c | 13 +++++++++++-- isisd/isisd.c | 10 +++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 77573cdfacb4..9d671137e945 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -822,15 +822,24 @@ int lsp_print_all(struct vty *vty, struct json_object *json, { struct isis_lsp *lsp; int lsp_count = 0; + struct json_object *lsp_json = NULL; if (detail == ISIS_UI_LEVEL_BRIEF) { frr_each (lspdb, head, lsp) { - lsp_print_common(lsp, vty, json, dynhost, isis); + if (json) { + lsp_json = json_object_new_object(); + json_object_array_add(json, lsp_json); + } + lsp_print_common(lsp, vty, lsp_json, dynhost, isis); lsp_count++; } } else if (detail == ISIS_UI_LEVEL_DETAIL) { frr_each (lspdb, head, lsp) { - lsp_print_detail(lsp, vty, json, dynhost, isis); + if (json) { + lsp_json = json_object_new_object(); + json_object_array_add(json, lsp_json); + } + lsp_print_detail(lsp, vty, lsp_json, dynhost, isis); lsp_count++; } } diff --git a/isisd/isisd.c b/isisd/isisd.c index c1eda4822a43..6535b8fcc070 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -2681,6 +2681,7 @@ void show_isis_database_lspdb_json(struct json_object *json, { struct isis_lsp *lsp; int lsp_count; + struct json_object *lsp_arr_json; if (lspdb_count(lspdb) > 0) { lsp = lsp_for_sysid(lspdb, sysid_str, area->isis); @@ -2697,9 +2698,12 @@ void show_isis_database_lspdb_json(struct json_object *json, lsp_print_json(lsp, json, area->dynhostname, area->isis); } else if (sysid_str == NULL) { - lsp_count = - lsp_print_all(NULL, json, lspdb, ui_level, - area->dynhostname, area->isis); + lsp_arr_json = json_object_new_array(); + json_object_object_add(json, "lsps", lsp_arr_json); + + lsp_count = lsp_print_all(NULL, lsp_arr_json, lspdb, + ui_level, area->dynhostname, + area->isis); json_object_int_add(json, "count", lsp_count); } From 94f902fddb1ae48de800773bce688ad1959e74b2 Mon Sep 17 00:00:00 2001 From: Maxence Younsi Date: Tue, 7 May 2024 13:15:31 +0200 Subject: [PATCH 075/472] bgpd: bmp rename tlv types renamed BMP_INFO_TYPE_SYSDESCR to BMP_INIT_INFO_TYPE_SYSDESCR renamed BMP_INFO_TYPE_SYSNAME to BMP_INIT_INFO_TYPE_SYSNAME added BMP_PEERUP_INFO_STRING Signed-off-by: Maxou --- bgpd/bgp_bmp.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 14066ae29dc9..2f3be0bc9d75 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -391,11 +391,11 @@ static int bmp_send_initiation(struct bmp *bmp) bmp_common_hdr(s, BMP_VERSION_3, BMP_TYPE_INITIATION); -#define BMP_INFO_TYPE_SYSDESCR 1 -#define BMP_INFO_TYPE_SYSNAME 2 - bmp_put_info_tlv(s, BMP_INFO_TYPE_SYSDESCR, - FRR_FULL_NAME " " FRR_VER_SHORT); - bmp_put_info_tlv(s, BMP_INFO_TYPE_SYSNAME, cmd_hostname_get()); +#define BMP_INIT_INFO_TYPE_SYSDESCR 1 +#define BMP_INIT_INFO_TYPE_SYSNAME 2 + bmp_put_info_tlv(s, BMP_INIT_INFO_TYPE_SYSDESCR, + FRR_FULL_NAME " " FRR_VER_SHORT); + bmp_put_info_tlv(s, BMP_INIT_INFO_TYPE_SYSNAME, cmd_hostname_get()); len = stream_get_endp(s); stream_putl_at(s, BMP_LENGTH_POS, len); /* message length is set. */ @@ -438,6 +438,7 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) monotime_to_realtime(&uptime, &uptime_real); #define BGP_BMP_MAX_PACKET_SIZE 1024 +#define BMP_PEERUP_INFO_TYPE_STRING 0 s = stream_new(BGP_MAX_PACKET_SIZE); if (peer_established(peer->connection) && !down) { @@ -493,7 +494,8 @@ static struct stream *bmp_peerstate(struct peer *peer, bool down) } if (peer->desc) - bmp_put_info_tlv(s, 0, peer->desc); + bmp_put_info_tlv(s, BMP_PEERUP_INFO_TYPE_STRING, + peer->desc); } else { uint8_t type; size_t type_pos; From 8b815dd2addca9541f0ef84aa503c51b2aa19f5e Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Mon, 6 May 2024 20:38:57 +0800 Subject: [PATCH 076/472] doc: fix one command for isis Correct one command for isis based on code. And better the web page. Signed-off-by: anlan_cs --- doc/user/isisd.rst | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 135d94004a5e..741261186929 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -462,10 +462,14 @@ To do so, it defines a set of Flex-Algo Definitions (FAD) which have the following characteristics: - a numeric identifier (ID) between 128 and 255 inclusive + - a set of constraints (basically, include or exclude a certain given set of links, designated by a admin-group) + - the calculation type (only the `Shortest-Path-First` is currently supported) + - the metric type (only the IGP inherited metric type is currently supported) + - some additional flags (not supported for the moment). A subset of routers advertises the Flex-Algo Definitions (FAD) to the other @@ -475,13 +479,18 @@ rules: - If a locally configured FAD is not advertised to the area, the router does not participate in the particular flex algorithm. + - If a given flex algorithm is running, the participation in this particular flex algorithm stops when its advertisements are over. + - A router includes its own FAD in the election process if and only if it is advertised to the other routers. + - If only one router advertises the FAD, the FAD is elected. + - If several FADs are advertised with different priorities, the one with the highest priority value is selected. + - If there are multiple advertisements of the FAD with the same highest priority, the FAD of the router with the highest IS-IS system-ID is selected. @@ -497,15 +506,11 @@ which flex algorithm they must use for a given packet. The following commands configure Flex-Algo at the 'router isis' configuration level. Segment-Routing prefixes must be configured for the Flex-Algo. -.. clicmd:: flexible-algorithm (128-255) +.. clicmd:: flex-algo (128-255) Add a Flex-Algo Definition (FAD) and enter the FAD configuration level. The algorithm ID value is in the range of 128 to 255 inclusive. -.. clicmd:: no flexible-algorithm (128-255) - - Unconfigure a Flex-Algo Definition. - .. clicmd:: affinity-map NAME bit-position (0-255) Add the specified 'affinity-map'. Affinity-map definitions are used in @@ -517,7 +522,7 @@ level. Segment-Routing prefixes must be configured for the Flex-Algo. admin-group 'bit-position' is set 1, else it is set to 0. The following commands configure Flex-Algo at the 'router isis' and -'flexible-algorithm (128-255)' configuration level. +'flex-algo (128-255)' configuration level. .. clicmd:: advertise-definition From 2661c0f62b4c6b2b85d68ed972885085788c8fd2 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 7 May 2024 02:40:27 +0000 Subject: [PATCH 077/472] mgmtd: some cleanup from original RPC commit - Fix memleak on multiple errstr returns (multiple clients) Allow the - multiple clients to all return results and merge them (as with other operations like get tree). Signed-off-by: Christian Hopps --- mgmtd/mgmt_txn.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 25376c16576f..0a80b3bbf7f3 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -2695,8 +2695,10 @@ int mgmt_txn_notify_error(struct mgmt_be_client_adapter *adapter, case MGMTD_TXN_PROC_RPC: rpc = txn_req->req.rpc; rpc->recv_clients |= (1u << id); - rpc->errstr = XSTRDUP(MTYPE_MGMTD_ERR, errstr); - + if (errstr) { + XFREE(MTYPE_MGMTD_ERR, rpc->errstr); + rpc->errstr = XSTRDUP(MTYPE_MGMTD_ERR, errstr); + } /* check if done yet */ if (rpc->recv_clients != rpc->sent_clients) return 0; @@ -2798,8 +2800,9 @@ int mgmt_txn_notify_rpc_reply(struct mgmt_be_client_adapter *adapter, struct mgmt_txn_ctx *txn = mgmt_txn_id2ctx(txn_id); struct mgmt_txn_req *txn_req; struct txn_req_rpc *rpc; + struct lyd_node *tree; size_t data_len = msg_len - sizeof(*reply_msg); - LY_ERR err; + LY_ERR err = LY_SUCCESS; if (!txn) { __log_err("RPC reply from %s for a missing txn-id %" PRIu64, @@ -2820,22 +2823,34 @@ int mgmt_txn_notify_rpc_reply(struct mgmt_be_client_adapter *adapter, rpc = txn_req->req.rpc; - /* we don't expect more than one daemon to provide output for an RPC */ - if (!rpc->client_results && data_len > 0) { + tree = NULL; + if (data_len) err = yang_parse_rpc(rpc->xpath, reply_msg->result_type, - reply_msg->data, true, - &rpc->client_results); + reply_msg->data, true, &tree); + if (err) { + __log_err("RPC reply from %s for txn-id %" PRIu64 + " req_id %" PRIu64 " error parsing result of type %u: %s", + adapter->name, txn_id, req_id, reply_msg->result_type, + ly_strerrcode(err)); + } + if (!err && tree) { + if (!rpc->client_results) + rpc->client_results = tree; + else + err = lyd_merge_siblings(&rpc->client_results, tree, + LYD_MERGE_DESTRUCT); if (err) { __log_err("RPC reply from %s for txn-id %" PRIu64 - " req_id %" PRIu64 - " error parsing result of type %u", + " req_id %" PRIu64 " error merging result: %s", adapter->name, txn_id, req_id, - reply_msg->result_type); - rpc->errstr = - XSTRDUP(MTYPE_MGMTD_ERR, - "Cannot parse result from the backend"); + ly_strerrcode(err)); } } + if (err) { + XFREE(MTYPE_MGMTD_ERR, rpc->errstr); + rpc->errstr = XSTRDUP(MTYPE_MGMTD_ERR, + "Cannot parse result from the backend"); + } rpc->recv_clients |= (1u << id); From 74f43b720a7d4c96f0fee8a78498d855db879e66 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 7 May 2024 23:07:42 +0200 Subject: [PATCH 078/472] lib: stick `XREF_SETUP` into libfrrzmq Didn't catch this one when adding the warning/error (with -Werror) for missing this. Neither the CI nor I build with ZeroMQ enabled :(. Signed-off-by: David Lamparter --- lib/frr_zmq.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/frr_zmq.c b/lib/frr_zmq.c index b28dd7f1bbc5..5273d3697443 100644 --- a/lib/frr_zmq.c +++ b/lib/frr_zmq.c @@ -21,6 +21,8 @@ #include "log.h" #include "lib_errors.h" +XREF_SETUP(); + DEFINE_MTYPE_STATIC(LIB, ZEROMQ_CB, "ZeroMQ callback"); /* libzmq's context */ From 290c6e3184a8f6c4c5c39fc45dcec81508e3858b Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Sun, 7 Apr 2024 12:27:20 +0200 Subject: [PATCH 079/472] lib: libyang.so.3 compatibilty layers Let's support libyang 2.2.8 using libyang.so.3.0.8 It requires the commit ed277585ea from the libyang. Signed-off-by: Vincent Jardin --- lib/vty.c | 24 ++++++++++++++++++------ lib/yang.c | 54 +++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/lib/vty.c b/lib/vty.c index d69b5eebd270..b4cac81d8d49 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -39,6 +39,7 @@ #include "libfrr.h" #include "frrstr.h" #include "lib_errors.h" +#include #include "northbound_cli.h" #include "printfrr.h" #include "json.h" @@ -3670,15 +3671,24 @@ static ssize_t vty_mgmt_libyang_print(void *user_data, const void *buf, } static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format, - struct ly_err_item *ei) + const struct ly_err_item *ei) { +#if (LY_VERSION_MAJOR < 3) +#define data_path path +#else +#define data_path data_path +#endif bool have_apptag = ei->apptag && ei->apptag[0] != 0; - bool have_path = ei->path && ei->path[0] != 0; + bool have_path = ei->data_path && ei->data_path[0] != 0; bool have_msg = ei->msg && ei->msg[0] != 0; const char *severity = NULL; const char *evalid = NULL; const char *ecode = NULL; +#if (LY_VERSION_MAJOR < 3) LY_ERR err = ei->no; +#else + LY_ERR err = ei->err; +#endif if (ei->level == LY_LLERR) severity = "error"; @@ -3703,7 +3713,8 @@ static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format, vty_out(vty, "%s\n", evalid); if (have_path) - vty_out(vty, "%s\n", ei->path); + vty_out(vty, "%s\n", + ei->data_path); if (have_apptag) vty_out(vty, "%s\n", ei->apptag); @@ -3722,7 +3733,7 @@ static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format, if (evalid) vty_out(vty, ", \"error-validation\": \"%s\"", evalid); if (have_path) - vty_out(vty, ", \"error-path\": \"%s\"", ei->path); + vty_out(vty, ", \"error-path\": \"%s\"", ei->data_path); if (have_apptag) vty_out(vty, ", \"error-app-tag\": \"%s\"", ei->apptag); if (have_msg) @@ -3739,18 +3750,19 @@ static void vty_out_yang_error(struct vty *vty, LYD_FORMAT format, if (evalid) vty_out(vty, " invalid: %s", evalid); if (have_path) - vty_out(vty, " path: %s", ei->path); + vty_out(vty, " path: %s", ei->data_path); if (have_apptag) vty_out(vty, " app-tag: %s", ei->apptag); if (have_msg) vty_out(vty, " msg: %s", ei->msg); break; } +#undef data_path } static uint vty_out_yang_errors(struct vty *vty, LYD_FORMAT format) { - struct ly_err_item *ei = ly_err_first(ly_native_ctx); + const struct ly_err_item *ei = ly_err_first(ly_native_ctx); uint count; if (!ei) diff --git a/lib/yang.c b/lib/yang.c index 013a7628424a..30b3d681a220 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -11,6 +11,7 @@ #include "lib_errors.h" #include "yang.h" #include "yang_translator.h" +#include #include "northbound.h" #include "frrstr.h" @@ -19,6 +20,17 @@ DEFINE_MTYPE_STATIC(LIB, YANG_MODULE, "YANG module"); DEFINE_MTYPE_STATIC(LIB, YANG_DATA, "YANG data structure"); +/* Safe to remove after libyang 2.2.8 */ +#if (LY_VERSION_MAJOR < 3) +#define yang_lyd_find_xpath3(ctx_node, tree, xpath, format, prefix_data, vars, \ + set) \ + lyd_find_xpath3(ctx_node, tree, xpath, vars, set) +#else +#define yang_lyd_find_xpath3(ctx_node, tree, xpath, format, prefix_data, vars, \ + set) \ + lyd_find_xpath3(ctx_node, tree, xpath, LY_VALUE_JSON, NULL, vars, set) +#endif + /* libyang container. */ struct ly_ctx *ly_native_ctx; @@ -702,7 +714,12 @@ struct yang_data *yang_data_list_find(const struct list *list, } /* Make libyang log its errors using FRR logging infrastructure. */ -static void ly_log_cb(LY_LOG_LEVEL level, const char *msg, const char *path) +static void ly_zlog_cb(LY_LOG_LEVEL level, const char *msg, const char *data_path +#if !(LY_VERSION_MAJOR < 3) + , + const char *schema_path, uint64_t line +#endif +) { int priority = LOG_ERR; @@ -719,8 +736,14 @@ static void ly_log_cb(LY_LOG_LEVEL level, const char *msg, const char *path) break; } - if (path) - zlog(priority, "libyang: %s (%s)", msg, path); + if (data_path) + zlog(priority, "libyang: %s (%s)", msg, data_path); +#if !(LY_VERSION_MAJOR < 3) + else if (schema_path) + zlog(priority, "libyang %s (%s)\n", msg, schema_path); + else if (line) + zlog(priority, "libyang %s (line %" PRIu64 ")\n", msg, line); +#endif else zlog(priority, "libyang: %s", msg); } @@ -747,7 +770,8 @@ LY_ERR yang_parse_notification(const char *xpath, LYD_FORMAT format, return err; } - err = lyd_find_xpath3(NULL, tree, xpath, NULL, &set); + err = yang_lyd_find_xpath3(NULL, tree, xpath, LY_VALUE_JSON, NULL, NULL, + &set); if (err) { zlog_err("Failed to parse notification: %s", ly_last_errmsg()); lyd_free_all(tree); @@ -840,23 +864,29 @@ char *yang_convert_lyd_format(const char *data, size_t data_len, const char *yang_print_errors(struct ly_ctx *ly_ctx, char *buf, size_t buf_len) { - struct ly_err_item *ei; + const struct ly_err_item *ei; ei = ly_err_first(ly_ctx); if (!ei) return ""; strlcpy(buf, "YANG error(s):\n", buf_len); +#if (LY_VERSION_MAJOR < 3) +#define data_path path +#else +#define data_path data_path +#endif for (; ei; ei = ei->next) { - if (ei->path) { + if (ei->data_path) { strlcat(buf, " Path: ", buf_len); - strlcat(buf, ei->path, buf_len); + strlcat(buf, ei->data_path, buf_len); strlcat(buf, "\n", buf_len); } strlcat(buf, " Error: ", buf_len); strlcat(buf, ei->msg, buf_len); strlcat(buf, "\n", buf_len); } +#undef data_path ly_err_clean(ly_ctx, NULL); @@ -908,7 +938,12 @@ struct ly_ctx *yang_ctx_new_setup(bool embedded_modules, bool explicit_compile) void yang_init(bool embedded_modules, bool defer_compile) { /* Initialize libyang global parameters that affect all containers. */ - ly_set_log_clb(ly_log_cb, 1); + ly_set_log_clb(ly_zlog_cb +#if (LY_VERSION_MAJOR < 3) + , + 1 +#endif + ); ly_log_options(LY_LOLOG | LY_LOSTORE); /* Initialize libyang container for native models. */ @@ -1246,7 +1281,8 @@ LY_ERR yang_lyd_trim_xpath(struct lyd_node **root, const char *xpath) *root = lyd_first_sibling(*root); - err = lyd_find_xpath3(NULL, *root, xpath, NULL, &set); + err = yang_lyd_find_xpath3(NULL, *root, xpath, LY_VALUE_JSON, NULL, + NULL, &set); if (err) { flog_err_sys(EC_LIB_LIBYANG, "cannot obtain specific result for xpath \"%s\": %s", From 9fd31367b42aa13983eca97958efc658f3bdbb19 Mon Sep 17 00:00:00 2001 From: Vincent JARDIN Date: Fri, 3 May 2024 19:01:27 +0200 Subject: [PATCH 080/472] debian: libyang3 libyang3-dev is required. TODO: add redhat, snapcraft Suggested-by: Martin Winter Signed-off-by: Vincent Jardin --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index e6d65133d3eb..12b80a77f362 100644 --- a/debian/control +++ b/debian/control @@ -23,7 +23,7 @@ Build-Depends: bison, librtr-dev (>= 0.8.0~) , libsnmp-dev, libssh-dev , - libyang2-dev (>= 2.1.128), + libyang2-dev (>= 2.1.128) | libyang-dev ( >= 3.0.3), lsb-base, pkg-config, protobuf-c-compiler, From a8db605731412abb5579a41efdf0361b7087eeb9 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 8 May 2024 17:02:15 +0300 Subject: [PATCH 081/472] bgpd: Remove redundant recursion flag variable Reuse an existing one. Signed-off-by: Donatas Abraitis --- bgpd/bgp_zebra.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 52c75a3dc213..e219dc536ccd 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1537,7 +1537,6 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, route_tag_t tag; bool is_add; uint32_t nhg_id = 0; - uint32_t recursion_flag = 0; struct bgp_table *table = bgp_dest_table(dest); const struct prefix *p = bgp_dest_get_prefix(dest); @@ -1655,11 +1654,8 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, api.metric, api.tag, api.nexthop_num, nhg_id); bgp_debug_zebra_nh(&api); - if (CHECK_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION)) - recursion_flag = 1; - zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)", - __func__, p, (recursion_flag ? "" : "NOT ")); + __func__, p, (allow_recursion ? "" : "NOT ")); } return zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient, &api); From b564c1d890aef75067db22df09e608faf72b99f5 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 14 Apr 2023 17:17:27 +0200 Subject: [PATCH 082/472] pimd: fix dr-priority range 0 is a valid DR priority. Signed-off-by: David Lamparter --- doc/user/pim.rst | 2 +- doc/user/pimv6.rst | 2 +- pimd/pim6_cmd.c | 4 ++-- pimd/pim_cmd.c | 4 ++-- yang/frr-pim.yang | 4 +--- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 80a6a2787c83..b19bb9d1b3ad 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -211,7 +211,7 @@ is in a vrf, enter the interface command with the vrf keyword at the end. messages. This is enabled by default. 'no' form of this command is used to restrict processing of unicast bsm messages on this interface. -.. clicmd:: ip pim drpriority (1-4294967295) +.. clicmd:: ip pim drpriority (0-4294967295) Set the DR Priority for the interface. This command is useful to allow the user to influence what node becomes the DR for a lan segment. diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst index d550c8e89ca9..b8567e4863ae 100644 --- a/doc/user/pimv6.rst +++ b/doc/user/pimv6.rst @@ -135,7 +135,7 @@ is in a vrf, enter the interface command with the vrf keyword at the end. command will not do anything if you do not have the underlying ability of a mlag implementation. -.. clicmd:: ipv6 pim drpriority (1-4294967295) +.. clicmd:: ipv6 pim drpriority (0-4294967295) Set the DR Priority for the interface. This command is useful to allow the user to influence what node becomes the DR for a lan segment. diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index 4db11572d8eb..ec912700d193 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -244,7 +244,7 @@ DEFPY (interface_no_ipv6_pim, DEFPY (interface_ipv6_pim_drprio, interface_ipv6_pim_drprio_cmd, - "ipv6 pim drpriority (1-4294967295)", + "ipv6 pim drpriority (0-4294967295)", IPV6_STR PIM_STR "Set the Designated Router Election Priority\n" @@ -255,7 +255,7 @@ DEFPY (interface_ipv6_pim_drprio, DEFPY (interface_no_ipv6_pim_drprio, interface_no_ipv6_pim_drprio_cmd, - "no ipv6 pim drpriority [(1-4294967295)]", + "no ipv6 pim drpriority [(0-4294967295)]", NO_STR IPV6_STR PIM_STR diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 15d3904c3707..a2d756a96a20 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3956,7 +3956,7 @@ DEFUN (interface_no_ip_igmp_last_member_query_interval, DEFUN (interface_ip_pim_drprio, interface_ip_pim_drprio_cmd, - "ip pim drpriority (1-4294967295)", + "ip pim drpriority (0-4294967295)", IP_STR PIM_STR "Set the Designated Router Election Priority\n" @@ -3969,7 +3969,7 @@ DEFUN (interface_ip_pim_drprio, DEFUN (interface_no_ip_pim_drprio, interface_no_ip_pim_drprio_cmd, - "no ip pim drpriority [(1-4294967295)]", + "no ip pim drpriority [(0-4294967295)]", NO_STR IP_STR PIM_STR diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang index e9b3f675073d..732a38a9e3ae 100644 --- a/yang/frr-pim.yang +++ b/yang/frr-pim.yang @@ -422,9 +422,7 @@ module frr-pim { } leaf dr-priority { - type uint32 { - range "1..max"; - } + type uint32; default 1; description "DR (Designated Router) priority"; From dce38da8061a7ac62c690dbb8a89cae7f9a758d6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 17 Apr 2023 11:47:08 +0200 Subject: [PATCH 083/472] pimd: fix null register before aging out reg-stop It looks like the code was trying to do this with the null_register parameter on pim_upstream_start_register_stop_timer(), but that didn't quite work right. Restructure a bit to get it right. Signed-off-by: David Lamparter --- pimd/pim_register.c | 4 +-- pimd/pim_upstream.c | 65 ++++++++++++++++++++++++++++++++------------- pimd/pim_upstream.h | 3 +-- 3 files changed, 49 insertions(+), 23 deletions(-) diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 01da699dbd17..b149b5a2a97c 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -109,12 +109,12 @@ static void pim_reg_stop_upstream(struct pim_instance *pim, up->reg_state = PIM_REG_PRUNE; pim_channel_del_oif(up->channel_oil, pim->regiface, PIM_OIF_FLAG_PROTO_PIM, __func__); - pim_upstream_start_register_stop_timer(up, 0); + pim_upstream_start_register_probe_timer(up); pim_vxlan_update_sg_reg_state(pim, up, false); break; case PIM_REG_JOIN_PENDING: up->reg_state = PIM_REG_PRUNE; - pim_upstream_start_register_stop_timer(up, 0); + pim_upstream_start_register_probe_timer(up); return; } } diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 556d25b82218..7417f311377f 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -1687,6 +1687,8 @@ const char *pim_reg_state2str(enum pim_reg_state reg_state, char *state_str, return state_str; } +static void pim_upstream_start_register_stop_timer(struct pim_upstream *up); + static void pim_upstream_register_stop_timer(struct event *t) { struct pim_interface *pim_ifp; @@ -1734,7 +1736,7 @@ static void pim_upstream_register_stop_timer(struct event *t) return; } up->reg_state = PIM_REG_JOIN_PENDING; - pim_upstream_start_register_stop_timer(up, 1); + pim_upstream_start_register_stop_timer(up); if (((up->channel_oil->cc.lastused / 100) > pim->keep_alive_time) @@ -1752,34 +1754,59 @@ static void pim_upstream_register_stop_timer(struct event *t) } } -void pim_upstream_start_register_stop_timer(struct pim_upstream *up, - int null_register) +static void pim_upstream_start_register_stop_timer(struct pim_upstream *up) { uint32_t time; EVENT_OFF(up->t_rs_timer); - if (!null_register) { - uint32_t lower = (0.5 * router->register_suppress_time); - uint32_t upper = (1.5 * router->register_suppress_time); - time = lower + (frr_weak_random() % (upper - lower + 1)); - /* Make sure we don't wrap around */ - if (time >= router->register_probe_time) - time -= router->register_probe_time; - else - time = 0; - } else - time = router->register_probe_time; + time = router->register_probe_time; - if (PIM_DEBUG_PIM_TRACE) { - zlog_debug( - "%s: (S,G)=%s Starting upstream register stop timer %d", - __func__, up->sg_str, time); - } + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("%s: (S,G)=%s Starting upstream register stop timer %d", + __func__, up->sg_str, time); event_add_timer(router->master, pim_upstream_register_stop_timer, up, time, &up->t_rs_timer); } +static void pim_upstream_register_probe_timer(struct event *t) +{ + struct pim_upstream *up = EVENT_ARG(t); + + if (!up->rpf.source_nexthop.interface || + !up->rpf.source_nexthop.interface->info) { + if (PIM_DEBUG_PIM_REG) + zlog_debug("cannot send Null register for %pSG, no path to RP", + &up->sg); + } else + pim_null_register_send(up); + + pim_upstream_start_register_stop_timer(up); +} + +void pim_upstream_start_register_probe_timer(struct pim_upstream *up) +{ + uint32_t time; + + EVENT_OFF(up->t_rs_timer); + + uint32_t lower = (0.5 * router->register_suppress_time); + uint32_t upper = (1.5 * router->register_suppress_time); + time = lower + (frr_weak_random() % (upper - lower + 1)); + /* Make sure we don't wrap around */ + if (time >= router->register_probe_time) + time -= router->register_probe_time; + else + time = 0; + + if (PIM_DEBUG_PIM_TRACE) + zlog_debug("%s: (S,G)=%s Starting upstream register stop null probe timer %d", + __func__, up->sg_str, time); + + event_add_timer(router->master, pim_upstream_register_probe_timer, up, + time, &up->t_rs_timer); +} + int pim_upstream_inherited_olist_decide(struct pim_instance *pim, struct pim_upstream *up) { diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index 62649cd949fd..8b4a35be398c 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -331,8 +331,7 @@ int pim_upstream_is_sg_rpt(struct pim_upstream *up); void pim_upstream_set_sptbit(struct pim_upstream *up, struct interface *incoming); -void pim_upstream_start_register_stop_timer(struct pim_upstream *up, - int null_register); +void pim_upstream_start_register_probe_timer(struct pim_upstream *up); void pim_upstream_send_join(struct pim_upstream *up); From fdb1a6fed5a8e42447b5b9633ad9df0f3042d0a9 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 12 Dec 2022 17:50:59 +0100 Subject: [PATCH 084/472] pimd: fix order of operations for evaluating join join_desired looks at whether up->channel_oil is empty. up->channel_oil is updated from pim_forward_stop(), calling pim_channel_del_oif(). But that was being called *after* updating join_desired, so join_desired saw a non-empty OIL. Pull up the pim_forward_stop() call to before updating join_desired. Signed-off-by: David Lamparter --- pimd/pim_ifchannel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index da5518994193..8f9e41039ae6 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -342,6 +342,13 @@ void pim_ifchannel_ifjoin_switch(const char *caller, struct pim_ifchannel *ch, ch->sg_str, ch->interface->name); } + /* pim_upstream_update_join_desired looks at up->channel_oil, + * but that's updated from pim_forward_stop(). Need this here + * so we correctly determine join_desired right below. + */ + if (new_state == PIM_IFJOIN_NOINFO) + pim_forward_stop(ch); + /* Record uptime of state transition to/from NOINFO */ @@ -619,7 +626,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, pim_sgaddr *sg, static void ifjoin_to_noinfo(struct pim_ifchannel *ch) { pim_ifchannel_ifjoin_switch(__func__, ch, PIM_IFJOIN_NOINFO); - pim_forward_stop(ch); PIM_UPSTREAM_FLAG_UNSET_SRC_PIM(ch->upstream->flags); From f39761e793c75d6f345c6c28c6833f653c1f71c1 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 8 May 2024 21:47:14 +0200 Subject: [PATCH 085/472] build: make clang-format ignore DEFUN/DEFPY This makes clang-format not wreck all our hand-formatted DEFUN/DEFPY statements. We apparently missed this option when we originally looked at setting up the .clang-format control file... Signed-off-by: David Lamparter --- .clang-format | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.clang-format b/.clang-format index 93ad18b98a49..06769c966152 100644 --- a/.clang-format +++ b/.clang-format @@ -207,4 +207,21 @@ SpacesInSquareBrackets: false Standard: Cpp03 TabWidth: 8 UseTab: Always +WhitespaceSensitiveMacros: + - "DEFPY" + - "DEFPY_HIDDEN" + - "DEFPY_NOSH" + - "DEFPY_YANG" + - "DEFPY_YANG_HIDDEN" + - "DEFPY_YANG_NOSH" + - "DEFSH" + - "DEFSH_HIDDEN" + - "DEFUN" + - "DEFUN_HIDDEN" + - "DEFUN_NOSH" + - "DEFUN_YANG" + - "DEFUN_YANG_HIDDEN" + - "DEFUN_YANG_NOSH" + - "DEFUNSH" + - "DEFUNSH_HIDDEN" ... From a8f20f504ce93bc2973dfa768812582331128479 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Thu, 9 May 2024 00:15:58 -0400 Subject: [PATCH 086/472] mgmtd: add missing diagnostic show cmd output (notify maps) - also add missing rpc client accounting bug in same diagnostic command. Signed-off-by: Christian Hopps --- mgmtd/mgmt_be_adapter.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index fadeafa408e1..81574d1a56cf 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -1073,6 +1073,11 @@ void mgmt_be_xpath_register_write(struct vty *vty) darr_foreach_p (be_oper_xpath_map, map) be_show_xpath_register(vty, map); + vty_out(vty, "\nMGMTD Backend NOTIFY XPath Registry: Count: %u\n", + darr_len(be_notif_xpath_map)); + darr_foreach_p (be_notif_xpath_map, map) + be_show_xpath_register(vty, map); + vty_out(vty, "\nMGMTD Backend RPC XPath Registry: Count: %u\n", darr_len(be_rpc_xpath_map)); darr_foreach_p (be_rpc_xpath_map, map) @@ -1083,21 +1088,25 @@ void mgmt_be_show_xpath_registries(struct vty *vty, const char *xpath) { enum mgmt_be_client_id id; struct mgmt_be_client_adapter *adapter; - uint64_t cclients, oclients, rclients, combined; + uint64_t cclients, nclients, oclients, rclients, combined; cclients = mgmt_be_interested_clients(xpath, MGMT_BE_XPATH_SUBSCR_TYPE_CFG); oclients = mgmt_be_interested_clients(xpath, MGMT_BE_XPATH_SUBSCR_TYPE_OPER); + nclients = mgmt_be_interested_clients(xpath, + MGMT_BE_XPATH_SUBSCR_TYPE_NOTIF); rclients = mgmt_be_interested_clients(xpath, MGMT_BE_XPATH_SUBSCR_TYPE_RPC); - combined = cclients | oclients; + combined = cclients | nclients | oclients | rclients; vty_out(vty, "XPath: '%s'\n", xpath); FOREACH_BE_CLIENT_BITS (id, combined) { - vty_out(vty, " -- Client: '%s'\tconfig:%d oper:%d rpc:%d\n", + vty_out(vty, + " -- Client: '%s'\tconfig:%d notify:%d oper:%d rpc:%d\n", mgmt_be_client_id2name(id), IS_IDBIT_SET(cclients, id), - IS_IDBIT_SET(oclients, id), IS_IDBIT_SET(rclients, id)); + IS_IDBIT_SET(nclients, id), IS_IDBIT_SET(oclients, id), + IS_IDBIT_SET(rclients, id)); adapter = mgmt_be_get_adapter_by_id(id); if (adapter) vty_out(vty, " -- Adapter: %p\n", adapter); From 65e01119be288922deeca09f53a410ecfee1e6c2 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 8 May 2024 09:45:56 +0200 Subject: [PATCH 087/472] bgpd: Fix SRv6 memory leaks spotted by ASAN Fix a couple of memory leaks spotted by Address Sanitizer: ``` ================================================================= ==970960==ERROR: LeakSanitizer: detected memory leaks Direct leak of 592 byte(s) in 2 object(s) allocated from: #0 0xfeb98b28a4b4 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 #1 0xfeb98ae572f8 in qcalloc lib/memory.c:105 #2 0xfeb98ae76138 in srv6_locator_chunk_alloc lib/srv6.c:138 #3 0xb7f3c8508fa0 in ensure_vrf_tovpn_sid_per_vrf bgpd/bgp_mplsvpn.c:831 #4 0xb7f3c8509494 in ensure_vrf_tovpn_sid bgpd/bgp_mplsvpn.c:866 #5 0xb7f3c85028a8 in vpn_leak_postchange bgpd/bgp_mplsvpn.h:289 #6 0xb7f3c851a7c0 in vpn_leak_postchange_all bgpd/bgp_mplsvpn.c:3769 #7 0xb7f3c86f6ef0 in bgp_zebra_process_srv6_locator_chunk bgpd/bgp_zebra.c:3378 #8 0xfeb98afa6e14 in zclient_read lib/zclient.c:4608 #9 0xfeb98af3d684 in event_call lib/event.c:2011 #10 0xfeb98ae2788c in frr_run lib/libfrr.c:1217 #11 0xb7f3c83cbf0c in main bgpd/bgp_main.c:545 #12 0xfeb98a8973f8 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #13 0xfeb98a8974c8 in __libc_start_main_impl ../csu/libc-start.c:392 #14 0xb7f3c83c832c in _start (/usr/lib/frr/bgpd+0x2d832c) Direct leak of 32 byte(s) in 2 object(s) allocated from: #0 0xfeb98b28a4b4 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 #1 0xfeb98ae572f8 in qcalloc lib/memory.c:105 #2 0xb7f3c8508fd8 in ensure_vrf_tovpn_sid_per_vrf bgpd/bgp_mplsvpn.c:832 #3 0xb7f3c8509494 in ensure_vrf_tovpn_sid bgpd/bgp_mplsvpn.c:866 #4 0xb7f3c85028a8 in vpn_leak_postchange bgpd/bgp_mplsvpn.h:289 #5 0xb7f3c851a7c0 in vpn_leak_postchange_all bgpd/bgp_mplsvpn.c:3769 #6 0xb7f3c86f6ef0 in bgp_zebra_process_srv6_locator_chunk bgpd/bgp_zebra.c:3378 #7 0xfeb98afa6e14 in zclient_read lib/zclient.c:4608 #8 0xfeb98af3d684 in event_call lib/event.c:2011 #9 0xfeb98ae2788c in frr_run lib/libfrr.c:1217 #10 0xb7f3c83cbf0c in main bgpd/bgp_main.c:545 #11 0xfeb98a8973f8 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #12 0xfeb98a8974c8 in __libc_start_main_impl ../csu/libc-start.c:392 #13 0xb7f3c83c832c in _start (/usr/lib/frr/bgpd+0x2d832c) Direct leak of 32 byte(s) in 2 object(s) allocated from: #0 0xfeb98b28a4b4 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 #1 0xfeb98ae572f8 in qcalloc lib/memory.c:105 #2 0xb7f3c8506520 in vpn_leak_zebra_vrf_sid_update_per_vrf bgpd/bgp_mplsvpn.c:439 #3 0xb7f3c85068d8 in vpn_leak_zebra_vrf_sid_update bgpd/bgp_mplsvpn.c:459 #4 0xb7f3c86f6aec in bgp_ifp_create bgpd/bgp_zebra.c:3345 #5 0xfeb98adfd3f8 in hook_call_if_real lib/if.c:48 #6 0xfeb98adfe750 in if_new_via_zapi lib/if.c:181 #7 0xfeb98af98084 in zclient_interface_add lib/zclient.c:2592 #8 0xfeb98afa6d24 in zclient_read lib/zclient.c:4606 #9 0xfeb98af3d684 in event_call lib/event.c:2011 #10 0xfeb98ae2788c in frr_run lib/libfrr.c:1217 #11 0xb7f3c83cbf0c in main bgpd/bgp_main.c:545 #12 0xfeb98a8973f8 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #13 0xfeb98a8974c8 in __libc_start_main_impl ../csu/libc-start.c:392 #14 0xb7f3c83c832c in _start (/usr/lib/frr/bgpd+0x2d832c) SUMMARY: AddressSanitizer: 656 byte(s) leaked in 6 allocation(s). ``` Signed-off-by: Carmine Scarpitta --- bgpd/bgpd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index cd083d889a9a..c133e02c73b3 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1473,6 +1473,15 @@ static void bgp_srv6_init(struct bgp *bgp) static void bgp_srv6_cleanup(struct bgp *bgp) { + if (bgp->tovpn_sid_locator != NULL) + srv6_locator_chunk_free(&bgp->tovpn_sid_locator); + if (bgp->tovpn_zebra_vrf_sid_last_sent != NULL) + XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_zebra_vrf_sid_last_sent); + if (bgp->tovpn_sid != NULL) { + sid_unregister(bgp, bgp->tovpn_sid); + XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_sid); + } + if (bgp->srv6_locator_chunks) list_delete(&bgp->srv6_locator_chunks); if (bgp->srv6_functions) From 165caaeea8b04b6ac59c9016f1d5240238200a27 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 8 May 2024 09:48:55 +0200 Subject: [PATCH 088/472] bgpd: Move SRv6 cleanup functions Move SRv6 cleanup operations to `bgp_srv6_cleanup` function. Signed-off-by: Carmine Scarpitta --- bgpd/bgpd.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c133e02c73b3..76014d4eb95e 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1473,6 +1473,20 @@ static void bgp_srv6_init(struct bgp *bgp) static void bgp_srv6_cleanup(struct bgp *bgp) { + for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) { + if (bgp->vpn_policy[afi].tovpn_sid_locator != NULL) + srv6_locator_chunk_free( + &bgp->vpn_policy[afi].tovpn_sid_locator); + if (bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent != NULL) + XFREE(MTYPE_BGP_SRV6_SID, + bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent); + if (bgp->vpn_policy[afi].tovpn_sid != NULL) { + sid_unregister(bgp, bgp->vpn_policy[afi].tovpn_sid); + XFREE(MTYPE_BGP_SRV6_SID, + bgp->vpn_policy[afi].tovpn_sid); + } + } + if (bgp->tovpn_sid_locator != NULL) srv6_locator_chunk_free(&bgp->tovpn_sid_locator); if (bgp->tovpn_zebra_vrf_sid_last_sent != NULL) @@ -4145,18 +4159,6 @@ void bgp_free(struct bgp *bgp) if (bgp->vpn_policy[afi].tovpn_rd_pretty) XFREE(MTYPE_BGP_NAME, bgp->vpn_policy[afi].tovpn_rd_pretty); - if (bgp->vpn_policy[afi].tovpn_sid_locator != NULL) - srv6_locator_chunk_free( - &bgp->vpn_policy[afi].tovpn_sid_locator); - if (bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent != NULL) - XFREE(MTYPE_BGP_SRV6_SID, - bgp->vpn_policy[afi] - .tovpn_zebra_vrf_sid_last_sent); - if (bgp->vpn_policy[afi].tovpn_sid != NULL) { - sid_unregister(bgp, bgp->vpn_policy[afi].tovpn_sid); - XFREE(MTYPE_BGP_SRV6_SID, - bgp->vpn_policy[afi].tovpn_sid); - } } bgp_srv6_cleanup(bgp); bgp_confederation_id_unset(bgp); From 0939f77b3998aed7a5d81f9d8afaba2370d1db26 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Thu, 9 May 2024 04:19:44 -0400 Subject: [PATCH 089/472] tests: fix mis-spelled `cryptographic-algorithm` keyword in test Also update to use a newer hashing function while we are here. fixes #15923 Signed-off-by: Christian Hopps --- tests/topotests/key_sendaccept/test_keychain.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/topotests/key_sendaccept/test_keychain.py b/tests/topotests/key_sendaccept/test_keychain.py index 111e88aca7cb..b11d31b981a6 100644 --- a/tests/topotests/key_sendaccept/test_keychain.py +++ b/tests/topotests/key_sendaccept/test_keychain.py @@ -62,7 +62,7 @@ def test_send_accept(tgen): key chain kc key 1 key-string theSecret - crypto-algorithm md5 + cryptographic-algorithm hmac-sha-256 exit exit """ @@ -74,7 +74,7 @@ def test_send_accept(tgen): key chain kc key 1 key-string theSecret - crypto-algorithm md5 + cryptographic-algorithm hmac-sha-256 send-lifetime 00:00:00 Jan 1 2024 infinite accept-lifetime 00:00:00 Jan 1 2024 infinite exit @@ -101,7 +101,7 @@ def test_send_accept(tgen): key chain kc key 2 key-string theSecret - crypto-algorithm md5 + cryptographic-algorithm hmac-sha-256 send-lifetime 00:00:00 Jan 1 2024 duration {secs_in_10_years} accept-lifetime 00:00:00 Jan 1 2024 duration {secs_in_10_years} exit @@ -127,7 +127,7 @@ def test_send_accept(tgen): key chain kc key 3 key-string theSecret - crypto-algorithm md5 + cryptographic-algorithm hmac-sha-256 send-lifetime 00:00:00 Jan 1 2024 23:59:59 Dec 31 2034 accept-lifetime 00:00:00 Jan 1 2024 23:59:59 Dec 31 2034 exit From 084aba4ec06d2f9df31ce1e3964d5847bd618cee Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 3 May 2024 11:59:02 -0400 Subject: [PATCH 090/472] zebra: Add 2 things to fpm_listener 1) Add ability to hex-dump the received packet for debugging 2) Receive encap type and vxlan vni and display them. Signed-off-by: Donald Sharp --- zebra/fpm_listener.c | 117 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 112 insertions(+), 5 deletions(-) diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c index 5533fa7f8be4..fed6c41631b4 100644 --- a/zebra/fpm_listener.c +++ b/zebra/fpm_listener.c @@ -31,6 +31,7 @@ #include #include +#include #include "rt_netlink.h" #include "fpm/fpm.h" @@ -42,6 +43,7 @@ struct glob { int server_sock; int sock; bool reflect; + bool dump_hex; }; struct glob glob_space; @@ -292,6 +294,8 @@ netlink_prot_to_s(unsigned char prot) struct netlink_nh { struct rtattr *gateway; int if_index; + uint16_t encap_type; + uint32_t vxlan_vni; }; struct netlink_msg_ctx { @@ -341,7 +345,7 @@ static inline void netlink_msg_ctx_set_err(struct netlink_msg_ctx *ctx, * parse_rtattrs_ */ static int parse_rtattrs_(struct rtattr *rta, size_t len, struct rtattr **rtas, - int num_rtas, const char **err_msg) + uint16_t num_rtas, const char **err_msg) { memset(rtas, 0, num_rtas * sizeof(rtas[0])); @@ -387,7 +391,8 @@ static int parse_rtattrs(struct netlink_msg_ctx *ctx, struct rtattr *rta, * netlink_msg_ctx_add_nh */ static int netlink_msg_ctx_add_nh(struct netlink_msg_ctx *ctx, int if_index, - struct rtattr *gateway) + struct rtattr *gateway, uint16_t encap_type, + uint32_t vxlan_vni) { struct netlink_nh *nh; @@ -400,6 +405,9 @@ static int netlink_msg_ctx_add_nh(struct netlink_msg_ctx *ctx, int if_index, nh->gateway = gateway; nh->if_index = if_index; + + nh->encap_type = encap_type; + nh->vxlan_vni = vxlan_vni; return 1; } @@ -412,6 +420,7 @@ static int parse_multipath_attr(struct netlink_msg_ctx *ctx, size_t len; struct rtnexthop *rtnh; struct rtattr *rtattrs[RTA_MAX + 1]; + struct rtattr *tb[RTA_MAX + 1]; struct rtattr *gateway; const char *err_msg; @@ -420,6 +429,8 @@ static int parse_multipath_attr(struct netlink_msg_ctx *ctx, for (; len > 0; len -= NLMSG_ALIGN(rtnh->rtnh_len), rtnh = RTNH_NEXT(rtnh)) { + uint32_t vxlan_vni; + uint16_t encap_type; if (!RTNH_OK(rtnh, len)) { netlink_msg_ctx_set_err(ctx, "Malformed nh"); @@ -443,7 +454,27 @@ static int parse_multipath_attr(struct netlink_msg_ctx *ctx, } gateway = rtattrs[RTA_GATEWAY]; - netlink_msg_ctx_add_nh(ctx, rtnh->rtnh_ifindex, gateway); + memset(tb, 0, sizeof(tb)); + if (rtattrs[RTA_ENCAP]) { + parse_rtattrs_(RTA_DATA(rtattrs[RTA_ENCAP]), + rtattrs[RTA_ENCAP]->rta_len - + sizeof(struct rtattr), + tb, ARRAY_SIZE(tb), &err_msg); + } + + if (rtattrs[RTA_ENCAP_TYPE]) + encap_type = + *(uint16_t *)RTA_DATA(rtattrs[RTA_ENCAP_TYPE]); + else + encap_type = 0; + + if (tb[0]) + vxlan_vni = *(uint32_t *)RTA_DATA(tb[0]); + else + vxlan_vni = 0; + + netlink_msg_ctx_add_nh(ctx, rtnh->rtnh_ifindex, gateway, + encap_type, vxlan_vni); } return 1; @@ -485,11 +516,33 @@ static int parse_route_msg(struct netlink_msg_ctx *ctx) gateway = rtattrs[RTA_GATEWAY]; oif = rtattrs[RTA_OIF]; if (gateway || oif) { + struct rtattr *tb[RTA_MAX + 1] = { 0 }; + uint16_t encap_type = 0; + uint32_t vxlan_vni = 0; + if_index = 0; if (oif) if_index = *((int *)RTA_DATA(oif)); - netlink_msg_ctx_add_nh(ctx, if_index, gateway); + + if (rtattrs[RTA_ENCAP]) { + const char *err_msg; + + parse_rtattrs_(RTA_DATA(rtattrs[RTA_ENCAP]), + rtattrs[RTA_ENCAP]->rta_len - + sizeof(struct rtattr), + tb, ARRAY_SIZE(tb), &err_msg); + } + + if (rtattrs[RTA_ENCAP_TYPE]) + encap_type = + *(uint16_t *)RTA_DATA(rtattrs[RTA_ENCAP_TYPE]); + + if (tb[0]) + vxlan_vni = *(uint32_t *)RTA_DATA(tb[0]); + + netlink_msg_ctx_add_nh(ctx, if_index, gateway, encap_type, + vxlan_vni); } rtattr = rtattrs[RTA_MULTIPATH]; @@ -557,6 +610,11 @@ static int netlink_msg_ctx_snprint(struct netlink_msg_ctx *ctx, char *buf, cur += snprintf(cur, end - cur, " via interface %d", nh->if_index); } + + if (nh->encap_type) + cur += snprintf(cur, end - cur, + ", Encap Type: %u Vxlan vni %u", + nh->encap_type, nh->vxlan_vni); } return cur - buf; @@ -573,6 +631,51 @@ static void print_netlink_msg_ctx(struct netlink_msg_ctx *ctx) printf("%s\n", buf); } +static void fpm_listener_hexdump(const void *mem, size_t len) +{ + char line[64]; + const uint8_t *src = mem; + const uint8_t *end = src + len; + + if (!glob->dump_hex) + return; + + if (len == 0) { + printf("%016lx: (zero length / no data)\n", (long)src); + return; + } + + while (src < end) { + struct fbuf fb = { + .buf = line, + .pos = line, + .len = sizeof(line), + }; + const uint8_t *lineend = src + 8; + uint32_t line_bytes = 0; + + printf("%016lx: ", (long)src); + + while (src < lineend && src < end) { + printf("%02x ", *src++); + line_bytes++; + } + if (line_bytes < 8) + printf("%*s", (8 - line_bytes) * 3, ""); + + src -= line_bytes; + while (src < lineend && src < end && fb.pos < fb.buf + fb.len) { + uint8_t byte = *src++; + + if (isprint(byte)) + *fb.pos++ = byte; + else + *fb.pos++ = '.'; + } + printf("\n"); + } +} + /* * parse_netlink_msg */ @@ -582,6 +685,7 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm) struct nlmsghdr *hdr; unsigned int len; + fpm_listener_hexdump(buf, buf_len); ctx = &ctx_space; hdr = (struct nlmsghdr *)buf; @@ -667,7 +771,7 @@ int main(int argc, char **argv) memset(glob, 0, sizeof(*glob)); - while ((r = getopt(argc, argv, "rd")) != -1) { + while ((r = getopt(argc, argv, "rdv")) != -1) { switch (r) { case 'r': glob->reflect = true; @@ -675,6 +779,9 @@ int main(int argc, char **argv) case 'd': fork_daemon = true; break; + case 'v': + glob->dump_hex = true; + break; } } From ba5a3538e8b7198ac58e97c1cc6e65f7763359b2 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 8 May 2024 12:46:08 -0400 Subject: [PATCH 091/472] zebra: Move netlink_route_nexthop_encap Move this static function earlier so we can avoid a predecleartion. Signed-off-by: Donald Sharp --- zebra/rt_netlink.c | 55 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 4a15b7400496..745f6497fb2b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1891,6 +1891,33 @@ static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen, return true; } +/* + * The function returns true if the attribute could be added + * to the message, otherwise false is returned. + */ +static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, + struct nexthop *nh) +{ + struct rtattr *nest; + + switch (nh->nh_encap_type) { + case NET_VXLAN: + if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type)) + return false; + + nest = nl_attr_nest(n, nlen, RTA_ENCAP); + if (!nest) + return false; + + if (!nl_attr_put32(n, nlen, 0 /* VXLAN_VNI */, nh->nh_encap.vni)) + return false; + nl_attr_nest_end(n, nest); + break; + } + + return true; +} + /* This function takes a nexthop as argument and * appends to the given netlink msg. If the nexthop * defines a preferred source, the src parameter @@ -2149,34 +2176,6 @@ static bool nexthop_set_src(const struct nexthop *nexthop, int family, return false; } -/* - * The function returns true if the attribute could be added - * to the message, otherwise false is returned. - */ -static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, - struct nexthop *nh) -{ - struct rtattr *nest; - - switch (nh->nh_encap_type) { - case NET_VXLAN: - if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type)) - return false; - - nest = nl_attr_nest(n, nlen, RTA_ENCAP); - if (!nest) - return false; - - if (!nl_attr_put32(n, nlen, 0 /* VXLAN_VNI */, - nh->nh_encap.vni)) - return false; - nl_attr_nest_end(n, nest); - break; - } - - return true; -} - /* * Routing table change via netlink interface, using a dataplane context object * From 569f9e439418a06ac0ddf9b68cd1943cbf860d1d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 8 May 2024 12:48:12 -0400 Subject: [PATCH 092/472] zebra: Move fpm check to inside of netlink_route_nexthop_encap Signed-off-by: Donald Sharp --- zebra/rt_netlink.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 745f6497fb2b..9ac4bb9bf8bb 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1895,11 +1895,14 @@ static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen, * The function returns true if the attribute could be added * to the message, otherwise false is returned. */ -static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, - struct nexthop *nh) +static int netlink_route_nexthop_encap(bool fpm, struct nlmsghdr *n, + size_t nlen, struct nexthop *nh) { struct rtattr *nest; + if (!fpm) + return true; + switch (nh->nh_encap_type) { case NET_VXLAN: if (!nl_attr_put16(n, nlen, RTA_ENCAP_TYPE, nh->nh_encap_type)) @@ -2430,12 +2433,10 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx * Add encapsulation information when * installing via FPM. */ - if (fpm) { - if (!netlink_route_nexthop_encap(&req->n, - datalen, - nexthop)) - return 0; - } + if (!netlink_route_nexthop_encap(fpm, &req->n, + datalen, + nexthop)) + return 0; nexthop_num++; break; @@ -2490,11 +2491,10 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx * Add encapsulation information when installing via * FPM. */ - if (fpm) { - if (!netlink_route_nexthop_encap( - &req->n, datalen, nexthop)) - return 0; - } + if (!netlink_route_nexthop_encap(fpm, &req->n, + datalen, + nexthop)) + return 0; if (!setsrc && src1) { if (p->family == AF_INET) From bd4fca132abd47d1ba08eca5e5193c431f095f7a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 8 May 2024 12:52:12 -0400 Subject: [PATCH 093/472] zebra: Ensure multipath encodes vxlan right for fpm usage The fpm code path for the dplane_fpm_nl module was improperly encoding the multipath nexthop data for vxlan type routes. Move this into the embedded nexthop encoding where it belongs. This change makes it so that the usage of `-M dplane_fpm_nl` is now producing the same netlink messages that `-M fpm` produces when using vxlan based nexthops. Signed-off-by: Donald Sharp --- zebra/rt_netlink.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 9ac4bb9bf8bb..d273e26a5dc2 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1896,7 +1896,7 @@ static inline bool _netlink_set_tag(struct nlmsghdr *n, unsigned int maxlen, * to the message, otherwise false is returned. */ static int netlink_route_nexthop_encap(bool fpm, struct nlmsghdr *n, - size_t nlen, struct nexthop *nh) + size_t nlen, const struct nexthop *nh) { struct rtattr *nest; @@ -1939,10 +1939,13 @@ static int netlink_route_nexthop_encap(bool fpm, struct nlmsghdr *n, * The function returns true if the nexthop could be added * to the message, otherwise false is returned. */ -static bool _netlink_route_build_multipath( - const struct prefix *p, const char *routedesc, int bytelen, - const struct nexthop *nexthop, struct nlmsghdr *nlmsg, size_t req_size, - struct rtmsg *rtmsg, const union g_addr **src, route_tag_t tag) +static bool _netlink_route_build_multipath(const struct prefix *p, + const char *routedesc, int bytelen, + const struct nexthop *nexthop, + struct nlmsghdr *nlmsg, + size_t req_size, struct rtmsg *rtmsg, + const union g_addr **src, + route_tag_t tag, bool fpm) { char label_buf[256]; struct vrf *vrf; @@ -2050,6 +2053,13 @@ static bool _netlink_route_build_multipath( if (!_netlink_set_tag(nlmsg, req_size, tag)) return false; + /* + * Add encapsulation information when installing via + * FPM. + */ + if (!netlink_route_nexthop_encap(fpm, nlmsg, req_size, nexthop)) + return false; + nl_attr_rtnh_end(nlmsg, rtnh); return true; } @@ -2084,7 +2094,7 @@ _netlink_mpls_build_multipath(const struct prefix *p, const char *routedesc, bytelen = (family == AF_INET ? 4 : 16); return _netlink_route_build_multipath(p, routedesc, bytelen, nhlfe->nexthop, nlmsg, req_size, - rtmsg, src, 0); + rtmsg, src, 0, false); } static void _netlink_mpls_debug(int cmd, uint32_t label, const char *routedesc) @@ -2481,19 +2491,14 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx : "multipath"; nexthop_num++; - if (!_netlink_route_build_multipath( - p, routedesc, bytelen, nexthop, - &req->n, datalen, &req->r, &src1, - tag)) - return 0; - - /* - * Add encapsulation information when installing via - * FPM. - */ - if (!netlink_route_nexthop_encap(fpm, &req->n, - datalen, - nexthop)) + if (!_netlink_route_build_multipath(p, routedesc, + bytelen, + nexthop, + &req->n, + datalen, + &req->r, + &src1, tag, + fpm)) return 0; if (!setsrc && src1) { From d65280a9a8e6c894c29dd17e328b99e2aaaf8c51 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 9 May 2024 07:22:08 +0200 Subject: [PATCH 094/472] build: throw in a few more `XREF_SETUP` This really should be all of them. Signed-off-by: David Lamparter --- grpc/frrgrpc_pb.c | 9 +++++++++ grpc/subdir.am | 4 ++++ mlag/mlag_pb.c | 9 +++++++++ mlag/subdir.am | 1 + 4 files changed, 23 insertions(+) create mode 100644 grpc/frrgrpc_pb.c create mode 100644 mlag/mlag_pb.c diff --git a/grpc/frrgrpc_pb.c b/grpc/frrgrpc_pb.c new file mode 100644 index 000000000000..938d777534e3 --- /dev/null +++ b/grpc/frrgrpc_pb.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: ISC +/* + * libfrrgrpc_pb library stub source + */ + +#include "config.h" +#include "xref.h" + +XREF_SETUP(); diff --git a/grpc/subdir.am b/grpc/subdir.am index 06b37f91d611..a464edc9303b 100644 --- a/grpc/subdir.am +++ b/grpc/subdir.am @@ -10,6 +10,10 @@ nodist_grpc_libfrrgrpc_pb_la_SOURCES = \ grpc/frr-northbound.pb.cc \ grpc/frr-northbound.grpc.pb.cc \ # end + +grpc_libfrrgrpc_pb_la_SOURCES = \ + grpc/frrgrpc_pb.c \ + # end endif CLEANFILES += \ diff --git a/mlag/mlag_pb.c b/mlag/mlag_pb.c new file mode 100644 index 000000000000..01c4f0b319ee --- /dev/null +++ b/mlag/mlag_pb.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: ISC +/* + * libmlag_pb library stub + */ + +#include "config.h" +#include "xref.h" + +XREF_SETUP(); diff --git a/mlag/subdir.am b/mlag/subdir.am index 376eea8bc9b5..aa30d33431e6 100644 --- a/mlag/subdir.am +++ b/mlag/subdir.am @@ -5,6 +5,7 @@ endif mlag_libmlag_pb_la_LDFLAGS = $(LIB_LDFLAGS) -version-info 0:0:0 mlag_libmlag_pb_la_CPPFLAGS = $(AM_CPPFLAGS) $(PROTOBUF_C_CFLAGS) mlag_libmlag_pb_la_SOURCES = \ + mlag/mlag_pb.c \ # end nodist_mlag_libmlag_pb_la_SOURCES = \ From 6afb6962be3581f3a86982a896628aec1e064916 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Thu, 9 May 2024 16:56:07 -0400 Subject: [PATCH 095/472] zebra: add some more netlink RTA_ strings Add a few more RTA_ attribute names to the netlink debug output. Signed-off-by: Mark Stapp --- zebra/debug_nl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zebra/debug_nl.c b/zebra/debug_nl.c index a7cccdb98ffd..037d0b6237d2 100644 --- a/zebra/debug_nl.c +++ b/zebra/debug_nl.c @@ -534,6 +534,12 @@ const char *rtm_rta2str(int type) return "NH_ID"; case RTA_EXPIRES: return "EXPIRES"; + case RTA_VIA: + return "VIA"; + case RTA_ENCAP_TYPE: + return "RTA_ENCAP_TYPE"; + case RTA_ENCAP: + return "RTA_ENCAP"; default: return "UNKNOWN"; } From e797b137f3fa3ee608f20958bbbb8991d37e0d6d Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 8 May 2024 22:25:38 +0300 Subject: [PATCH 096/472] lib: Allow doing match/set tag untagged In route-map: `match tag untagged`. E.g. Cisco/Juniper allows that, but they use `match tag 0` instead. Signed-off-by: Donatas Abraitis --- doc/user/ripngd.rst | 2 +- doc/user/routemap.rst | 10 +++++----- lib/routemap_cli.c | 43 ++++++++++++++++++++++++++++++----------- yang/frr-route-map.yang | 2 +- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/doc/user/ripngd.rst b/doc/user/ripngd.rst index f898bed57a10..f55ee3944570 100644 --- a/doc/user/ripngd.rst +++ b/doc/user/ripngd.rst @@ -136,7 +136,7 @@ functionality. range is very large for compatibility with other protocols. For RIPng, valid metric values are from 1 to 16. -.. clicmd:: set tag (1-4294967295) +.. clicmd:: set tag Set a tag on the matched route. diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index 791762aa7b88..1d2f4e352f38 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -176,10 +176,9 @@ Route Map Match Command Matches the specified `metric`. -.. clicmd:: match tag TAG +.. clicmd:: match tag - Matches the specified tag value associated with the route. This tag value - can be in the range of (1-4294967295). + Matches the specified tag (or untagged) value associated with the route. .. clicmd:: match local-preference METRIC @@ -241,9 +240,10 @@ Route Map Set Command .. program:: configure -.. clicmd:: set tag TAG +.. clicmd:: set tag + + Set a tag on the matched route. - Set a tag on the matched route. This tag value can be from (1-4294967295). Additionally if you have compiled with the :option:`--enable-realms` configure option. Tag values from (1-255) are sent to the Linux kernel as a realm value. Then route policy can be applied. See the tc man page. As diff --git a/lib/routemap_cli.c b/lib/routemap_cli.c index a12a07c14fbc..8e2e497e0940 100644 --- a/lib/routemap_cli.c +++ b/lib/routemap_cli.c @@ -490,29 +490,33 @@ DEFPY_YANG( DEFPY_YANG( match_tag, match_tag_cmd, - "match tag (1-4294967295)$tag", + "match tag ", MATCH_STR "Match tag of route\n" + "Untagged route\n" "Tag value\n") { const char *xpath = "./match-condition[condition='frr-route-map:match-tag']"; char xpath_value[XPATH_MAXLEN]; + char value[64]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-match-condition/tag", xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str); + snprintf(value, sizeof(value), "%lu", tagged ? tagged : 0); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value); return nb_cli_apply_changes(vty, NULL); } DEFPY_YANG( no_match_tag, no_match_tag_cmd, - "no match tag [(1-4294967295)]", + "no match tag []", NO_STR MATCH_STR "Match tag of route\n" + "Untagged route\n" "Tag value\n") { const char *xpath = @@ -581,9 +585,15 @@ void route_map_condition_show(struct vty *vty, const struct lyd_node *dnode, yang_dnode_get_string(dnode, "./rmap-match-condition/metric")); } else if (IS_MATCH_TAG(condition)) { - vty_out(vty, " match tag %s\n", - yang_dnode_get_string(dnode, - "./rmap-match-condition/tag")); + uint32_t tag = + strtoul(yang_dnode_get_string(dnode, + "./rmap-match-condition/tag"), + NULL, 10); + + if (!tag) + vty_out(vty, " match tag untagged\n"); + else + vty_out(vty, " match tag %u\n", tag); } else if (IS_MATCH_IPv4_PREFIX_LEN(condition)) { vty_out(vty, " match ip address prefix-len %s\n", yang_dnode_get_string( @@ -973,28 +983,32 @@ DEFPY_YANG(no_set_max_metric, no_set_max_metric_cmd, DEFPY_YANG( set_tag, set_tag_cmd, - "set tag (1-4294967295)$tag", + "set tag ", SET_STR "Tag value for routing protocol\n" + "Untagged route\n" "Tag value\n") { const char *xpath = "./set-action[action='frr-route-map:set-tag']"; char xpath_value[XPATH_MAXLEN]; + char value[64]; nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); snprintf(xpath_value, sizeof(xpath_value), "%s/rmap-set-action/tag", xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, tag_str); + snprintf(value, sizeof(value), "%lu", tagged ? tagged : 0); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, value); return nb_cli_apply_changes(vty, NULL); } DEFPY_YANG( no_set_tag, no_set_tag_cmd, - "no set tag [(1-4294967295)]", + "no set tag []", NO_STR SET_STR "Tag value for routing protocol\n" + "Untagged route\n" "Tag value\n") { const char *xpath = "./set-action[action='frr-route-map:set-tag']"; @@ -1101,8 +1115,15 @@ void route_map_action_show(struct vty *vty, const struct lyd_node *dnode, yang_dnode_get_string(dnode, "./rmap-set-action/max-metric")); } else if (IS_SET_TAG(action)) { - vty_out(vty, " set tag %s\n", - yang_dnode_get_string(dnode, "rmap-set-action/tag")); + uint32_t tag = + strtoul(yang_dnode_get_string(dnode, + "rmap-set-action/tag"), + NULL, 10); + + if (!tag) + vty_out(vty, " set tag untagged\n"); + else + vty_out(vty, " set tag %u\n", tag); } else if (IS_SET_SR_TE_COLOR(action)) { vty_out(vty, " set sr-te color %s\n", yang_dnode_get_string(dnode, diff --git a/yang/frr-route-map.yang b/yang/frr-route-map.yang index 7cb13b60f2fc..26d56acc039b 100644 --- a/yang/frr-route-map.yang +++ b/yang/frr-route-map.yang @@ -268,7 +268,7 @@ module frr-route-map { when "derived-from-or-self(../condition, 'match-tag')"; leaf tag { type uint32 { - range "1..4294967295"; + range "0..4294967295"; } } } From adce8e066ce442cf0f4c2ba944e071a4ec2e57a0 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 10 May 2024 10:21:54 +0300 Subject: [PATCH 097/472] tests: Check if `set/match tag untagged` works Signed-off-by: Donatas Abraitis --- .../__init__.py | 0 .../r1/frr.conf | 19 +++++ .../test_bgp_route_map_match_tag_untagged.py | 83 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 tests/topotests/bgp_route_map_match_tag_untagged/__init__.py create mode 100644 tests/topotests/bgp_route_map_match_tag_untagged/r1/frr.conf create mode 100644 tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py diff --git a/tests/topotests/bgp_route_map_match_tag_untagged/__init__.py b/tests/topotests/bgp_route_map_match_tag_untagged/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_route_map_match_tag_untagged/r1/frr.conf b/tests/topotests/bgp_route_map_match_tag_untagged/r1/frr.conf new file mode 100644 index 000000000000..13eced2042a1 --- /dev/null +++ b/tests/topotests/bgp_route_map_match_tag_untagged/r1/frr.conf @@ -0,0 +1,19 @@ +! +interface r1-eth0 + ip address 192.168.1.1/24 +! +router bgp 65001 + address-family ipv4 + redistribute static route-map untagged + exit-address-family +! +ip route 10.10.10.10/32 Null0 +ip route 10.10.10.20/32 Null0 tag 20 +! +route-map untagged permit 10 + match tag untagged + set tag 10 +route-map untagged permit 20 + match tag 20 + set tag untagged +exit diff --git a/tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py b/tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py new file mode 100644 index 000000000000..7dd63fdac0b9 --- /dev/null +++ b/tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by +# Donatas Abraitis +# + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + for routern in range(1, 2): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_route_map_match_tag_untagged(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_check_advertised_routes_r2(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show bgp ipv4 unicast detail json") + ) + expected = { + "routes": { + "10.10.10.10/32": [ + { + "tag": 10, + } + ], + "10.10.10.20/32": [ + { + "tag": None, + } + ], + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_advertised_routes_r2) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Tags for static routes are not as expected" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From 73ad64a6f4b039ce482ad5c3b080e8c9bb02890f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 9 May 2024 07:47:29 -0400 Subject: [PATCH 098/472] *: Modify agentx to be allowed to be called If you had a situation where an operator turned on ospfd with snmp but not ospf6d and agentx was configured then you get into a situation where ospf6d would complain that the config for agentx did not exist. Let's modify the code to allow this situation to happen. Fixes: #15896 Signed-off-by: Donald Sharp --- bgpd/bgp_main.c | 3 +++ eigrpd/eigrp_main.c | 3 +++ isisd/isis_main.c | 2 ++ ldpd/ldpd.c | 2 ++ lib/agentx.c | 44 +++++++------------------------ lib/libagentx.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ lib/libagentx.h | 14 ++++++++++ lib/smux.h | 1 + lib/subdir.am | 2 ++ ospf6d/ospf6_main.c | 2 ++ ospfd/ospf_main.c | 2 ++ python/xref2vtysh.py | 2 +- ripd/rip_main.c | 2 ++ zebra/main.c | 2 ++ 14 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 lib/libagentx.c create mode 100644 lib/libagentx.h diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 44d5ee68cce6..2bbd3a4b1bb8 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -26,6 +26,7 @@ #include "bfd.h" #include "libfrr.h" #include "ns.h" +#include "libagentx.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_attr.h" @@ -516,8 +517,10 @@ int main(int argc, char **argv) bgp_option_set(BGP_OPT_NO_ZEBRA); bgp_error_init(); /* Initializations. */ + libagentx_init(); bgp_vrf_init(); + #ifdef HAVE_SCRIPTING bgp_script_init(); #endif diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c index d387b9be1804..319ac925337b 100644 --- a/eigrpd/eigrp_main.c +++ b/eigrpd/eigrp_main.c @@ -36,6 +36,7 @@ #include "distribute.h" #include "libfrr.h" #include "routemap.h" +#include "libagentx.h" //#include "if_rmap.h" #include "eigrpd/eigrp_structs.h" @@ -178,9 +179,11 @@ int main(int argc, char **argv, char **envp) /* EIGRP master init. */ eigrp_master_init(); + eigrp_om->master = frr_init(); master = eigrp_om->master; + libagentx_init(); eigrp_error_init(); eigrp_vrf_init(); vrf_init(NULL, NULL, NULL, NULL); diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 60ec8cdad480..8dd3a97aa1fa 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -28,6 +28,7 @@ #include "libfrr.h" #include "routemap.h" #include "affinitymap.h" +#include "libagentx.h" #include "isisd/isis_affinitymap.h" #include "isisd/isis_constants.h" @@ -307,6 +308,7 @@ int main(int argc, char **argv, char **envp) /* * initializations */ + libagentx_init(); cmd_init_config_callbacks(isis_config_start, isis_config_end); isis_error_init(); access_list_init(); diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index 492a36b3d6a1..4d38fdcd02c9 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -36,6 +36,7 @@ #include "libfrr.h" #include "lib_errors.h" #include "zlog_recirculate.h" +#include "libagentx.h" static void ldpd_shutdown(void); static pid_t start_child(enum ldpd_process, char *, int, int, int); @@ -370,6 +371,7 @@ main(int argc, char *argv[]) zlog_recirculate_subscribe(master, pipe_lde_log[0]); zlog_recirculate_subscribe(master, pipe_ldpe_log[0]); + libagentx_init(); vrf_init(NULL, NULL, NULL, NULL); access_list_init(); ldp_vty_init(); diff --git a/lib/agentx.c b/lib/agentx.c index 70ee6753ff4c..19f2a6b7fce8 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -22,12 +22,13 @@ #include "hook.h" #include "libfrr.h" #include "xref.h" +#include "lib/libagentx.h" XREF_SETUP(); DEFINE_HOOK(agentx_enabled, (), ()); -static bool agentx_enabled = false; +//bool agentx_enabled = false; static struct event_loop *agentx_tm; static struct event *timeout_thr = NULL; @@ -153,15 +154,6 @@ static void agentx_events_update(void) netsnmp_large_fd_set_cleanup(&lfds); } -/* AgentX node. */ -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, void *clientarg) @@ -201,17 +193,7 @@ static int agentx_log_callback(int major, int minor, void *serverarg, return SNMP_ERR_NOERROR; } -static int config_write_agentx(struct vty *vty) -{ - if (agentx_enabled) - vty_out(vty, "agentx\n"); - return 1; -} - -DEFUN (agentx_enable, - agentx_enable_cmd, - "agentx", - "SNMP AgentX protocol settings\n") +static int agentx_cli_on(void) { if (!agentx_enabled) { init_snmp(FRR_SMUX_NAME); @@ -221,19 +203,14 @@ DEFUN (agentx_enable, hook_call(agentx_enabled); } - return CMD_SUCCESS; + return 1; } -DEFUN (no_agentx, - no_agentx_cmd, - "no agentx", - NO_STR - "SNMP AgentX protocol settings\n") +static int agentx_cli_off(void) { if (!agentx_enabled) - return CMD_SUCCESS; - vty_out(vty, "SNMP AgentX support cannot be disabled once enabled\n"); - return CMD_WARNING_CONFIG_FAILED; + return 1; + return 0; } static int smux_disable(void) @@ -252,6 +229,9 @@ void smux_init(struct event_loop *tm) { agentx_tm = tm; + hook_register(agentx_cli_enabled, agentx_cli_on); + hook_register(agentx_cli_disabled, agentx_cli_off); + netsnmp_enable_subagent(); snmp_disable_log(); snmp_enable_calllog(); @@ -259,10 +239,6 @@ void smux_init(struct event_loop *tm) agentx_log_callback, NULL); init_agent(FRR_SMUX_NAME); - install_node(&agentx_node); - install_element(CONFIG_NODE, &agentx_enable_cmd); - install_element(CONFIG_NODE, &no_agentx_cmd); - hook_register(frr_early_fini, smux_disable); } diff --git a/lib/libagentx.c b/lib/libagentx.c new file mode 100644 index 000000000000..23826572ed11 --- /dev/null +++ b/lib/libagentx.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* SNMP cli support + * Copyright (C) 2024 Donald Sharp NVIDIA Corporation + */ +#include + +#include "lib/hook.h" +#include "lib/libagentx.h" +#include "command.h" + +DEFINE_HOOK(agentx_cli_enabled, (), ()); +DEFINE_HOOK(agentx_cli_disabled, (), ()); + +bool agentx_enabled; + +/* AgentX node. */ +static int config_write_agentx(struct vty *vty) +{ + if (agentx_enabled) + vty_out(vty, "agentx\n"); + return 1; +} + +static struct cmd_node agentx_node = { + .name = "smux", + .node = SMUX_NODE, + .prompt = "", + .config_write = config_write_agentx, +}; + +DEFUN(agentx_enable, agentx_enable_cmd, "agentx", + "SNMP AgentX protocol settings\n") +{ + if (!hook_have_hooks(agentx_cli_enabled)) { + zlog_info( + "agentx specified but the agentx Module is not loaded, is this intentional?"); + + return CMD_SUCCESS; + } + + hook_call(agentx_cli_enabled); + + return CMD_SUCCESS; +} + +DEFUN(no_agentx, no_agentx_cmd, "no agentx", + NO_STR "SNMP AgentX protocol settings\n") +{ + vty_out(vty, "SNMP AgentX support cannot be disabled once enabled\n"); + if (!hook_call(agentx_cli_disabled)) + return CMD_WARNING_CONFIG_FAILED; + + return CMD_SUCCESS; +} + +void libagentx_init(void) +{ + agentx_enabled = false; + + install_node(&agentx_node); + install_element(CONFIG_NODE, &agentx_enable_cmd); + install_element(CONFIG_NODE, &no_agentx_cmd); +} diff --git a/lib/libagentx.h b/lib/libagentx.h new file mode 100644 index 000000000000..c3246d975f14 --- /dev/null +++ b/lib/libagentx.h @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* SNMP cli support + * Copyright (C) 2024 Donald Sharp NVIDIA Corporation + */ +#ifndef __LIBAGENTX_H__ +#define __LIBAGENTX_H__ + +extern void libagentx_init(void); +extern bool agentx_enabled; + +DECLARE_HOOK(agentx_cli_enabled, (), ()); +DECLARE_HOOK(agentx_cli_disabled, (), ()); + +#endif diff --git a/lib/smux.h b/lib/smux.h index cec4d2a1bf1e..8ec847afd01f 100644 --- a/lib/smux.h +++ b/lib/smux.h @@ -99,6 +99,7 @@ struct index_oid { */ extern bool smux_enabled(void); +extern void libagentx_init(void); extern void smux_init(struct event_loop *tm); extern void smux_agentx_enable(void); extern void smux_register_mib(const char *, struct variable *, size_t, int, diff --git a/lib/subdir.am b/lib/subdir.am index 221c0b1e1d87..3264f31af7a4 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -58,6 +58,7 @@ lib_libfrr_la_SOURCES = \ lib/ldp_sync.c \ lib/lib_errors.c \ lib/lib_vty.c \ + lib/libagentx.c \ lib/libfrr.c \ lib/libfrr_trace.c \ lib/linklist.c \ @@ -252,6 +253,7 @@ pkginclude_HEADERS += \ lib/ldp_sync.h \ lib/lib_errors.h \ lib/lib_vty.h \ + lib/libagentx.h \ lib/libfrr.h \ lib/libfrr_trace.h \ lib/libospf.h \ diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index abd43203357c..8320f11f6cce 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -24,6 +24,7 @@ #include "vrf.h" #include "bfd.h" #include "libfrr.h" +#include "libagentx.h" #include "ospf6d.h" #include "ospf6_top.h" @@ -266,6 +267,7 @@ int main(int argc, char *argv[], char *envp[]) /* thread master */ master = om6->master; + libagentx_init(); keychain_init(); ospf6_vrf_init(); access_list_init(); diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 9e97abba1ca1..fdb4e5c5875f 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -28,6 +28,7 @@ #include "libfrr.h" #include "routemap.h" #include "keychain.h" +#include "libagentx.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -256,6 +257,7 @@ int main(int argc, char **argv) master = om->master; /* Library inits. */ + libagentx_init(); ospf_debug_init(); ospf_vrf_init(); diff --git a/python/xref2vtysh.py b/python/xref2vtysh.py index 177de757b04d..75d9ccf367df 100644 --- a/python/xref2vtysh.py +++ b/python/xref2vtysh.py @@ -32,7 +32,7 @@ # not quite obvious... daemon_flags = { - "lib/agentx.c": "VTYSH_ISISD|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA", + "lib/libagentx.c": "VTYSH_ISISD|VTYSH_RIPD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA", "lib/filter.c": "VTYSH_ACL_SHOW", "lib/filter_cli.c": "VTYSH_ACL_CONFIG", "lib/if.c": "VTYSH_INTERFACE", diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 734e7ac4d926..67469f5fe52c 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -23,6 +23,7 @@ #include "routemap.h" #include "bfd.h" #include "mgmt_be_client.h" +#include "libagentx.h" #include "ripd/ripd.h" #include "ripd/rip_bfd.h" @@ -190,6 +191,7 @@ int main(int argc, char **argv) master = frr_init(); /* Library initialization. */ + libagentx_init(); rip_error_init(); keychain_init_new(true); rip_vrf_init(); diff --git a/zebra/main.c b/zebra/main.c index d83f1d0491bf..ea1e1cbdbbd8 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -26,6 +26,7 @@ #include "routemap.h" #include "routing_nb.h" #include "mgmt_be_client.h" +#include "libagentx.h" #include "zebra/zebra_router.h" #include "zebra/zebra_errors.h" @@ -435,6 +436,7 @@ int main(int argc, char **argv) zrouter.master = frr_init(); /* Zebra related initialize. */ + libagentx_init(); zebra_router_init(asic_offload, notify_on_ack, v6_with_v4_nexthop); zserv_init(); zebra_rib_init(); From 42c497dec06b514d8bbf30ea01dea2601e82573c Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 13 May 2024 17:42:30 +0200 Subject: [PATCH 099/472] bgpd: fix colored nexthops resolution When the SR-TE service is off, colored BGP routes are not selected if it is recursively resolved over routes that are colored only. Actually, a BGP nexthop context includes the color attribute; when an update from ZEBRA is received, there is no color, and the colored BGP nexthop contexts are parsed, only if there is a non colored BGP nexthop context. The actual setup shows this may not be the case every time. Fix this by parsing all the colored BGP nexthop contexts. Fixes: b8210849b8ac ("bgpd: Make bgp ready to remove distinction between 2 nh tracking types") Signed-off-by: Philippe Guibert --- bgpd/bgp_nht.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 66d6a55683d7..fca3da938695 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -972,12 +972,12 @@ void bgp_nexthop_update(struct vrf *vrf, struct prefix *match, * which should provide a better infrastructure to solve this issue in * a more efficient and elegant way. */ - if (nhr->srte_color == 0 && bnc_nhc) { + if (nhr->srte_color == 0) { struct bgp_nexthop_cache *bnc_iter; frr_each (bgp_nexthop_cache, &bgp->nexthop_cache_table[afi], bnc_iter) { - if (!prefix_same(&bnc_nhc->prefix, &bnc_iter->prefix) || + if (!prefix_same(match, &bnc_iter->prefix) || bnc_iter->srte_color == 0 || CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID)) continue; From 70e5005cba584a000c8d4d19807565c7a3394f4e Mon Sep 17 00:00:00 2001 From: Piotr Suchy Date: Wed, 8 May 2024 21:04:04 +0000 Subject: [PATCH 100/472] lib, vtysh, topotests: fix 'show ip[v6] access-list ... json' formatting Similarly to recently fixed 'show ip[v6] prefix-list ...' - PR#15750, json output is not valid for 'show ip[v6] access-list ... json' commands, as it goes through all the running daemons and for each one it calls 'filter_show' creating a new json object. To aggreagate the output and create a valid json that can later be parsed, the commands were moved to vtysh and formatted accordingly Signed-off-by: Piotr Suchy --- lib/filter.c | 18 ++-- tests/topotests/nb_config/test_nb_config.py | 4 +- vtysh/vtysh.c | 102 ++++++++++++++++++++ vtysh/vtysh.h | 4 + 4 files changed, 114 insertions(+), 14 deletions(-) diff --git a/lib/filter.c b/lib/filter.c index 5a0790f8bfc2..0722bed1cbf5 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -458,7 +458,6 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi, struct filter_cisco *filter; bool first; json_object *json = NULL; - json_object *json_proto = NULL; master = access_master_get(afi); if (master == NULL) { @@ -469,12 +468,7 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi, if (use_json) json = json_object_new_object(); - - /* Print the name of the protocol */ - if (json) { - json_proto = json_object_new_object(); - json_object_object_add(json, frr_protoname, json_proto); - } else + else vty_out(vty, "%s:\n", frr_protoname); for (access = master->str.head; access; access = access->next) { @@ -496,7 +490,7 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi, if (json) { json_acl = json_object_new_object(); - json_object_object_add(json_proto, + json_object_object_add(json, access->name, json_acl); @@ -596,7 +590,7 @@ DEFUN (show_mac_access_list_name, return filter_show(vty, argv[3]->arg, AFI_L2VPN, false); } -DEFUN (show_ip_access_list, +DEFUN_NOSH (show_ip_access_list, show_ip_access_list_cmd, "show ip access-list [json]", SHOW_STR @@ -608,7 +602,7 @@ DEFUN (show_ip_access_list, return filter_show(vty, NULL, AFI_IP, uj); } -DEFUN (show_ip_access_list_name, +DEFUN_NOSH (show_ip_access_list_name, show_ip_access_list_name_cmd, "show ip access-list ACCESSLIST4_NAME [json]", SHOW_STR @@ -622,7 +616,7 @@ DEFUN (show_ip_access_list_name, return filter_show(vty, argv[idx_acl]->arg, AFI_IP, uj); } -DEFUN (show_ipv6_access_list, +DEFUN_NOSH (show_ipv6_access_list, show_ipv6_access_list_cmd, "show ipv6 access-list [json]", SHOW_STR @@ -634,7 +628,7 @@ DEFUN (show_ipv6_access_list, return filter_show(vty, NULL, AFI_IP6, uj); } -DEFUN (show_ipv6_access_list_name, +DEFUN_NOSH (show_ipv6_access_list_name, show_ipv6_access_list_name_cmd, "show ipv6 access-list ACCESSLIST6_NAME [json]", SHOW_STR diff --git a/tests/topotests/nb_config/test_nb_config.py b/tests/topotests/nb_config/test_nb_config.py index 8def19ffd545..9099ef10b8c4 100644 --- a/tests/topotests/nb_config/test_nb_config.py +++ b/tests/topotests/nb_config/test_nb_config.py @@ -50,7 +50,7 @@ def test_access_list_config_ordering(tgen): output = r1.vtysh_cmd("show ip access-list test json") got = json.loads(output) expected = json.loads( - '{"ZEBRA":{"test":{"type":"Standard", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "address":"10.0.0.1", "mask":"0.0.0.0"}]}}}' + '{"zebra":{"test":{"type":"Standard", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "address":"10.0.0.1", "mask":"0.0.0.0"}]}}}' ) result = json_cmp(got, expected) assert result is None @@ -63,7 +63,7 @@ def test_access_list_config_ordering(tgen): output = r1.vtysh_cmd("show ip access-list test json") got = json.loads(output) expected = json.loads( - '{"ZEBRA":{"test":{"type":"Zebra", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "prefix":"10.0.0.0/8", "exact-match":false}]}}}' + '{"zebra":{"test":{"type":"Zebra", "addressFamily":"IPv4", "rules":[{"sequenceNumber":1, "filterType":"permit", "prefix":"10.0.0.0/8", "exact-match":false}]}}}' ) result = json_cmp(got, expected) assert result is None diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 1a358017dc55..b1c957d043a3 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -3628,6 +3628,104 @@ DEFPY (show_ipv6_prefix_list_detail, return CMD_SUCCESS; } +static void show_access_list_send(afi_t afi, const char *access_list, bool json) +{ + unsigned int i; + bool first = true; + char command_line[128]; + + if (afi == AFI_IP) + snprintf(command_line, sizeof(command_line), + "do show ip access-list "); + else if (afi == AFI_IP6) + snprintf(command_line, sizeof(command_line), + "do show ipv6 access-list "); + if (access_list) + strlcat(command_line, access_list, sizeof(command_line)); + if (json) { + strlcat(command_line, " json", sizeof(command_line)); + vty_out(vty, "{"); + } + + for (i = 0; i < array_size(vtysh_client); i++) { + const struct vtysh_client *client = &vtysh_client[i]; + bool is_connected = true; + + if (!CHECK_FLAG(client->flag, VTYSH_ACCESS_LIST_SHOW)) + continue; + + for (; client; client = client->next) + if (client->fd < 0) + is_connected = false; + + if (!is_connected) + continue; + + if (json && !first) + vty_out(vty, ","); + else + first = false; + + if (json) + vty_out(vty, "\"%s\":", vtysh_client[i].name); + + vtysh_client_execute_name(vtysh_client[i].name, command_line); + } + + if (json) + vty_out(vty, "}\n"); +} + +DEFPY (show_ip_access_list, + show_ip_access_list_cmd, + "show ip access-list [json$uj]", + SHOW_STR + IP_STR + "List IP access lists\n" + JSON_STR) +{ + show_access_list_send(AFI_IP, NULL, !!uj); + return CMD_SUCCESS; +} + +DEFPY (show_ip_access_list_name, + show_ip_access_list_name_cmd, + "show ip access-list ACCESSLIST4_NAME$name [json$uj]", + SHOW_STR + IP_STR + "List IP access lists\n" + "IP access-list name\n" + JSON_STR) +{ + show_access_list_send(AFI_IP, name, !!uj); + return CMD_SUCCESS; +} + +DEFPY (show_ipv6_access_list, + show_ipv6_access_list_cmd, + "show ipv6 access-list [json$uj]", + SHOW_STR + IPV6_STR + "List IPv6 access lists\n" + JSON_STR) +{ + show_access_list_send(AFI_IP6, NULL, !!uj); + return CMD_SUCCESS; +} + +DEFPY (show_ipv6_access_list_name, + show_ipv6_access_list_name_cmd, + "show ipv6 access-list ACCESSLIST6_NAME$name [json$uj]", + SHOW_STR + IPV6_STR + "List IPv6 access lists\n" + "IPv6 access-list name\n" + JSON_STR) +{ + show_access_list_send(AFI_IP6, name, !!uj); + return CMD_SUCCESS; +} + DEFUN (vtysh_integrated_config, vtysh_integrated_config_cmd, "service integrated-vtysh-config", @@ -5234,6 +5332,10 @@ void vtysh_init_vty(void) install_element(ENABLE_NODE, &show_ipv6_prefix_list_cmd); install_element(ENABLE_NODE, &show_ipv6_prefix_list_summary_cmd); install_element(ENABLE_NODE, &show_ipv6_prefix_list_detail_cmd); + install_element(ENABLE_NODE, &show_ip_access_list_cmd); + install_element(ENABLE_NODE, &show_ip_access_list_name_cmd); + install_element(ENABLE_NODE, &show_ipv6_access_list_cmd); + install_element(ENABLE_NODE, &show_ipv6_access_list_name_cmd); /* "write terminal" command. */ install_element(ENABLE_NODE, &vtysh_write_terminal_cmd); diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 131fbef8ba50..b1d57aa3c221 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -68,6 +68,10 @@ extern struct event_loop *master; VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \ VTYSH_BGPD | VTYSH_ISISD | VTYSH_PIMD | VTYSH_EIGRPD | \ VTYSH_FABRICD +#define VTYSH_ACCESS_LIST_SHOW \ + VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \ + VTYSH_BGPD | VTYSH_ISISD | VTYSH_PIMD | VTYSH_EIGRPD | \ + VTYSH_FABRICD #define VTYSH_PREFIX_LIST_SHOW \ VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \ VTYSH_BGPD | VTYSH_ISISD | VTYSH_PIMD | VTYSH_EIGRPD | \ From e265b16f83e224f349b31f15227b3a99c30b8ecb Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 14 May 2024 11:51:50 +0200 Subject: [PATCH 101/472] bgpd: fix colored routes not installed after a switchover On a multihomed setup with colored bgp updates, when the primary PE goes offline, only a small subset of colored bgp routes are not switching to the secondary pe. When a switchover happens, due to a remote IP becoming unreachable, some nexthop tracking down notifications are sent, but those messages are completely ignored for colored bgp updates. The original code has been thought for mounting up the SR-TE service, when IP reachability is ok, but not when services goes offline. Fix this by extending the down notification mechanism for colored routes too. Fixes: 545aeef1d13e ("bgpd: extend the NHT code to understand SR-TE colors") Signed-off-by: Philippe Guibert --- bgpd/bgp_nht.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index fca3da938695..79f62ef60969 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -978,8 +978,7 @@ void bgp_nexthop_update(struct vrf *vrf, struct prefix *match, frr_each (bgp_nexthop_cache, &bgp->nexthop_cache_table[afi], bnc_iter) { if (!prefix_same(match, &bnc_iter->prefix) || - bnc_iter->srte_color == 0 || - CHECK_FLAG(bnc_iter->flags, BGP_NEXTHOP_VALID)) + bnc_iter->srte_color == 0) continue; bgp_process_nexthop_update(bnc_iter, nhr, false); From cd001c5ac07d9dd45ce4faada2cf1244a1f8163f Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 14 May 2024 14:52:23 +0200 Subject: [PATCH 102/472] bgpd: fixes bmp stats send-experimental configuration Unconfiguring the send-experimental stats in BMP has no effect on the current behavior. Fixes this by swapping the configuration boolean. Fixes: 7ba991cf963f ("bgpd: add 'bmp stat send-experimental' command") Signed-off-by: Philippe Guibert --- bgpd/bgp_bmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 2f3be0bc9d75..bf08e30509af 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -2496,7 +2496,7 @@ DEFPY(bmp_stats_send_experimental, { VTY_DECLVAR_CONTEXT_SUB(bmp_targets, bt); - bt->stats_send_experimental = !!no; + bt->stats_send_experimental = !no; return CMD_SUCCESS; } From d6835df9cc868a0bc8ad62ba51ed26903580bd70 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Tue, 14 May 2024 10:28:17 -0400 Subject: [PATCH 103/472] zebra: include route source set by route-map in show output Include the prefix source address when set by a route-map in show output for routes, in various formats. Add some debugs when encoding netlink route messages with a source address. Signed-off-by: Mark Stapp --- zebra/rt_netlink.c | 28 ++++++++++++++ zebra/zebra_rnh.c | 41 ++++++++++++++++---- zebra/zebra_rnh.h | 4 +- zebra/zebra_vty.c | 96 ++++++++++++++++++++++++++-------------------- 4 files changed, 119 insertions(+), 50 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 4a15b7400496..5c582995f2a1 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2369,6 +2369,14 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx break; setsrc = nexthop_set_src(nexthop, p->family, &src); + if (setsrc && IS_ZEBRA_DEBUG_KERNEL) { + if (p->family == AF_INET) + zlog_debug("%s: %pFX set src %pI4", + __func__, p, &src.ipv4); + else if (p->family == AF_INET6) + zlog_debug("%s: %pFX set src %pI6", + __func__, p, &src.ipv6); + } } if (setsrc) { @@ -2411,6 +2419,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx setsrc = nexthop_set_src(nexthop, p->family, &src); + if (setsrc && IS_ZEBRA_DEBUG_KERNEL) { + if (p->family == AF_INET) + zlog_debug("%s: %pFX set src %pI4", + __func__, p, + &src.ipv4); + else if (p->family == AF_INET6) + zlog_debug("%s: %pFX set src %pI6", + __func__, p, + &src.ipv6); + } continue; } @@ -2472,6 +2490,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx setsrc = nexthop_set_src(nexthop, p->family, &src); + if (setsrc && IS_ZEBRA_DEBUG_KERNEL) { + if (p->family == AF_INET) + zlog_debug("%s: %pFX set src %pI4", + __func__, p, + &src.ipv4); + else if (p->family == AF_INET6) + zlog_debug("%s: %pFX set src %pI6", + __func__, p, + &src.ipv6); + } continue; } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index b387e9949bb0..06fb5b099b0b 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -1266,6 +1266,7 @@ int zebra_send_rnh_update(struct rnh *rnh, struct zserv *client, */ void show_nexthop_json_helper(json_object *json_nexthop, const struct nexthop *nexthop, + const struct route_node *rn, const struct route_entry *re) { json_object *json_labels = NULL; @@ -1381,13 +1382,24 @@ void show_nexthop_json_helper(json_object *json_nexthop, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) + if (nexthop->rmap_src.ipv4.s_addr) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI4", &nexthop->rmap_src.ipv4); + else if (nexthop->src.ipv4.s_addr) json_object_string_addf(json_nexthop, "source", "%pI4", &nexthop->src.ipv4); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn && rn->p.family == AF_INET && + nexthop->rmap_src.ipv4.s_addr) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) json_object_string_addf(json_nexthop, "source", "%pI6", &nexthop->src.ipv6); break; @@ -1461,13 +1473,15 @@ void show_nexthop_json_helper(json_object *json_nexthop, /* * Helper for nexthop output, used in the 'show ip route' path */ -void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, +void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn, + const struct route_entry *re, const struct nexthop *nexthop) { char buf[MPLS_LABEL_STRLEN]; char seg_buf[SRV6_SEG_STRLEN]; struct seg6_segs segs; uint8_t i; + bool src_p = false; switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: @@ -1529,8 +1543,14 @@ void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) { + if (nexthop->rmap_src.ipv4.s_addr) { + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + src_p = true; + } else if (nexthop->src.ipv4.s_addr) { vty_out(vty, ", src %pI4", &nexthop->src.ipv4); + src_p = true; + } + if (src_p) { /* SR-TE information */ if (nexthop->srte_color) vty_out(vty, ", SR-TE color %u", @@ -1539,7 +1559,13 @@ void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn && rn->p.family == AF_INET && + nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + vty_out(vty, ", rmapsrc %pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) vty_out(vty, ", src %pI6", &nexthop->src.ipv6); break; case NEXTHOP_TYPE_IFINDEX: @@ -1644,9 +1670,10 @@ static void print_rnh(struct route_node *rn, struct vty *vty, json_object *json) json_object_array_add(json_nexthop_array, json_nexthop); show_nexthop_json_helper(json_nexthop, nexthop, - NULL); + rn, NULL); } else { - show_route_nexthop_helper(vty, NULL, nexthop); + show_route_nexthop_helper(vty, rn, NULL, + nexthop); vty_out(vty, "\n"); } } diff --git a/zebra/zebra_rnh.h b/zebra/zebra_rnh.h index 07db7bbd7a10..f0b10d825c84 100644 --- a/zebra/zebra_rnh.h +++ b/zebra/zebra_rnh.h @@ -45,8 +45,10 @@ bool rnh_get_hide_backups(void); void show_nexthop_json_helper(json_object *json_nexthop, const struct nexthop *nexthop, + const struct route_node *rn, const struct route_entry *re); -void show_route_nexthop_helper(struct vty *vty, const struct route_entry *re, +void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn, + const struct route_entry *re, const struct nexthop *nexthop); #ifdef __cplusplus diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index bdbb059e5619..44720754ba8b 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -76,13 +76,17 @@ static void vty_show_ip_route_summary_prefix(struct vty *vty, bool use_json); /* Helper api to format a nexthop in the 'detailed' output path. */ static void show_nexthop_detail_helper(struct vty *vty, + const struct route_node *rn, const struct route_entry *re, const struct nexthop *nexthop, bool is_backup); static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table); -static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, - struct route_entry *re, unsigned int num); +static void show_ip_route_nht_dump(struct vty *vty, + const struct nexthop *nexthop, + const struct route_node *rn, + const struct route_entry *re, + unsigned int num); DEFUN (ip_multicast_mode, ip_multicast_mode_cmd, @@ -252,7 +256,7 @@ static char re_status_output_char(const struct route_entry *re, /* * Show backup nexthop info, in the 'detailed' output path */ -static void show_nh_backup_helper(struct vty *vty, +static void show_nh_backup_helper(struct vty *vty, const struct route_node *rn, const struct route_entry *re, const struct nexthop *nexthop) { @@ -282,7 +286,7 @@ static void show_nh_backup_helper(struct vty *vty, temp = backup; while (backup) { vty_out(vty, " "); - show_nexthop_detail_helper(vty, re, backup, + show_nexthop_detail_helper(vty, rn, re, backup, true /*backup*/); vty_out(vty, "\n"); @@ -303,11 +307,11 @@ static void show_nh_backup_helper(struct vty *vty, * output path. */ static void show_nexthop_detail_helper(struct vty *vty, + const struct route_node *rn, const struct route_entry *re, const struct nexthop *nexthop, bool is_backup) { - char addrstr[32]; char buf[MPLS_LABEL_STRLEN]; int i; @@ -391,23 +395,21 @@ static void show_nexthop_detail_helper(struct vty *vty, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->src.ipv4.s_addr) { - if (inet_ntop(AF_INET, &nexthop->src.ipv4, - addrstr, sizeof(addrstr))) - vty_out(vty, ", src %s", - addrstr); - } + if (nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + else if (nexthop->src.ipv4.s_addr) + vty_out(vty, ", src %pI4", &nexthop->src.ipv4); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, - &in6addr_any)) { - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, - addrstr, sizeof(addrstr))) - vty_out(vty, ", src %s", - addrstr); - } + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn->p.family == AF_INET && nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + vty_out(vty, ", rmapsrc %pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + vty_out(vty, ", src %pI6", &nexthop->src.ipv6); break; case NEXTHOP_TYPE_IFINDEX: @@ -591,13 +593,13 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn, for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) { /* Use helper to format each nexthop */ - show_nexthop_detail_helper(vty, re, nexthop, + show_nexthop_detail_helper(vty, rn, re, nexthop, false /*not backup*/); vty_out(vty, "\n"); /* Include backup(s), if present */ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) - show_nh_backup_helper(vty, re, nexthop); + show_nh_backup_helper(vty, rn, re, nexthop); } zebra_show_ip_route_opaque(vty, re, NULL); @@ -704,8 +706,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, for (ALL_NEXTHOPS_PTR(nhg, nexthop)) { json_nexthop = json_object_new_object(); - show_nexthop_json_helper(json_nexthop, - nexthop, re); + show_nexthop_json_helper(json_nexthop, nexthop, rn, re); json_object_array_add(json_nexthops, json_nexthop); @@ -725,8 +726,8 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, for (ALL_NEXTHOPS_PTR(nhg, nexthop)) { json_nexthop = json_object_new_object(); - show_nexthop_json_helper(json_nexthop, - nexthop, re); + show_nexthop_json_helper(json_nexthop, nexthop, + rn, re); json_object_array_add(json_nexthops, json_nexthop); } @@ -791,7 +792,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, len - 3 + (2 * nexthop_level(nexthop)), ' '); } - show_route_nexthop_helper(vty, re, nexthop); + show_route_nexthop_helper(vty, rn, re, nexthop); vty_out(vty, ", %s\n", up_str); } @@ -822,7 +823,7 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn, vty_out(vty, " b%c %*c", (star_p ? '*' : ' '), len - 3 + (2 * nexthop_level(nexthop)), ' '); - show_route_nexthop_helper(vty, re, nexthop); + show_route_nexthop_helper(vty, rn, re, nexthop); vty_out(vty, "\n"); } @@ -1278,14 +1279,15 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, for (ALL_NEXTHOPS(nhe->nhg, nexthop)) { if (json_nexthop_array) { json_nexthops = json_object_new_object(); - show_nexthop_json_helper(json_nexthops, nexthop, NULL); + show_nexthop_json_helper(json_nexthops, nexthop, NULL, + NULL); } else { if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) vty_out(vty, " "); else /* Make recursive nexthops a bit more clear */ vty_out(vty, " "); - show_route_nexthop_helper(vty, NULL, nexthop); + show_route_nexthop_helper(vty, NULL, NULL, nexthop); } if (nhe->backup_info == NULL || nhe->backup_info->nhe == NULL) { @@ -1343,7 +1345,7 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, if (json_backup_nexthop_array) { json_backup_nexthops = json_object_new_object(); show_nexthop_json_helper(json_backup_nexthops, - nexthop, NULL); + nexthop, NULL, NULL); json_object_array_add(json_backup_nexthop_array, json_backup_nexthops); } else { @@ -1356,7 +1358,8 @@ static void show_nexthop_group_out(struct vty *vty, struct nhg_hash_entry *nhe, * clear */ vty_out(vty, " "); - show_route_nexthop_helper(vty, NULL, nexthop); + show_route_nexthop_helper(vty, NULL, NULL, + nexthop); vty_out(vty, "\n"); } } @@ -2104,8 +2107,11 @@ DEFUN_HIDDEN (show_route_zebra_dump, return CMD_SUCCESS; } -static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, - struct route_entry *re, unsigned int num) +static void show_ip_route_nht_dump(struct vty *vty, + const struct nexthop *nexthop, + const struct route_node *rn, + const struct route_entry *re, + unsigned int num) { char buf[SRCDEST2STR_BUFFER]; @@ -2129,10 +2135,12 @@ static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, nexthop->vrf_id)); } - if (nexthop->src.ipv4.s_addr - && (inet_ntop(AF_INET, &nexthop->src.ipv4, buf, - sizeof(buf)))) - vty_out(vty, " source: %s\n", buf); + if (nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, " rmapsrc: %pI4\n", + &nexthop->rmap_src.ipv4); + else if (nexthop->src.ipv4.s_addr) + vty_out(vty, " source: %pI4\n", + &nexthop->src.ipv4.s_addr); break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -2149,11 +2157,15 @@ static void show_ip_route_nht_dump(struct vty *vty, struct nexthop *nexthop, nexthop->vrf_id)); } - if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) { - if (inet_ntop(AF_INET6, &nexthop->src.ipv6, buf, - sizeof(buf))) - vty_out(vty, " source: %s\n", buf); - } + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn->p.family == AF_INET && nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, " rmapsrc: %pI4\n", + &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + vty_out(vty, " rmapsrc: %pI6\n", + &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + vty_out(vty, " source: %pI6\n", &nexthop->src.ipv6); break; case NEXTHOP_TYPE_IFINDEX: vty_out(vty, @@ -2245,7 +2257,7 @@ static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table) for (ALL_NEXTHOPS_PTR(&(re->nhe->nhg), nexthop)) { nexthop_num++; - show_ip_route_nht_dump(vty, nexthop, re, + show_ip_route_nht_dump(vty, nexthop, rn, re, nexthop_num); } From 2429dd130f7c6c81311b5e92340d392f8d6d9991 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Tue, 14 May 2024 23:25:32 +0800 Subject: [PATCH 104/472] zebra: fix wrong fpm packet header Signed-off-by: anlan_cs --- zebra/fpm_listener.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c index fed6c41631b4..63977633a93b 100644 --- a/zebra/fpm_listener.c +++ b/zebra/fpm_listener.c @@ -693,7 +693,7 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm) for (; NLMSG_OK(hdr, len); hdr = NLMSG_NEXT(hdr, len)) { netlink_msg_ctx_init(ctx); - ctx->hdr = (struct nlmsghdr *)buf; + ctx->hdr = hdr; switch (hdr->nlmsg_type) { From 9dc02dd338946887b04e9c79216ed5bc95ddaf1f Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 14 May 2024 23:36:38 -0400 Subject: [PATCH 105/472] tests: improve the grpc query client and topotest - Add separate get, get-config, get-state operations to query command, as well as switching default output to JSON. - Add an `--xml` to change the output format. - move printss to logging.debug so output is a machine parseable result. Signed-off-by: Christian Hopps --- tests/topotests/grpc_basic/test_basic_grpc.py | 94 +++++++++++++++---- tests/topotests/lib/grpc-query.py | 44 ++++++--- 2 files changed, 106 insertions(+), 32 deletions(-) diff --git a/tests/topotests/grpc_basic/test_basic_grpc.py b/tests/topotests/grpc_basic/test_basic_grpc.py index 1ded663179e1..cf1c6d0ec75b 100644 --- a/tests/topotests/grpc_basic/test_basic_grpc.py +++ b/tests/topotests/grpc_basic/test_basic_grpc.py @@ -9,16 +9,18 @@ test_basic_grpc.py: Test Basic gRPC. """ +import json import logging import os +import re import sys import pytest - from lib.common_config import step from lib.micronet import commander from lib.topogen import Topogen, TopoRouter from lib.topolog import logger +from lib.topotest import json_cmp CWD = os.path.dirname(os.path.realpath(__file__)) @@ -28,6 +30,7 @@ GRPCP_ISISD = 50054 GRPCP_OSPFD = 50055 GRPCP_PIMD = 50056 +GRPCP_MGMTD = 50057 pytestmark = [ pytest.mark.mgmtd, @@ -59,12 +62,15 @@ def tgen(request): for rname, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf", f"-M grpc:{GRPCP_ZEBRA}") - router.load_config(TopoRouter.RD_STATIC, None, f"-M grpc:{GRPCP_STATICD}") - # router.load_config(TopoRouter.RD_BFD, None, f"-M grpc:{GRPCP_BFDD}") + router.load_config(TopoRouter.RD_STATIC, "", f"-M grpc:{GRPCP_STATICD}") + # router.load_config(TopoRouter.RD_BFDD, "", f"-M grpc:{GRPCP_BFDD}") # router.load_config(TopoRouter.RD_ISIS, None, f"-M grpc:{GRPCP_ISISD}") # router.load_config(TopoRouter.RD_OSPF, None, f"-M grpc:{GRPCP_OSPFD}") # router.load_config(TopoRouter.RD_PIM, None, f"-M grpc:{GRPCP_PIMD}") + # This doesn't work yet... + # router.load_config(TopoRouter.RD_MGMTD, "", f"-M grpc:{GRPCP_MGMTD}") + tgen.start_router() yield tgen @@ -94,40 +100,94 @@ def run_grpc_client(r, port, commands): def test_connectivity(tgen): - r1 = tgen.gears["r1"] - output = r1.cmd_raises("ping -c1 192.168.1.2") - logging.info("ping output: %s", output) + tgen.gears["r1"].cmd_raises("ping -c1 192.168.1.2") def test_capabilities(tgen): r1 = tgen.gears["r1"] - output = run_grpc_client(r1, GRPCP_ZEBRA, "GETCAP") - logging.info("grpc output: %s", output) + output = run_grpc_client(r1, GRPCP_STATICD, "GETCAP") + logging.debug("grpc output: %s", output) + + modules = sorted(re.findall('name: "([^"]+)"', output)) + expected = ["frr-interface", "frr-routing", "frr-staticd", "frr-vrf"] + assert modules == expected + + encodings = sorted(re.findall("supported_encodings: (.*)", output)) + expected = ["JSON", "XML"] + assert encodings == expected def test_get_config(tgen): nrepeat = 5 r1 = tgen.gears["r1"] - step("'GET' interface config 10 times, once per invocation") + step("'GET' interface config and state 10 times, once per invocation") for i in range(0, nrepeat): - output = run_grpc_client(r1, GRPCP_ZEBRA, "GET,/frr-interface:lib") - logging.info("[iteration %s]: grpc GET output: %s", i, output) + output = run_grpc_client(r1, GRPCP_ZEBRA, "GET-CONFIG,/frr-interface:lib") + logging.debug("[iteration %s]: grpc GET output: %s", i, output) step(f"'GET' YANG {nrepeat} times in one invocation") - commands = ["GET,/frr-interface:lib" for _ in range(0, 10)] + commands = ["GET-CONFIG,/frr-interface:lib" for _ in range(0, 10)] output = run_grpc_client(r1, GRPCP_ZEBRA, commands) - logging.info("grpc GET*{%d} output: %s", nrepeat, output) + logging.debug("grpc GET*{%d} output: %s", nrepeat, output) + + output = run_grpc_client(r1, GRPCP_ZEBRA, commands[0]) + out_json = json.loads(output) + expect = json.loads( + """{ + "frr-interface:lib": { + "interface": [ + { + "name": "r1-eth0", + "frr-zebra:zebra": { + "ipv4-addrs": [ + { + "ip": "192.168.1.1", + "prefix-length": 24 + } + ], + "evpn-mh": {}, + "ipv6-router-advertisements": {} + } + } + ] + }, + "frr-zebra:zebra": { + "import-kernel-table": {} + } +} """ + ) + result = json_cmp(out_json, expect, exact=True) + assert result is None def test_get_vrf_config(tgen): r1 = tgen.gears["r1"] - step("'GET' get VRF config") - - output = run_grpc_client(r1, GRPCP_ZEBRA, "GET,/frr-vrf:lib") - logging.info("grpc GET /frr-vrf:lib output: %s", output) + step("'GET' VRF config and state") + + output = run_grpc_client(r1, GRPCP_STATICD, "GET,/frr-vrf:lib") + logging.debug("grpc GET /frr-vrf:lib output: %s", output) + out_json = json.loads(output) + expect = json.loads( + """{ + "frr-vrf:lib": { + "vrf": [ + { + "name": "default", + "state": { + "id": 0, + "active": true + } + } + ] + } +} + """ + ) + result = json_cmp(out_json, expect, exact=True) + assert result is None def test_shutdown_checks(tgen): diff --git a/tests/topotests/lib/grpc-query.py b/tests/topotests/lib/grpc-query.py index 8c4701c24390..c9b79b0bdc99 100755 --- a/tests/topotests/lib/grpc-query.py +++ b/tests/topotests/lib/grpc-query.py @@ -18,15 +18,16 @@ # This is painful but works if you have installed grpc and grpc_tools would be *way* # better if we actually built and installed these but ... python packaging. try: - import grpc import grpc_tools + import grpc + sys.path.append(os.path.dirname(CWD)) from munet.base import commander commander.cmd_raises(f"cp {CWD}/../../../grpc/frr-northbound.proto .") commander.cmd_raises( - f"python3 -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I . frr-northbound.proto" + "python3 -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I . frr-northbound.proto" ) except Exception as error: logging.error("can't create proto definition modules %s", error) @@ -57,16 +58,16 @@ def get_capabilities(self): logging.debug("GRPC Capabilities: %s", response) return response - def get(self, xpath): + def get(self, xpath, encoding, gtype): request = frr_northbound_pb2.GetRequest() request.path.append(xpath) - request.type = frr_northbound_pb2.GetRequest.ALL - request.encoding = frr_northbound_pb2.XML - xml = "" + request.type = gtype + request.encoding = encoding + result = "" for r in self.stub.Get(request): - logging.info('GRPC Get path: "%s" value: %s', request.path, r) - xml += str(r.data.data) - return xml + logging.debug('GRPC Get path: "%s" value: %s', request.path, r) + result += str(r.data.data) + return result def next_action(action_list=None): @@ -95,6 +96,7 @@ def main(*args): ) parser.add_argument("-v", "--verbose", action="store_true", help="be verbose") parser.add_argument("--check", action="store_true", help="check runable") + parser.add_argument("--xml", action="store_true", help="encode XML instead of JSON") parser.add_argument("actions", nargs="*", help="GETCAP|GET,xpath") args = parser.parse_args(*args) @@ -107,20 +109,32 @@ def main(*args): if args.check: sys.exit(0) + encoding = frr_northbound_pb2.XML if args.xml else frr_northbound_pb2.JSON + c = GRPCClient(args.server, args.port) for action in next_action(args.actions): action = action.casefold() - logging.info("GOT ACTION: %s", action) + logging.debug("GOT ACTION: %s", action) if action == "getcap": caps = c.get_capabilities() - print("Capabilities:", caps) + print(caps) elif action.startswith("get,"): - # Print Interface State and Config + # Get and print config and state + _, xpath = action.split(",", 1) + logging.debug("Get XPath: %s", xpath) + print(c.get(xpath, encoding, gtype=frr_northbound_pb2.GetRequest.ALL)) + elif action.startswith("get-config,"): + # Get and print config + _, xpath = action.split(",", 1) + logging.debug("Get Config XPath: %s", xpath) + print(c.get(xpath, encoding, gtype=frr_northbound_pb2.GetRequest.CONFIG)) + # for _ in range(0, 1): + elif action.startswith("get-state,"): + # Get and print state _, xpath = action.split(",", 1) - print("Get XPath: ", xpath) - xml = c.get(xpath) - print("{}: {}".format(xpath, xml)) + logging.debug("Get State XPath: %s", xpath) + print(c.get(xpath, encoding, gtype=frr_northbound_pb2.GetRequest.STATE)) # for _ in range(0, 1): From 05b6cfc71a2516c721c40d2dd92bd8e1934c3df0 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 3 Jan 2024 21:33:58 +0100 Subject: [PATCH 106/472] zebra, lib: move nexthop display helper to lib folder The zebra_nexthop_vty_helper() and zebra_nexthop_json_helper() functions could be very helpful to display nexthop information from whatever daemon. Move the core function in the nexthop_vty_helper() and the nexthop_json_helper() function. The zebra API call remains unchanged. Signed-off-by: Philippe Guibert --- lib/nexthop.c | 349 ++++++++++++++++++++++++++++++++++++++++++++++ lib/nexthop.h | 6 + zebra/zebra_rnh.c | 347 +++------------------------------------------ 3 files changed, 373 insertions(+), 329 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 243b52d55474..533641222bc4 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -1154,3 +1154,352 @@ bool nexthop_is_blackhole(const struct nexthop *nh) { return nh->type == NEXTHOP_TYPE_BLACKHOLE; } + +/* + * Render a nexthop into a json object; the caller allocates and owns + * the json object memory. + */ +void nexthop_json_helper(json_object *json_nexthop, + const struct nexthop *nexthop, bool display_vrfid, + uint8_t rn_family) +{ + json_object *json_labels = NULL; + json_object *json_backups = NULL; + json_object *json_seg6local = NULL; + json_object *json_seg6 = NULL; + json_object *json_segs = NULL; + int i; + + json_object_int_add(json_nexthop, "flags", nexthop->flags); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) + json_object_boolean_true_add(json_nexthop, "duplicate"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) + json_object_boolean_true_add(json_nexthop, "fib"); + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + json_object_string_addf(json_nexthop, "ip", "%pI4", + &nexthop->gate.ipv4); + json_object_string_add(json_nexthop, "afi", "ipv4"); + + if (nexthop->ifindex) { + json_object_int_add(json_nexthop, "interfaceIndex", + nexthop->ifindex); + json_object_string_add(json_nexthop, "interfaceName", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + } + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + json_object_string_addf(json_nexthop, "ip", "%pI6", + &nexthop->gate.ipv6); + json_object_string_add(json_nexthop, "afi", "ipv6"); + + if (nexthop->ifindex) { + json_object_int_add(json_nexthop, "interfaceIndex", + nexthop->ifindex); + json_object_string_add(json_nexthop, "interfaceName", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + } + break; + + case NEXTHOP_TYPE_IFINDEX: + json_object_boolean_true_add(json_nexthop, "directlyConnected"); + json_object_int_add(json_nexthop, "interfaceIndex", + nexthop->ifindex); + json_object_string_add(json_nexthop, "interfaceName", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + json_object_boolean_true_add(json_nexthop, "unreachable"); + switch (nexthop->bh_type) { + case BLACKHOLE_REJECT: + json_object_boolean_true_add(json_nexthop, "reject"); + break; + case BLACKHOLE_ADMINPROHIB: + json_object_boolean_true_add(json_nexthop, + "adminProhibited"); + break; + case BLACKHOLE_NULL: + json_object_boolean_true_add(json_nexthop, "blackhole"); + break; + case BLACKHOLE_UNSPEC: + break; + } + break; + } + + /* This nexthop is a resolver for the parent nexthop. + * Set resolver flag for better clarity and delimiter + * in flat list of nexthops in json. + */ + if (nexthop->rparent) + json_object_boolean_true_add(json_nexthop, "resolver"); + + if (display_vrfid) + json_object_string_add(json_nexthop, "vrf", + vrf_id_to_name(nexthop->vrf_id)); + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) + json_object_boolean_true_add(json_nexthop, "duplicate"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + json_object_boolean_true_add(json_nexthop, "active"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) + json_object_boolean_true_add(json_nexthop, "onLink"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN)) + json_object_boolean_true_add(json_nexthop, "linkDown"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + json_object_boolean_true_add(json_nexthop, "recursive"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) { + json_backups = json_object_new_array(); + for (i = 0; i < nexthop->backup_num; i++) { + json_object_array_add(json_backups, + json_object_new_int( + nexthop->backup_idx[i])); + } + + json_object_object_add(json_nexthop, "backupIndex", + json_backups); + } + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (nexthop->rmap_src.ipv4.s_addr) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI4", &nexthop->rmap_src.ipv4); + else if (nexthop->src.ipv4.s_addr) + json_object_string_addf(json_nexthop, "source", "%pI4", + &nexthop->src.ipv4); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn_family == AF_INET && nexthop->rmap_src.ipv4.s_addr) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + json_object_string_addf(json_nexthop, "rmapSource", + "%pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + json_object_string_addf(json_nexthop, "source", "%pI6", + &nexthop->src.ipv6); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_BLACKHOLE: + break; + } + + if (nexthop->nh_label && nexthop->nh_label->num_labels) { + json_labels = json_object_new_array(); + + for (int label_index = 0; + label_index < nexthop->nh_label->num_labels; label_index++) + json_object_array_add( + json_labels, + json_object_new_int(( + (nexthop->nh_label_type == ZEBRA_LSP_EVPN) + ? label2vni( + &nexthop->nh_label->label + [label_index]) + : nexthop->nh_label + ->label[label_index]))); + + json_object_object_add(json_nexthop, "labels", json_labels); + } + + if (nexthop->weight) + json_object_int_add(json_nexthop, "weight", nexthop->weight); + + if (nexthop->srte_color) + json_object_int_add(json_nexthop, "srteColor", + nexthop->srte_color); + + if (nexthop->nh_srv6) { + json_seg6local = json_object_new_object(); + json_object_string_add(json_seg6local, "action", + seg6local_action2str( + nexthop->nh_srv6 + ->seg6local_action)); + json_object_object_add(json_nexthop, "seg6local", + json_seg6local); + if (nexthop->nh_srv6->seg6_segs && + nexthop->nh_srv6->seg6_segs->num_segs == 1) { + json_seg6 = json_object_new_object(); + json_object_string_addf(json_seg6, "segs", "%pI6", + &nexthop->nh_srv6->seg6_segs + ->seg[0]); + json_object_object_add(json_nexthop, "seg6", json_seg6); + } else { + if (nexthop->nh_srv6->seg6_segs) { + json_segs = json_object_new_array(); + for (int seg_idx = 0; + seg_idx < + nexthop->nh_srv6->seg6_segs->num_segs; + seg_idx++) + json_object_array_add( + json_segs, + json_object_new_stringf( + "%pI6", + &nexthop->nh_srv6 + ->seg6_segs + ->seg[seg_idx])); + json_object_object_add(json_nexthop, "seg6", + json_segs); + } + } + } +} + +/* + * Helper for nexthop output + */ +void nexthop_vty_helper(struct vty *vty, const struct nexthop *nexthop, + bool display_vrfid, uint8_t rn_family) +{ + char buf[MPLS_LABEL_STRLEN]; + char seg_buf[SRV6_SEG_STRLEN]; + struct seg6_segs segs; + uint8_t i; + bool src_p = false; + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + vty_out(vty, " via %pI4", &nexthop->gate.ipv4); + if (nexthop->ifindex) + vty_out(vty, ", %s", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + vty_out(vty, " via %s", + inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, + sizeof(buf))); + if (nexthop->ifindex) + vty_out(vty, ", %s", + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id)); + break; + + case NEXTHOP_TYPE_IFINDEX: + vty_out(vty, " is directly connected, %s", + ifindex2ifname(nexthop->ifindex, nexthop->vrf_id)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + vty_out(vty, " unreachable"); + switch (nexthop->bh_type) { + case BLACKHOLE_REJECT: + vty_out(vty, " (ICMP unreachable)"); + break; + case BLACKHOLE_ADMINPROHIB: + vty_out(vty, " (ICMP admin-prohibited)"); + break; + case BLACKHOLE_NULL: + vty_out(vty, " (blackhole)"); + break; + case BLACKHOLE_UNSPEC: + break; + } + break; + } + + if (display_vrfid) + vty_out(vty, " (vrf %s)", vrf_id_to_name(nexthop->vrf_id)); + + if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + vty_out(vty, " inactive"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) + vty_out(vty, " onlink"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN)) + vty_out(vty, " linkdown"); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + vty_out(vty, " (recursive)"); + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + if (nexthop->rmap_src.ipv4.s_addr) { + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + src_p = true; + } else if (nexthop->src.ipv4.s_addr) { + vty_out(vty, ", src %pI4", &nexthop->src.ipv4); + src_p = true; + } + if (src_p) { + /* SR-TE information */ + if (nexthop->srte_color) + vty_out(vty, ", SR-TE color %u", + nexthop->srte_color); + } + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ + if (rn_family == AF_INET && nexthop->rmap_src.ipv4.s_addr) + vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); + else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) + vty_out(vty, ", rmapsrc %pI6", &nexthop->rmap_src.ipv6); + else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) + vty_out(vty, ", src %pI6", &nexthop->src.ipv6); + break; + case NEXTHOP_TYPE_IFINDEX: + case NEXTHOP_TYPE_BLACKHOLE: + break; + } + + /* Label information */ + if (nexthop->nh_label && nexthop->nh_label->num_labels) { + vty_out(vty, ", label %s", + mpls_label2str(nexthop->nh_label->num_labels, + nexthop->nh_label->label, buf, + sizeof(buf), nexthop->nh_label_type, 1)); + } + + if (nexthop->nh_srv6) { + seg6local_context2str(buf, sizeof(buf), + &nexthop->nh_srv6->seg6local_ctx, + nexthop->nh_srv6->seg6local_action); + if (nexthop->nh_srv6->seg6local_action != + ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) + vty_out(vty, ", seg6local %s %s", + seg6local_action2str( + nexthop->nh_srv6->seg6local_action), + buf); + if (nexthop->nh_srv6->seg6_segs && + IPV6_ADDR_CMP(&nexthop->nh_srv6->seg6_segs->seg[0], + &in6addr_any)) { + segs.num_segs = nexthop->nh_srv6->seg6_segs->num_segs; + for (i = 0; i < segs.num_segs; i++) + memcpy(&segs.segs[i], + &nexthop->nh_srv6->seg6_segs->seg[i], + sizeof(struct in6_addr)); + snprintf_seg6_segs(seg_buf, SRV6_SEG_STRLEN, &segs); + vty_out(vty, ", seg6 %s", seg_buf); + } + } + + if (nexthop->weight) + vty_out(vty, ", weight %u", nexthop->weight); + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) { + vty_out(vty, ", backup %d", nexthop->backup_idx[0]); + + for (i = 1; i < nexthop->backup_num; i++) + vty_out(vty, ",%d", nexthop->backup_idx[i]); + } +} diff --git a/lib/nexthop.h b/lib/nexthop.h index 958d06aa51b7..27073b948dea 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -252,6 +252,12 @@ extern bool nexthop_is_blackhole(const struct nexthop *nh); int nexthop_str2backups(const char *str, int *num_backups, uint8_t *backups); +void nexthop_json_helper(json_object *json_nexthop, + const struct nexthop *nexthop, bool display_vrfid, + uint8_t rn_family); +void nexthop_vty_helper(struct vty *vty, const struct nexthop *nexthop, + bool display_vrfid, uint8_t rn_family); + #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pNH" (struct nexthop *) #endif diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 06fb5b099b0b..bff82588790e 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -1269,205 +1269,18 @@ void show_nexthop_json_helper(json_object *json_nexthop, const struct route_node *rn, const struct route_entry *re) { - json_object *json_labels = NULL; - json_object *json_backups = NULL; - json_object *json_seg6local = NULL; - json_object *json_seg6 = NULL; - json_object *json_segs = NULL; - int i; - - json_object_int_add(json_nexthop, "flags", nexthop->flags); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) - json_object_boolean_true_add(json_nexthop, "duplicate"); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) - json_object_boolean_true_add(json_nexthop, "fib"); - - switch (nexthop->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - json_object_string_addf(json_nexthop, "ip", "%pI4", - &nexthop->gate.ipv4); - json_object_string_add(json_nexthop, "afi", "ipv4"); - - if (nexthop->ifindex) { - json_object_int_add(json_nexthop, "interfaceIndex", - nexthop->ifindex); - json_object_string_add(json_nexthop, "interfaceName", - ifindex2ifname(nexthop->ifindex, - nexthop->vrf_id)); - } - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - json_object_string_addf(json_nexthop, "ip", "%pI6", - &nexthop->gate.ipv6); - json_object_string_add(json_nexthop, "afi", "ipv6"); - - if (nexthop->ifindex) { - json_object_int_add(json_nexthop, "interfaceIndex", - nexthop->ifindex); - json_object_string_add(json_nexthop, "interfaceName", - ifindex2ifname(nexthop->ifindex, - nexthop->vrf_id)); - } - break; - - case NEXTHOP_TYPE_IFINDEX: - json_object_boolean_true_add(json_nexthop, "directlyConnected"); - json_object_int_add(json_nexthop, "interfaceIndex", - nexthop->ifindex); - json_object_string_add( - json_nexthop, "interfaceName", - ifindex2ifname(nexthop->ifindex, nexthop->vrf_id)); - break; - case NEXTHOP_TYPE_BLACKHOLE: - json_object_boolean_true_add(json_nexthop, "unreachable"); - switch (nexthop->bh_type) { - case BLACKHOLE_REJECT: - json_object_boolean_true_add(json_nexthop, "reject"); - break; - case BLACKHOLE_ADMINPROHIB: - json_object_boolean_true_add(json_nexthop, - "adminProhibited"); - break; - case BLACKHOLE_NULL: - json_object_boolean_true_add(json_nexthop, "blackhole"); - break; - case BLACKHOLE_UNSPEC: - break; - } - break; - } - - /* This nexthop is a resolver for the parent nexthop. - * Set resolver flag for better clarity and delimiter - * in flat list of nexthops in json. - */ - if (nexthop->rparent) - json_object_boolean_true_add(json_nexthop, "resolver"); - - if ((re == NULL || (nexthop->vrf_id != re->vrf_id))) - json_object_string_add(json_nexthop, "vrf", - vrf_id_to_name(nexthop->vrf_id)); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) - json_object_boolean_true_add(json_nexthop, "duplicate"); + bool display_vrfid = false; + uint8_t rn_family; - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - json_object_boolean_true_add(json_nexthop, "active"); + if (re == NULL || nexthop->vrf_id != re->vrf_id) + display_vrfid = true; - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) - json_object_boolean_true_add(json_nexthop, "onLink"); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN)) - json_object_boolean_true_add(json_nexthop, "linkDown"); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - json_object_boolean_true_add(json_nexthop, "recursive"); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) { - json_backups = json_object_new_array(); - for (i = 0; i < nexthop->backup_num; i++) { - json_object_array_add( - json_backups, - json_object_new_int(nexthop->backup_idx[i])); - } - - json_object_object_add(json_nexthop, "backupIndex", - json_backups); - } - - switch (nexthop->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->rmap_src.ipv4.s_addr) - json_object_string_addf(json_nexthop, "rmapSource", - "%pI4", &nexthop->rmap_src.ipv4); - else if (nexthop->src.ipv4.s_addr) - json_object_string_addf(json_nexthop, "source", "%pI4", - &nexthop->src.ipv4); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ - if (rn && rn->p.family == AF_INET && - nexthop->rmap_src.ipv4.s_addr) - json_object_string_addf(json_nexthop, "rmapSource", - "%pI4", &nexthop->rmap_src.ipv4); - else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) - json_object_string_addf(json_nexthop, "rmapSource", - "%pI6", &nexthop->rmap_src.ipv6); - else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) - json_object_string_addf(json_nexthop, "source", "%pI6", - &nexthop->src.ipv6); - break; - case NEXTHOP_TYPE_IFINDEX: - case NEXTHOP_TYPE_BLACKHOLE: - break; - } - - if (nexthop->nh_label && nexthop->nh_label->num_labels) { - json_labels = json_object_new_array(); - - for (int label_index = 0; - label_index < nexthop->nh_label->num_labels; label_index++) - json_object_array_add( - json_labels, - json_object_new_int(( - (nexthop->nh_label_type == - ZEBRA_LSP_EVPN) - ? label2vni( - &nexthop->nh_label->label - [label_index]) - : nexthop->nh_label->label - [label_index]))); - - json_object_object_add(json_nexthop, "labels", json_labels); - } + if (rn) + rn_family = rn->p.family; + else + rn_family = AF_UNSPEC; - if (nexthop->weight) - json_object_int_add(json_nexthop, "weight", nexthop->weight); - - if (nexthop->srte_color) - json_object_int_add(json_nexthop, "srteColor", - nexthop->srte_color); - - if (nexthop->nh_srv6) { - json_seg6local = json_object_new_object(); - json_object_string_add( - json_seg6local, "action", - seg6local_action2str( - nexthop->nh_srv6->seg6local_action)); - json_object_object_add(json_nexthop, "seg6local", - json_seg6local); - if (nexthop->nh_srv6->seg6_segs && - nexthop->nh_srv6->seg6_segs->num_segs == 1) { - json_seg6 = json_object_new_object(); - json_object_string_addf(json_seg6, "segs", "%pI6", - &nexthop->nh_srv6->seg6_segs - ->seg[0]); - json_object_object_add(json_nexthop, "seg6", json_seg6); - } else { - if (nexthop->nh_srv6->seg6_segs) { - json_segs = json_object_new_array(); - for (int seg_idx = 0; - seg_idx < - nexthop->nh_srv6->seg6_segs->num_segs; - seg_idx++) - json_object_array_add( - json_segs, - json_object_new_stringf( - "%pI6", - &nexthop->nh_srv6 - ->seg6_segs - ->seg[seg_idx])); - json_object_object_add(json_nexthop, "seg6", - json_segs); - } - } - } + nexthop_json_helper(json_nexthop, nexthop, display_vrfid, rn_family); } /* @@ -1477,142 +1290,18 @@ void show_route_nexthop_helper(struct vty *vty, const struct route_node *rn, const struct route_entry *re, const struct nexthop *nexthop) { - char buf[MPLS_LABEL_STRLEN]; - char seg_buf[SRV6_SEG_STRLEN]; - struct seg6_segs segs; - uint8_t i; - bool src_p = false; - - switch (nexthop->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - vty_out(vty, " via %pI4", &nexthop->gate.ipv4); - if (nexthop->ifindex) - vty_out(vty, ", %s", - ifindex2ifname(nexthop->ifindex, - nexthop->vrf_id)); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - vty_out(vty, " via %s", - inet_ntop(AF_INET6, &nexthop->gate.ipv6, buf, - sizeof(buf))); - if (nexthop->ifindex) - vty_out(vty, ", %s", - ifindex2ifname(nexthop->ifindex, - nexthop->vrf_id)); - break; - - case NEXTHOP_TYPE_IFINDEX: - vty_out(vty, " is directly connected, %s", - ifindex2ifname(nexthop->ifindex, nexthop->vrf_id)); - break; - case NEXTHOP_TYPE_BLACKHOLE: - vty_out(vty, " unreachable"); - switch (nexthop->bh_type) { - case BLACKHOLE_REJECT: - vty_out(vty, " (ICMP unreachable)"); - break; - case BLACKHOLE_ADMINPROHIB: - vty_out(vty, " (ICMP admin-prohibited)"); - break; - case BLACKHOLE_NULL: - vty_out(vty, " (blackhole)"); - break; - case BLACKHOLE_UNSPEC: - break; - } - break; - } - - if ((re == NULL || (nexthop->vrf_id != re->vrf_id))) - vty_out(vty, " (vrf %s)", vrf_id_to_name(nexthop->vrf_id)); - - if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) - vty_out(vty, " inactive"); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) - vty_out(vty, " onlink"); + bool display_vrfid = false; + uint8_t rn_family; - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_LINKDOWN)) - vty_out(vty, " linkdown"); + if (re == NULL || nexthop->vrf_id != re->vrf_id) + display_vrfid = true; - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) - vty_out(vty, " (recursive)"); - - switch (nexthop->type) { - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->rmap_src.ipv4.s_addr) { - vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); - src_p = true; - } else if (nexthop->src.ipv4.s_addr) { - vty_out(vty, ", src %pI4", &nexthop->src.ipv4); - src_p = true; - } - if (src_p) { - /* SR-TE information */ - if (nexthop->srte_color) - vty_out(vty, ", SR-TE color %u", - nexthop->srte_color); - } - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - /* Allow for 5549 ipv4 prefix with ipv6 nexthop */ - if (rn && rn->p.family == AF_INET && - nexthop->rmap_src.ipv4.s_addr) - vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); - else if (!IPV6_ADDR_SAME(&nexthop->rmap_src.ipv6, &in6addr_any)) - vty_out(vty, ", rmapsrc %pI6", &nexthop->rmap_src.ipv6); - else if (!IPV6_ADDR_SAME(&nexthop->src.ipv6, &in6addr_any)) - vty_out(vty, ", src %pI6", &nexthop->src.ipv6); - break; - case NEXTHOP_TYPE_IFINDEX: - case NEXTHOP_TYPE_BLACKHOLE: - break; - } - - /* Label information */ - if (nexthop->nh_label && nexthop->nh_label->num_labels) { - vty_out(vty, ", label %s", - mpls_label2str(nexthop->nh_label->num_labels, - nexthop->nh_label->label, buf, - sizeof(buf), nexthop->nh_label_type, 1)); - } - - if (nexthop->nh_srv6) { - seg6local_context2str(buf, sizeof(buf), - &nexthop->nh_srv6->seg6local_ctx, - nexthop->nh_srv6->seg6local_action); - if (nexthop->nh_srv6->seg6local_action != - ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) - vty_out(vty, ", seg6local %s %s", - seg6local_action2str( - nexthop->nh_srv6->seg6local_action), - buf); - if (nexthop->nh_srv6->seg6_segs && - IPV6_ADDR_CMP(&nexthop->nh_srv6->seg6_segs->seg[0], - &in6addr_any)) { - segs.num_segs = nexthop->nh_srv6->seg6_segs->num_segs; - for (i = 0; i < segs.num_segs; i++) - memcpy(&segs.segs[i], - &nexthop->nh_srv6->seg6_segs->seg[i], - sizeof(struct in6_addr)); - snprintf_seg6_segs(seg_buf, SRV6_SEG_STRLEN, &segs); - vty_out(vty, ", seg6 %s", seg_buf); - } - } - - if (nexthop->weight) - vty_out(vty, ", weight %u", nexthop->weight); - - if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) { - vty_out(vty, ", backup %d", nexthop->backup_idx[0]); + if (rn) + rn_family = rn->p.family; + else + rn_family = AF_UNSPEC; - for (i = 1; i < nexthop->backup_num; i++) - vty_out(vty, ",%d", nexthop->backup_idx[i]); - } + nexthop_vty_helper(vty, nexthop, display_vrfid, rn_family); } static void print_rnh(struct route_node *rn, struct vty *vty, json_object *json) From 4648225b539d0b2c40d55ceb4aae76a9ee92f7dd Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 15 May 2024 15:36:04 +0200 Subject: [PATCH 107/472] zebra: fix dump SR-TE information if available The SR-TE color of nexthop should be displayed in all situations. Fixes: 553c8048460a ("zebra: fix JSON fields for 'show ip/ipv6 nht'") Signed-off-by: Philippe Guibert --- lib/nexthop.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c index 533641222bc4..26c338256f6e 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -1371,7 +1371,6 @@ void nexthop_vty_helper(struct vty *vty, const struct nexthop *nexthop, char seg_buf[SRV6_SEG_STRLEN]; struct seg6_segs segs; uint8_t i; - bool src_p = false; switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: @@ -1433,19 +1432,10 @@ void nexthop_vty_helper(struct vty *vty, const struct nexthop *nexthop, switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: - if (nexthop->rmap_src.ipv4.s_addr) { + if (nexthop->rmap_src.ipv4.s_addr) vty_out(vty, ", rmapsrc %pI4", &nexthop->rmap_src.ipv4); - src_p = true; - } else if (nexthop->src.ipv4.s_addr) { + else if (nexthop->src.ipv4.s_addr) vty_out(vty, ", src %pI4", &nexthop->src.ipv4); - src_p = true; - } - if (src_p) { - /* SR-TE information */ - if (nexthop->srte_color) - vty_out(vty, ", SR-TE color %u", - nexthop->srte_color); - } break; case NEXTHOP_TYPE_IPV6: case NEXTHOP_TYPE_IPV6_IFINDEX: @@ -1462,6 +1452,10 @@ void nexthop_vty_helper(struct vty *vty, const struct nexthop *nexthop, break; } + /* SR-TE information */ + if (nexthop->srte_color) + vty_out(vty, ", SR-TE color %u", nexthop->srte_color); + /* Label information */ if (nexthop->nh_label && nexthop->nh_label->num_labels) { vty_out(vty, ", label %s", From 0e040960d76f4098ca829910c3a0c51a5cd9476c Mon Sep 17 00:00:00 2001 From: EasyNetDev Date: Mon, 13 May 2024 17:30:45 +0300 Subject: [PATCH 108/472] zebra: Update Zebra for DPDK >=22.11 API * Starting from version DPDK 22.11 we have API changes: The rte_driver and rte_device objects are now opaque and must be manipulated through added accessors. We need to update Zebra DPDK sources to DPDK version >=22.11 * Fix clang-format Signed-off-by: EasyNet --- zebra/dpdk/zebra_dplane_dpdk.c | 31 +++++++++++++++++-------------- zebra/dpdk/zebra_dplane_dpdk.h | 2 ++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/zebra/dpdk/zebra_dplane_dpdk.c b/zebra/dpdk/zebra_dplane_dpdk.c index 7a5388c57bb7..411155167f64 100644 --- a/zebra/dpdk/zebra_dplane_dpdk.c +++ b/zebra/dpdk/zebra_dplane_dpdk.c @@ -52,7 +52,7 @@ void zd_dpdk_stat_show(struct vty *vty) static void zd_dpdk_flow_stat_show(struct vty *vty, int in_ifindex, intptr_t dp_flow_ptr) { - struct rte_flow_action_count count = {.shared = 0, .id = 0}; + struct rte_flow_action_count count = { .id = 0 }; const struct rte_flow_action actions[] = { { .type = RTE_FLOW_ACTION_TYPE_COUNT, @@ -498,9 +498,11 @@ static void zd_dpdk_port_show_entry(struct zd_dpdk_port *dport, struct vty *vty, if (detail) { vty_out(vty, "DPDK port: %u\n", dport->port_id); vty_out(vty, " Device: %s\n", - dev_info->device ? dev_info->device->name : "-"); + dev_info->device ? rte_dev_name(dev_info->device) : "-"); vty_out(vty, " Driver: %s\n", - dev_info->driver_name ? dev_info->driver_name : "-"); + dev_info->driver_name ? rte_driver_name(rte_dev_driver( + dev_info->device)) + : "-"); vty_out(vty, " Interface: %s (%d)\n", ifindex2ifname(dev_info->if_index, VRF_DEFAULT), dev_info->if_index); @@ -510,9 +512,8 @@ static void zd_dpdk_port_show_entry(struct zd_dpdk_port *dport, struct vty *vty, dev_info->switch_info.port_id); vty_out(vty, "\n"); } else { - vty_out(vty, "%-4u %-16s %-16s %-16d %s,%u,%u\n", - dport->port_id, - dev_info->device ? dev_info->device->name : "-", + vty_out(vty, "%-4u %-16s %-16s %-16d %s,%u,%u\n", dport->port_id, + dev_info->device ? rte_dev_name(dev_info->device) : "-", ifindex2ifname(dev_info->if_index, VRF_DEFAULT), dev_info->if_index, dev_info->switch_info.name, dev_info->switch_info.domain_id, @@ -595,13 +596,15 @@ static void zd_dpdk_port_init(void) } SET_FLAG(dport->flags, ZD_DPDK_PORT_FLAG_INITED); if (IS_ZEBRA_DEBUG_DPLANE_DPDK) - zlog_debug( - "port %u, dev %s, ifI %d, sw_name %s, sw_domain %u, sw_port %u", - port_id, - dev_info->device ? dev_info->device->name : "-", - dev_info->if_index, dev_info->switch_info.name, - dev_info->switch_info.domain_id, - dev_info->switch_info.port_id); + zlog_debug("port %u, dev %s, ifI %d, sw_name %s, sw_domain %u, sw_port %u", + port_id, + dev_info->device + ? rte_dev_name(dev_info->device) + : "-", + dev_info->if_index, + dev_info->switch_info.name, + dev_info->switch_info.domain_id, + dev_info->switch_info.port_id); if (rte_flow_isolate(port_id, 1, &error)) { if (IS_ZEBRA_DEBUG_DPLANE_DPDK) zlog_debug( @@ -635,7 +638,7 @@ static int zd_dpdk_init(void) zd_dpdk_vty_init(); frr_with_privs (&zserv_privs) { - rc = rte_eal_init(array_size(argv), argv); + rc = rte_eal_init(array_size(argv), (char **)argv); } if (rc < 0) { zlog_warn("EAL init failed %s", rte_strerror(rte_errno)); diff --git a/zebra/dpdk/zebra_dplane_dpdk.h b/zebra/dpdk/zebra_dplane_dpdk.h index e5a3dbebab29..ece72d9efbe5 100644 --- a/zebra/dpdk/zebra_dplane_dpdk.h +++ b/zebra/dpdk/zebra_dplane_dpdk.h @@ -20,4 +20,6 @@ extern void zd_dpdk_port_show(struct vty *vty, uint16_t port_id, bool uj, extern void zd_dpdk_stat_show(struct vty *vty); extern void zd_dpdk_vty_init(void); +extern struct zebra_privs_t zserv_privs; + #endif From e446308d76b4ac8f26149db982bf5ed5ac93d5f5 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 16 May 2024 15:08:09 +0200 Subject: [PATCH 109/472] bgpd: fix dynamic peer graceful restart race condition bgp_llgr topotest sometimes fails at step 8: > topo: STEP 8: 'Check if we can see 172.16.1.2/32 after R4 (dynamic peer) was killed' R4 neighbor is deleted on R2 because it fails to re-connect: > 14:33:40.128048 BGP: [HKWM3-ZC5QP] 192.168.3.1 fd -1 went from Established to Clearing > 14:33:40.128154 BGP: [MJ1TJ-HEE3V] 192.168.3.1(r4) graceful restart timer expired > 14:33:40.128158 BGP: [ZTA2J-YRKGY] 192.168.3.1(r4) graceful restart stalepath timer stopped > 14:33:40.128162 BGP: [H917J-25EWN] 192.168.3.1(r4) Long-lived stale timer (IPv4 Unicast) started for 20 sec > 14:33:40.128168 BGP: [H5X66-NXP9S] 192.168.3.1(r4) Long-lived set stale community (LLGR_STALE) for: 172.16.1.2/32 > 14:33:40.128220 BGP: [H5X66-NXP9S] 192.168.3.1(r4) Long-lived set stale community (LLGR_STALE) for: 192.168.3.0/24 > [...] > 14:33:41.138869 BGP: [RGGAC-RJ6WG] 192.168.3.1 [Event] Connect failed 111(Connection refused) > 14:33:41.138906 BGP: [ZWCSR-M7FG9] 192.168.3.1 [FSM] TCP_connection_open_failed (Connect->Active), fd 23 > 14:33:41.138912 BGP: [JA9RP-HSD1K] 192.168.3.1 (dynamic neighbor) deleted (bgp_connect_fail) > 14:33:41.139126 BGP: [P98A2-2RDFE] 192.168.3.1(r4) graceful restart stalepath timer stopped af8496af08 ("bgpd: Do not delete BGP dynamic peers if graceful restart kicks in") forgot to modify bgp_connect_fail() Do not delete the peer in bgp_connect_fail() if Non-Stop-Forwarding is in progress. Fixes: af8496af08 ("bgpd: Do not delete BGP dynamic peers if graceful restart kicks in") Signed-off-by: Louis Scalbert --- bgpd/bgp_fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index f10705ef2195..15cc5dbe2ea0 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1779,7 +1779,7 @@ bgp_connect_fail(struct peer_connection *connection) { struct peer *peer = connection->peer; - if (peer_dynamic_neighbor(peer)) { + if (peer_dynamic_neighbor_no_nsf(peer)) { if (bgp_debug_neighbor_events(peer)) zlog_debug("%s (dynamic neighbor) deleted (%s)", peer->host, __func__); From 05ad3ccb034c174d2e853e88b826ca0db1e77f45 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Thu, 16 May 2024 16:44:45 +0800 Subject: [PATCH 110/472] zebra: fix mpls command Configured with "mpls label bind 1.1.1.1/32 explicit-null", the running configuration is: ``` ! mpls label bind 1.1.1.1/32 IPv4 Explicit Null ! ``` After this commit, the running configuration is: ``` ! mpls label bind 1.1.1.1/32 explicit-null ! ``` And add the support for the "no" form: ``` anlan(config)# mpls label bind 1.1.1.1/32 explicit-null anlan(config)# no mpls label bind 1.1.1.1/32 explicit-null ``` Signed-off-by: anlan_cs --- zebra/zebra_mpls.c | 12 ++++++++++-- zebra/zebra_mpls_vty.c | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 4cc85d461f4a..d1c9cd54affc 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -2638,8 +2638,16 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf) continue; write = 1; - vty_out(vty, "mpls label bind %pFX %s\n", &rn->p, - label2str(fec->label, 0, lstr, BUFSIZ)); + + if (fec->label == MPLS_LABEL_IPV4_EXPLICIT_NULL || + fec->label == MPLS_LABEL_IPV6_EXPLICIT_NULL) + strlcpy(lstr, "explicit-null", sizeof(lstr)); + else if (fec->label == MPLS_LABEL_IMPLICIT_NULL) + strlcpy(lstr, "implicit-null", sizeof(lstr)); + else + snprintf(lstr, sizeof(lstr), "%d", fec->label); + + vty_out(vty, "mpls label bind %pFX %s\n", &rn->p, lstr); } } diff --git a/zebra/zebra_mpls_vty.c b/zebra/zebra_mpls_vty.c index 8248d4a55535..b31bf449a9a4 100644 --- a/zebra/zebra_mpls_vty.c +++ b/zebra/zebra_mpls_vty.c @@ -247,7 +247,7 @@ DEFUN (mpls_label_bind, DEFUN (no_mpls_label_bind, no_mpls_label_bind_cmd, - "no mpls label bind [<(16-1048575)|implicit-null>]", + "no mpls label bind [<(16-1048575)|implicit-null|explicit-null>]", NO_STR MPLS_STR "Label configuration\n" @@ -255,7 +255,8 @@ DEFUN (no_mpls_label_bind, "IPv4 prefix\n" "IPv6 prefix\n" "MPLS Label to bind\n" - "Use Implicit-Null Label\n") + "Use Implicit-Null Label\n" + "Use Explicit-Null Label\n") { return zebra_mpls_bind(vty, 0, argv[4]->arg, NULL); } From 094dcc3cdac19d3da65b38effc45aa88d960909f Mon Sep 17 00:00:00 2001 From: Francois Dumontet Date: Tue, 23 Apr 2024 11:16:24 +0200 Subject: [PATCH 111/472] bgpd: fix "bgp as-pah access-list" with "set aspath exclude" set/unset issues whith the following config router bgp 65001 no bgp ebgp-requires-policy neighbor 192.168.1.2 remote-as external neighbor 192.168.1.2 timers 3 10 ! address-family ipv4 unicast neighbor 192.168.1.2 route-map r2 in exit-address-family exit ! bgp as-path access-list FIRST seq 5 permit ^65 bgp as-path access-list SECOND seq 5 permit 2$ ! route-map r2 permit 6 match ip address prefix-list p2 set as-path exclude as-path-access-list SECOND exit ! route-map r2 permit 10 match ip address prefix-list p1 set as-path exclude 65003 exit ! route-map r2 permit 20 match ip address prefix-list p3 set as-path exclude all exit making some no bgp as-path access-list SECOND permit 2$ bgp as-path access-list SECOND permit 3$ clear bgp * no bgp as-path access-list SECOND permit 3$ bgp as-path access-list SECOND permit 2$ clear bgp * will induce some crashes thus we rework the links between aslists and aspath_exclude Signed-off-by: Francois Dumontet --- bgpd/bgp_aspath.c | 47 ++++++++++++++++++++++++++++++++++++ bgpd/bgp_aspath.h | 7 ++++++ bgpd/bgp_filter.c | 41 +++++++++++++++++++------------ bgpd/bgp_filter.h | 13 +++++----- bgpd/bgp_routemap.c | 59 ++++++++++++++++++--------------------------- 5 files changed, 108 insertions(+), 59 deletions(-) diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 9dcd0ad1d621..4c1615a5c625 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -77,6 +77,9 @@ static struct hash *ashash; /* Stream for SNMP. See aspath_snmp_pathseg */ static struct stream *snmp_stream; +/* as-path orphan exclude list */ +static struct as_list_list_head as_exclude_list_orphan; + /* Callers are required to initialize the memory */ static as_t *assegment_data_new(int num) { @@ -1558,6 +1561,38 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2) /* Not reached */ } +/* insert aspath exclude in head of orphan exclude list*/ +void as_exclude_set_orphan(struct aspath_exclude *ase) +{ + ase->exclude_aspath_acl = NULL; + as_list_list_add_head(&as_exclude_list_orphan, ase); +} + +void as_exclude_remove_orphan(struct aspath_exclude *ase) +{ + if (as_list_list_count(&as_exclude_list_orphan)) + as_list_list_del(&as_exclude_list_orphan, ase); +} + +/* currently provide only one exclude, not a list */ +struct aspath_exclude *as_exclude_lookup_orphan(const char *acl_name) +{ + struct aspath_exclude *ase = NULL; + char *name = NULL; + + frr_each (as_list_list, &as_exclude_list_orphan, ase) { + if (ase->exclude_aspath_acl_name) { + name = ase->exclude_aspath_acl_name; + if (!strcmp(name, acl_name)) + break; + } + } + if (ase) + as_exclude_remove_orphan(ase); + + return ase; +} + /* Iterate over AS_PATH segments and wipe all occurrences of the * listed AS numbers. Hence some segments may lose some or even * all data on the way, the operation is implemented as a smarter @@ -2236,14 +2271,26 @@ void aspath_init(void) { ashash = hash_create_size(32768, aspath_key_make, aspath_cmp, "BGP AS Path"); + + as_list_list_init(&as_exclude_list_orphan); } void aspath_finish(void) { + struct aspath_exclude *ase; + hash_clean_and_free(&ashash, (void (*)(void *))aspath_free); if (snmp_stream) stream_free(snmp_stream); + + while ((ase = as_list_list_pop(&as_exclude_list_orphan))) { + aspath_free(ase->aspath); + if (ase->exclude_aspath_acl_name) + XFREE(MTYPE_TMP, ase->exclude_aspath_acl_name); + XFREE(MTYPE_ROUTE_MAP_COMPILED, ase); + } + as_list_list_fini(&as_exclude_list_orphan); } /* return and as path value */ diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h index 2a831c3a5510..f7e57fd66dda 100644 --- a/bgpd/bgp_aspath.h +++ b/bgpd/bgp_aspath.h @@ -9,6 +9,7 @@ #include "lib/json.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_filter.h" +#include /* AS path segment type. */ #define AS_SET 1 @@ -67,11 +68,14 @@ struct aspath { /* `set as-path exclude ASn' */ struct aspath_exclude { + struct as_list_list_item exclude_list; struct aspath *aspath; bool exclude_all; char *exclude_aspath_acl_name; struct as_list *exclude_aspath_acl; }; +DECLARE_DLIST(as_list_list, struct aspath_exclude, exclude_list); + /* Prototypes. */ extern void aspath_init(void); @@ -83,6 +87,9 @@ extern struct aspath *aspath_parse(struct stream *s, size_t length, extern struct aspath *aspath_dup(struct aspath *aspath); extern struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2); extern struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2); +extern void as_exclude_set_orphan(struct aspath_exclude *ase); +extern void as_exclude_remove_orphan(struct aspath_exclude *ase); +extern struct aspath_exclude *as_exclude_lookup_orphan(const char *acl_name); extern struct aspath *aspath_filter_exclude(struct aspath *source, struct aspath *exclude_list); extern struct aspath *aspath_filter_exclude_all(struct aspath *source); diff --git a/bgpd/bgp_filter.c b/bgpd/bgp_filter.c index a85117965aaa..002f054f5e41 100644 --- a/bgpd/bgp_filter.c +++ b/bgpd/bgp_filter.c @@ -16,7 +16,7 @@ #include "bgpd/bgp_aspath.h" #include "bgpd/bgp_regex.h" -/* List of AS filter list. */ +/* List of AS list. */ struct as_list_list { struct as_list *head; struct as_list *tail; @@ -205,14 +205,6 @@ static struct as_list *as_list_new(void) static void as_list_free(struct as_list *aslist) { - struct aspath_exclude_list *cur_bp = aslist->exclude_list; - struct aspath_exclude_list *next_bp = NULL; - - while (cur_bp) { - next_bp = cur_bp->next; - XFREE(MTYPE_ROUTE_MAP_COMPILED, cur_bp); - cur_bp = next_bp; - } XFREE (MTYPE_AS_STR, aslist->name); XFREE (MTYPE_AS_LIST, aslist); @@ -299,7 +291,6 @@ static void as_list_delete(struct as_list *aslist) { struct as_list_list *list; struct as_filter *filter, *next; - struct aspath_exclude_list *cur_bp; for (filter = aslist->head; filter; filter = next) { next = filter->next; @@ -318,12 +309,6 @@ static void as_list_delete(struct as_list *aslist) else list->head = aslist->next; - cur_bp = aslist->exclude_list; - while (cur_bp) { - cur_bp->bp_as_excl->exclude_aspath_acl = NULL; - cur_bp = cur_bp->next; - } - as_list_free(aslist); } @@ -431,6 +416,7 @@ DEFUN(as_path, bgp_as_path_cmd, enum as_filter_type type; struct as_filter *asfilter; struct as_list *aslist; + struct aspath_exclude *ase; regex_t *regex; char *regstr; int64_t seqnum = ASPATH_SEQ_NUMBER_AUTO; @@ -482,6 +468,22 @@ DEFUN(as_path, bgp_as_path_cmd, else as_list_filter_add(aslist, asfilter); + /* init the exclude rule list*/ + as_list_list_init(&aslist->exclude_rule); + + /* get aspath orphan exclude that are using this acl */ + ase = as_exclude_lookup_orphan(alname); + if (ase) { + as_list_list_add_head(&aslist->exclude_rule, ase); + /* set reverse pointer */ + ase->exclude_aspath_acl = aslist; + /* set list of aspath excludes using that acl */ + while ((ase = as_exclude_lookup_orphan(alname))) { + as_list_list_add_head(&aslist->exclude_rule, ase); + ase->exclude_aspath_acl = aslist; + } + } + return CMD_SUCCESS; } @@ -502,6 +504,7 @@ DEFUN(no_as_path, no_bgp_as_path_cmd, enum as_filter_type type; struct as_filter *asfilter; struct as_list *aslist; + struct aspath_exclude *ase; char *regstr; regex_t *regex; @@ -556,6 +559,12 @@ DEFUN(no_as_path, no_bgp_as_path_cmd, XFREE(MTYPE_TMP, regstr); + /* put aspath exclude list into orphan */ + if (as_list_list_count(&aslist->exclude_rule)) + while ((ase = as_list_list_pop(&aslist->exclude_rule))) + as_exclude_set_orphan(ase); + + as_list_list_fini(&aslist->exclude_rule); as_list_filter_delete(aslist, asfilter); return CMD_SUCCESS; diff --git a/bgpd/bgp_filter.h b/bgpd/bgp_filter.h index 2d9f07ce84a3..77a3f3c2f727 100644 --- a/bgpd/bgp_filter.h +++ b/bgpd/bgp_filter.h @@ -6,11 +6,12 @@ #ifndef _QUAGGA_BGP_FILTER_H #define _QUAGGA_BGP_FILTER_H +#include + #define ASPATH_SEQ_NUMBER_AUTO -1 enum as_filter_type { AS_FILTER_DENY, AS_FILTER_PERMIT }; - /* Element of AS path filter. */ struct as_filter { struct as_filter *next; @@ -25,11 +26,7 @@ struct as_filter { int64_t seq; }; -struct aspath_exclude_list { - struct aspath_exclude_list *next; - struct aspath_exclude *bp_as_excl; -}; - +PREDECL_DLIST(as_list_list); /* AS path filter list. */ struct as_list { char *name; @@ -39,7 +36,9 @@ struct as_list { struct as_filter *head; struct as_filter *tail; - struct aspath_exclude_list *exclude_list; + + /* Changes in AS path */ + struct as_list_list_head exclude_rule; }; diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index df5c2557bd26..f938869b1c48 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -2325,7 +2325,7 @@ static const struct route_map_rule_cmd route_set_aspath_prepend_cmd = { static void *route_aspath_exclude_compile(const char *arg) { struct aspath_exclude *ase; - struct aspath_exclude_list *ael; + struct as_list *aux_aslist; const char *str = arg; static const char asp_acl[] = "as-path-access-list"; @@ -2337,44 +2337,37 @@ static void *route_aspath_exclude_compile(const char *arg) while (*str == ' ') str++; ase->exclude_aspath_acl_name = XSTRDUP(MTYPE_TMP, str); - ase->exclude_aspath_acl = as_list_lookup(str); + aux_aslist = as_list_lookup(str); + if (!aux_aslist) + /* new orphan filter */ + as_exclude_set_orphan(ase); + else + as_list_list_add_head(&aux_aslist->exclude_rule, ase); + + ase->exclude_aspath_acl = aux_aslist; } else ase->aspath = aspath_str2aspath(str, bgp_get_asnotation(NULL)); - if (ase->exclude_aspath_acl) { - ael = XCALLOC(MTYPE_ROUTE_MAP_COMPILED, - sizeof(struct aspath_exclude_list)); - ael->bp_as_excl = ase; - ael->next = ase->exclude_aspath_acl->exclude_list; - ase->exclude_aspath_acl->exclude_list = ael; - } - return ase; } static void route_aspath_exclude_free(void *rule) { struct aspath_exclude *ase = rule; - struct aspath_exclude_list *cur_ael = NULL; - struct aspath_exclude_list *prev_ael = NULL; + struct as_list *acl; + + /* manage references to that rule*/ + if (ase->exclude_aspath_acl) { + acl = ase->exclude_aspath_acl; + as_list_list_del(&acl->exclude_rule, ase); + } else { + /* no ref to acl, this aspath exclude is orphan */ + as_exclude_remove_orphan(ase); + } aspath_free(ase->aspath); if (ase->exclude_aspath_acl_name) XFREE(MTYPE_TMP, ase->exclude_aspath_acl_name); - if (ase->exclude_aspath_acl) - cur_ael = ase->exclude_aspath_acl->exclude_list; - while (cur_ael) { - if (cur_ael->bp_as_excl == ase) { - if (prev_ael) - prev_ael->next = cur_ael->next; - else - ase->exclude_aspath_acl->exclude_list = NULL; - XFREE(MTYPE_ROUTE_MAP_COMPILED, cur_ael); - break; - } - prev_ael = cur_ael; - cur_ael = cur_ael->next; - } XFREE(MTYPE_ROUTE_MAP_COMPILED, ase); } @@ -2409,16 +2402,10 @@ route_set_aspath_exclude(void *rule, const struct prefix *dummy, void *object) else if (ase->exclude_all) path->attr->aspath = aspath_filter_exclude_all(new_path); - else if (ase->exclude_aspath_acl_name) { - if (!ase->exclude_aspath_acl) - ase->exclude_aspath_acl = - as_list_lookup(ase->exclude_aspath_acl_name); - if (ase->exclude_aspath_acl) - path->attr->aspath = - aspath_filter_exclude_acl(new_path, - ase->exclude_aspath_acl); - } - + else if (ase->exclude_aspath_acl) + path->attr->aspath = + aspath_filter_exclude_acl(new_path, + ase->exclude_aspath_acl); return RMAP_OKAY; } From 0df2e149970beff39915d0095614d56d5859f3ff Mon Sep 17 00:00:00 2001 From: Francois Dumontet Date: Wed, 24 Apr 2024 14:34:48 +0200 Subject: [PATCH 112/472] tests: improve tests for aspath exclude and bgp access list add some match in route map rules add some set unset bgp access path list add another prefix for better tests discrimination update expected results Signed-off-by: Francois Dumontet --- .../bgp_set_aspath_exclude/r1/bgpd.conf | 9 +++ .../bgp_set_aspath_exclude/r3/zebra.conf | 1 + .../test_bgp_set_aspath_exclude.py | 70 +++++++++++++++---- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/tests/topotests/bgp_set_aspath_exclude/r1/bgpd.conf b/tests/topotests/bgp_set_aspath_exclude/r1/bgpd.conf index 9bef24f93154..c70b4934a079 100644 --- a/tests/topotests/bgp_set_aspath_exclude/r1/bgpd.conf +++ b/tests/topotests/bgp_set_aspath_exclude/r1/bgpd.conf @@ -8,10 +8,19 @@ router bgp 65001 exit-address-family ! ip prefix-list p1 seq 5 permit 172.16.255.31/32 +ip prefix-list p2 seq 5 permit 172.16.255.32/32 +ip prefix-list p3 seq 5 permit 172.16.255.30/32 ! +bgp as-path access-list FIRST permit ^65 +bgp as-path access-list SECOND permit 2$ + +route-map r2 permit 6 + match ip address prefix-list p2 + set as-path exclude as-path-access-list SECOND route-map r2 permit 10 match ip address prefix-list p1 set as-path exclude 65003 route-map r2 permit 20 + match ip address prefix-list p3 set as-path exclude all ! diff --git a/tests/topotests/bgp_set_aspath_exclude/r3/zebra.conf b/tests/topotests/bgp_set_aspath_exclude/r3/zebra.conf index 3fa6c644844c..56893158a403 100644 --- a/tests/topotests/bgp_set_aspath_exclude/r3/zebra.conf +++ b/tests/topotests/bgp_set_aspath_exclude/r3/zebra.conf @@ -1,5 +1,6 @@ ! int lo + ip address 172.16.255.30/32 ip address 172.16.255.31/32 ip address 172.16.255.32/32 ! diff --git a/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py b/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py index d373a749fe87..85e7b9676d0e 100644 --- a/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py +++ b/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py @@ -64,29 +64,33 @@ def teardown_module(mod): expected_1 = { "routes": { + "172.16.255.30/32": [{"path": ""}], "172.16.255.31/32": [{"path": "65002"}], - "172.16.255.32/32": [{"path": ""}], + "172.16.255.32/32": [{"path": "65003"}], } } expected_2 = { "routes": { - "172.16.255.31/32": [{"path": ""}], + "172.16.255.30/32": [{"path": ""}], + "172.16.255.31/32": [{"path": "65002"}], "172.16.255.32/32": [{"path": ""}], } } expected_3 = { "routes": { - "172.16.255.31/32": [{"path": "65003"}], - "172.16.255.32/32": [{"path": "65003"}], + "172.16.255.30/32": [{"path": ""}], + "172.16.255.31/32": [{"path": "65002"}], + "172.16.255.32/32": [{"path": "65002 65003"}], } } expected_4 = { "routes": { - "172.16.255.31/32": [{"path": "65002 65003"}], - "172.16.255.32/32": [{"path": "65002 65003"}], + "172.16.255.30/32": [{"path": ""}], + "172.16.255.31/32": [{"path": "65002"}], + "172.16.255.32/32": [{"path": "65002"}], } } @@ -117,34 +121,42 @@ def test_bgp_set_aspath_exclude_access_list(): rname = "r1" r1 = tgen.gears[rname] + # tgen.mininet_cli() r1.vtysh_cmd( """ conf bgp as-path access-list FIRST permit ^65 route-map r2 permit 6 + no set as-path exclude as-path-access-list SECOND set as-path exclude as-path-access-list FIRST """ ) + # tgen.mininet_cli() + r1.vtysh_cmd( + """ +clear bgp * + """ + ) test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_2) _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) - assert result is None, "Failed overriding incoming AS-PATH with regex 1 route-map" + assert result is None, "Failed change of exclude rule in route map" r1.vtysh_cmd( """ conf - bgp as-path access-list SECOND permit 2 route-map r2 permit 6 + no set as-path exclude as-path-access-list FIRST set as-path exclude as-path-access-list SECOND """ ) # tgen.mininet_cli() - test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_3) + test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_1) _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) - assert result is None, "Failed overriding incoming AS-PATH with regex 2 route-map" + assert result is None, "Failed reverting exclude rule in route map" def test_no_bgp_set_aspath_exclude_access_list(): @@ -159,15 +171,28 @@ def test_no_bgp_set_aspath_exclude_access_list(): r1.vtysh_cmd( """ conf - no bgp as-path access-list SECOND permit 2 + no bgp as-path access-list SECOND permit 2$ + """ + ) + + r1.vtysh_cmd( + """ +clear bgp * """ ) test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_3) _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) - assert result is None, "Failed removing bgp as-path access-list" + assert result is None, "Failed to removing current accesslist" + # tgen.mininet_cli() + r1.vtysh_cmd( + """ +conf + bgp as-path access-list SECOND permit 3$ + """ + ) r1.vtysh_cmd( """ clear bgp * @@ -177,7 +202,26 @@ def test_no_bgp_set_aspath_exclude_access_list(): test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_4) _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) - assert result is None, "Failed to renegotiate with peers" + assert result is None, "Failed to renegotiate with peers 2" + + r1.vtysh_cmd( + """ +conf + route-map r2 permit 6 + no set as-path exclude as-path-access-list SECOND + """ + ) + + r1.vtysh_cmd( + """ +clear bgp * + """ + ) + + test_func = functools.partial(bgp_converge, tgen.gears["r1"], expected_3) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + + assert result is None, "Failed to renegotiate with peers 2" if __name__ == "__main__": From edfc03614f0c5e14cffde25afae111908cb3bf30 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 16 May 2024 20:49:56 +0300 Subject: [PATCH 113/472] bgpd: Fix `match peer` when switching between IPv4/IPv6/interface Without this patch we MUST follow this sequence: ``` no match peer 10.0.0.1 match peer 2a01::1 ``` Otherwise, both IPv4/IPv6 values are set/compiled, thus when printing the configuration in show running, we see the first one (IPv4). Signed-off-by: Donatas Abraitis --- bgpd/bgp_routemap.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index df5c2557bd26..dc26a1f5dd82 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -5234,27 +5234,23 @@ DEFPY_YANG (match_peer, nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - if (addrv4_str) { - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv4-address", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, - addrv4_str); - } else if (addrv6_str) { - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv6-address", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, - addrv6_str); - } else { - snprintf( - xpath_value, sizeof(xpath_value), - "%s/rmap-match-condition/frr-bgp-route-map:peer-interface", - xpath); - nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, intf); - } + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv4-address", + xpath); + nb_cli_enqueue_change(vty, xpath_value, + addrv4_str ? NB_OP_MODIFY : NB_OP_DESTROY, + addrv4_str); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv6-address", + xpath); + nb_cli_enqueue_change(vty, xpath_value, + addrv6_str ? NB_OP_MODIFY : NB_OP_DESTROY, + addrv6_str); + snprintf(xpath_value, sizeof(xpath_value), + "%s/rmap-match-condition/frr-bgp-route-map:peer-interface", + xpath); + nb_cli_enqueue_change(vty, xpath_value, + intf ? NB_OP_MODIFY : NB_OP_DESTROY, intf); return nb_cli_apply_changes(vty, NULL); } From 07a084f921cc7ce53123df20588e44a7606f3b0f Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Fri, 17 May 2024 00:54:20 -0400 Subject: [PATCH 114/472] tests: embed YANG in mgmtd unit-test bin `make check` should run w/o installing FRR first. Thus we need to embed the yang modules otherwise mgmtd unit-test fails. Signed-off-by: Christian Hopps --- tests/lib/subdir.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/lib/subdir.am b/tests/lib/subdir.am index 94df3626d679..185b89507932 100644 --- a/tests/lib/subdir.am +++ b/tests/lib/subdir.am @@ -34,6 +34,10 @@ tests_lib_test_grpc_CXXFLAGS = $(WERROR) $(TESTS_CXXFLAGS) tests_lib_test_grpc_CPPFLAGS = $(TESTS_CPPFLAGS) tests_lib_test_grpc_LDADD = $(GRPC_TESTS_LDADD) tests_lib_test_grpc_SOURCES = tests/lib/test_grpc.cpp +nodist_tests_lib_test_grpc_SOURCES = \ + yang/frr-bfdd.yang.c \ + yang/frr-staticd.yang.c \ + # end ############################################################################## From d50730ba48e337c6424ed7daba241d762060415d Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 17 May 2024 22:04:40 +0300 Subject: [PATCH 115/472] bgpd: Fix logging message when receiving a software version capability Signed-off-by: Donatas Abraitis --- bgpd/bgp_open.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 1c3bb6e7755f..e163df5954ee 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -998,8 +998,8 @@ static int bgp_capability_software_version(struct peer *peer, peer->soft_version = XSTRDUP(MTYPE_BGP_SOFT_VERSION, str); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s sent Software Version: %s", peer->host, - peer->soft_version); + zlog_debug("%s received Software Version: %s", + peer->host, peer->soft_version); } return 0; From f4ba47238e9d0c5b9efa5e42d7689cc7bb9c0334 Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Fri, 17 May 2024 12:36:31 -0700 Subject: [PATCH 116/472] bgpd: backpressure - Fix to withdraw evpn type-5 routes immediately As part of backpressure changes, there is a bug where immediate withdraw is to be sent for evpn imported type-5 prefix to clear the nh neigh and RMAC entry. Fixing this by sending withdraw immediately to keep it inline with the code today Ticket: #3905571 Signed-off-by: Donald Sharp Signed-off-by: Rajasekar Raja --- bgpd/bgp_route.c | 3 +-- bgpd/bgp_zebra.c | 9 ++------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index d24ffc0ac0d3..2309b710ed2c 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3810,8 +3810,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, */ if (old_select && is_route_parent_evpn(old_select)) - bgp_zebra_route_install(dest, old_select, bgp, - false, NULL, false); + bgp_zebra_withdraw_actual(dest, old_select, bgp); bgp_zebra_route_install(dest, new_select, bgp, true, NULL, false); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index aaad7e8a2a5f..1c2f08465d70 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1891,11 +1891,9 @@ static void bgp_zebra_buffer_write_ready(void) * save new pi, mark as going to be * withdrawan, remove install flag * - * Withdrawal Install Special case, send withdrawal immediately - * Leave dest on list, release old pi, + * Withdrawal Install Leave dest on list, release old pi, * save new pi, mark as going to be - * installed. + * installed. * Withdrawal Withdrawal Leave dest on list, release old pi, * save new pi, mark as going to be * withdrawn. @@ -1950,9 +1948,6 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, dest->za_bgp_pi = info; } else if (CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE)) { assert(dest->za_bgp_pi); - if (install & !is_evpn) - bgp_zebra_withdraw_actual(dest, dest->za_bgp_pi, bgp); - bgp_path_info_unlock(dest->za_bgp_pi); bgp_path_info_lock(info); dest->za_bgp_pi = info; From 920bf45e101c2163f4ed4a6d354026609e1eaeca Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Fri, 17 May 2024 15:43:59 -0700 Subject: [PATCH 117/472] bgpd: backpressure - Fix to avoid CPU hog In case when bgp_evpn_free or bgp_delete is called and the announce_list has few items where vpn/bgp does not match, we add the item back to the list. Because of this the list count is always > 0 thereby hogging CPU or infinite loop. Ticket: #3905624 Signed-off-by: Rajasekar Raja --- bgpd/bgp_evpn.c | 4 +++- bgpd/bgpd.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 1c3b4e05c636..ce9666d6115a 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -6317,9 +6317,11 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) { struct bgp_dest *dest = NULL; + uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head); - while (zebra_announce_count(&bm->zebra_announce_head)) { + while (ann_count) { dest = zebra_announce_pop(&bm->zebra_announce_head); + ann_count--; if (dest->za_vpn == vpn) { bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 80383dacdf40..09e64cf9ec31 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3908,11 +3908,13 @@ int bgp_delete(struct bgp *bgp) int i; struct bgp_dest *dest = NULL; struct graceful_restart_info *gr_info; + uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head); assert(bgp); - while (zebra_announce_count(&bm->zebra_announce_head)) { + while (ann_count) { dest = zebra_announce_pop(&bm->zebra_announce_head); + ann_count--; if (dest->za_bgp_pi->peer->bgp == bgp) { bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); From fdcd6749a2a77d3a7beb9fce071d73af7c3576c5 Mon Sep 17 00:00:00 2001 From: zhou-run <166502045+zhou-run@users.noreply.github.com> Date: Sat, 18 May 2024 11:13:35 +0800 Subject: [PATCH 118/472] isisd: fix crash when configuring the circuit type for the interface. 1. When both Router A and Router B are configured with "is-type level-1," the area->is_type will be assigned the value IS_LEVEL_1, and circuit->is_type will also be assigned the value IS_LEVEL_1. 2. Configuring the circuit type "isis circuit-type level-1-2" for the interface of Router A will inadvertently call lib_interface_isis_circuit_type_modify to assign circuit->is_type the value IS_LEVEL_1_AND_2. This causes the hello packets reception and transmission, as well as the reception of LSP/SNP packets, to check circuit->is_type, allowing the level-2 hello packets to be sent and received normally, and level-2 LSP/SNP packets to be received normally. 3. When Router B modifies the configuration to "is-type level-2," and Router A and Router B establish a level-2 neighbor relationship, Router B sends level-2 LSP packets to Router A. Upon receiving these, Router A calls isis_spf_schedule to calculate the level-2 SPT, which results in accessing a null pointer. When defining the behavior of the ISIS router, the call to isis_area_is_type_set will check that area->is_type is not IS_LEVEL_1_AND_2, and it disallows circuit->is_type_config from overriding circuit->is_type. Therefore, when configuring the circuit type for the interface of Router A, it should also check that area->is_type is not IS_LEVEL_1_AND_2 and disallow circuit->is_type_config from overriding circuit->is_type. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> --- isisd/isis_nb_config.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 5794e16a115b..763b8b73d270 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -3821,7 +3821,8 @@ int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args) case NB_EV_APPLY: circuit = nb_running_get_entry(args->dnode, NULL, true); circuit->is_type_config = circ_type; - isis_circuit_is_type_set(circuit, circ_type); + if (!circuit->area || circuit->area->is_type == IS_LEVEL_1_AND_2) + isis_circuit_is_type_set(circuit, circ_type); break; } From 31fc89b2301ca624a331539c0a077627bacddbe2 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 17 May 2024 17:57:46 +0200 Subject: [PATCH 119/472] bgpd, tests: fix route leaking from the default l3vrf Leaked route from the l3VRF are installed with the loopback as the nexthop interface instead of the real interface. > B>* 10.0.0.0/30 [20/0] is directly connected, lo (vrf default), weight 1, 00:21:01 Routing of packet from a L3VRF to the default L3VRF destined to a leak prefix fails because of the default routing rules on Linux. > 0: from all lookup local > 1000: from all lookup [l3mdev-table] > 32766: from all lookup main > 32767: from all lookup default When the packet is received in the loopback interface, the local rules are checked without match, then the l3mdev-table says to route to the loopback. A routing loop occurs (TTL is decreasing). > 12:26:27.928748 ens37 In IP (tos 0x0, ttl 64, id 26402, offset 0, flags [DF], proto ICMP (1), length 84) > 10.0.0.2 > 10.0.1.2: ICMP echo request, id 47463, seq 1, length 64 > 12:26:27.928784 red Out IP (tos 0x0, ttl 63, id 26402, offset 0, flags [DF], proto ICMP (1), length 84) > 10.0.0.2 > 10.0.1.2: ICMP echo request, id 47463, seq 1, length 64 > 12:26:27.928797 ens38 Out IP (tos 0x0, ttl 63, id 26402, offset 0, flags [DF], proto ICMP (1), length 84) > 10.0.0.2 > 10.0.1.2: ICMP echo request, id 47463, seq 1, length 64 Do not set the lo interface as a nexthop interface. Keep the real interface where possible. Fixes: db7cf73a33 ("bgpd: fix interface on leaks from redistribute connected") Fixes: 067fbab4e4 ("bgpd: fix interface on leaks from network statement") Fixes: 8a02d9fe1e ("bgpd: Set nh ifindex to VRF's interface, not the real") Fixes: https://github.com/FRRouting/frr/issues/15909 Signed-off-by: Louis Scalbert --- bgpd/bgp_mplsvpn.c | 5 +++-- .../test_bgp-vrf-route-leak-basic.py | 2 +- .../ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index d17fdc716950..39f8f84a02eb 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -2240,8 +2240,9 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ * Let the kernel to decide with double lookup the real next-hop * interface when installing the route. */ - if (src_bgp || bpi_ultimate->sub_type == BGP_ROUTE_STATIC || - bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE) { + if (src_vrf->vrf_id != VRF_DEFAULT && + (src_bgp || bpi_ultimate->sub_type == BGP_ROUTE_STATIC || + bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)) { ifp = if_get_vrf_loopback(src_vrf->vrf_id); if (ifp) static_attr.nh_ifindex = ifp->ifindex; diff --git a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py index 013ddfece9c3..3938a966eea2 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py +++ b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py @@ -116,7 +116,7 @@ def test_vrf_route_leak_donna(): "nexthops": [ { "fib": True, - "interfaceName": "lo", + "interfaceName": "dummy0", "vrf": "default", "active": True, }, diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt index 6ab1bb8f92cd..1495c8893670 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt @@ -1,9 +1,9 @@ VRF ray: B 10.0.1.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX -B 10.0.2.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.2.0/24 [20/0] is directly connected, r2-eth0 (vrf default) inactive, weight 1, XX:XX:XX B>* 10.0.3.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2, weight 1, XX:XX:XX -B 10.0.20.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX +B 10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX O 10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX C>* 10.0.40.0/24 is directly connected, r2-eth2, XX:XX:XX From 31da224cdf23c5ace028b6bb60a2a855dc148e4f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 20 May 2024 15:44:00 -0400 Subject: [PATCH 120/472] doc: Fixup `show ip route` command doc The documentation for this command is just... wrong. Let's clean it up. Signed-off-by: Donald Sharp --- doc/user/zebra.rst | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 72b4f2041852..b04d65094fa8 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1453,23 +1453,26 @@ To program the PBR rules as rte_flows you additionally need to configure zebra Terminal Mode Commands ============================ -.. clicmd:: show ip route +.. clicmd:: show [ip|ipv6] route Display current routes which zebra holds in its database. :: Router# show ip route - Codes: K - kernel route, C - connected, S - static, R - RIP, - B - BGP * - FIB route. + Codes: K - kernel route, C - connected, L - local, S - static, + R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP, + F - PBR, f - OpenFabric, t - Table-Direct, + > - selected route, * - FIB route, q - queued, r - rejected, b - backup + t - trapped, o - offload failure + + K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 00:30:22 + S> 4.5.6.7/32 [1/0] via 192.168.119.1 (recursive), weight 1, 00:30:22 + * via 192.168.119.1, enp13s0, weight 1, 00:30:22 + K>* 169.254.0.0/16 [0/1000] is directly connected, virbr2 linkdown, 00:30:22 + L>* 192.168.119.205/32 is directly connected, enp13s0, 00:30:22 - K* 0.0.0.0/0 203.181.89.241 - S 0.0.0.0/0 203.181.89.1 - C* 127.0.0.0/8 lo - C* 203.181.89.240/28 eth0 - - -.. clicmd:: show ipv6 route .. clicmd:: show [ip|ipv6] route [PREFIX] [nexthop-group] From d284e2229691baf3f1df0af1b184932d06828cdc Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 20 May 2024 15:46:29 -0400 Subject: [PATCH 121/472] doc: Add missing `show ip route summ` command Signed-off-by: Donald Sharp --- doc/user/zebra.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index b04d65094fa8..37644dc88a78 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1479,6 +1479,15 @@ zebra Terminal Mode Commands Display detailed information about a route. If [nexthop-group] is included, it will display the nexthop group ID the route is using as well. +.. clicmd:: show [ip|ipv6] route summary + + Display summary information about routes received from each protocol. + This command displays the entries received from each route and as such + this total can be more than the actual number of FIB routes. Finally + due to the way that linux supports local and connected routes the FIB + total may not be exactly what is shown in the equivalent `ip route show` + command to see the state of the linux kernel. + .. clicmd:: show interface [NAME] [{vrf VRF|brief}] [json] .. clicmd:: show interface [NAME] [{vrf all|brief}] [json] From 705e8ef78f84dea3af5943a74571f968ad076c8d Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Thu, 16 May 2024 16:36:18 -0700 Subject: [PATCH 122/472] zebra: Deny the routes if ip protocol CLI refers to an undefined rmap Currently zebra does not deny the routes if `ip protocol route-map FOO` commmand is configured with reference to an undefined route-map (FOO in this case). However, on FRR restart, in zebra_route_map_check() routes get denied if route-map name is available but the route-map is not defined. This change was introduced in fd303a4ba14c762550db972317e1e88528768005. Fix: When `ip protocol route-map FOO` CLI is configured with reference to an undefined route-map FOO, let the processing in ip_protocol_rm_add() and ip_protocol_rm_del() go through so that zebra can deny the routes instead of simply returning. This will result in consistent behavior. Testing Done: Before fix: ``` spine-1# configure spine-1(config)# ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# vtysh -c "show run" | grep rmap7 ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 02:27:45 B>* 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1, weight 1, 02:27:35 B>* 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2, weight 1, 02:27:40 B>* 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3, weight 1, 02:27:40 B>* 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4, weight 1, 02:27:40 ``` After fix: ``` spine-1(config)# ip protocol bgp route-map route-map67 spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 00:35:03 B 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1 inactive, weight 1, 00:34:58 B 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2 inactive, weight 1, 00:34:57 B 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3 inactive, weight 1, 00:34:57 B 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4 inactive, weight 1, 00:34:58 spine-1(config)# root@spine-1:mgmt:/var/home/cumulus# ip route show root@spine-1:mgmt:/var/home/cumulus# ``` Signed-off-by: Pooja Jagadeesh Doijode --- zebra/zebra_routemap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 95da7891083e..c1ec5067d95f 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -299,8 +299,7 @@ int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype, route_map_lookup_by_name(PROTO_RM_NAME(zvrf, afi, rtype)); route_map_counter_increment(PROTO_RM_MAP(zvrf, afi, rtype)); - if (PROTO_RM_MAP(zvrf, afi, rtype)) { - + if (PROTO_RM_NAME(zvrf, afi, rtype)) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( "%u: IPv4 Routemap config for protocol %d scheduling RIB processing", @@ -326,7 +325,7 @@ int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, if (!rmap || strcmp(rmap, PROTO_RM_NAME(zvrf, afi, rtype)) == 0) { route_map_counter_decrement(PROTO_RM_MAP(zvrf, afi, rtype)); - if (PROTO_RM_MAP(zvrf, afi, rtype)) { + if (PROTO_RM_NAME(zvrf, afi, rtype)) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( "%u: IPv4 Routemap unconfig for protocol %d, scheduling RIB processing", From 043cff5286f63dd62b7aaf9f4a0d7deaef5659db Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 16 May 2024 23:27:34 +0300 Subject: [PATCH 123/472] bgpd: Split `rpki cache` command into separate per SSH/TCP Current command (bundled two into one) is absolutely wrong. When you configure TCP session with the source, the command thinks, that it's a SSH session with a username. It's much better to split this into two separate commands where it's much easier to do the changes in the future (if more options comes in). Yes, this is a breaking change, but there is no other proper way to overcome this. Bonus note how it looks, which also can lead to crashes (due to port 0x0): ``` (gdb) p *cache->tr_config.ssh_config $11 = {host = 0x5555562f9cd0 "1.1.1.1", port = 0, bindaddr = 0x0, username = 0x55555629ad00 "", server_hostkey_path = 0x7ffff53667a0 "Uf\017\357\300H\211\345AWAVAUATSH\201", , client_privkey_path = 0x0, data = 0x0, new_socket = 0x51, connect_timeout = 4143762592, password = 0x7ffff6fccca0 "\300\"0VUU"} (gdb) p *cache->tr_config.tcp_config $12 = {host = 0x5555562f9cd0 "1.1.1.1", port = 0x0, bindaddr = 0x0, data = 0x55555629ad00, new_socket = 0x7ffff53667a0 , connect_timeout = 0} ``` Signed-off-by: Donatas Abraitis --- bgpd/bgp_rpki.c | 165 +++++++++++++++++- doc/user/rpki.rst | 25 +-- tests/topotests/bgp_rpki_topo1/r2/bgpd.conf | 2 +- .../bgp_rpki_topo1/test_bgp_rpki_topo1.py | 6 +- 4 files changed, 173 insertions(+), 25 deletions(-) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 67f59edb9307..08a7e1896ff7 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -1621,7 +1621,7 @@ static int bgp_rpki_write_vrf(struct vty *vty, struct vrf *vrf) #endif case TCP: tcp_config = cache->tr_config.tcp_config; - vty_out(vty, "%s rpki cache %s %s ", sep, + vty_out(vty, "%s rpki cache tcp %s %s ", sep, tcp_config->host, tcp_config->port); if (tcp_config->bindaddr) vty_out(vty, "source %s ", @@ -1630,7 +1630,7 @@ static int bgp_rpki_write_vrf(struct vty *vty, struct vrf *vrf) #if defined(FOUND_SSH) case SSH: ssh_config = cache->tr_config.ssh_config; - vty_out(vty, "%s rpki cache %s %u %s %s %s ", sep, + vty_out(vty, "%s rpki cache ssh %s %u %s %s %s ", sep, ssh_config->host, ssh_config->port, ssh_config->username, ssh_config->client_privkey_path, @@ -1918,6 +1918,9 @@ DEFUN (no_rpki_retry_interval, return CMD_SUCCESS; } +#if CONFDATE > 20240916 +CPP_NOTICE("Remove rpki_cache_cmd") +#endif DEFPY(rpki_cache, rpki_cache_cmd, "rpki cache [source $bindaddr] preference (1-255)", RPKI_OUTPUT_STRING @@ -1990,12 +1993,136 @@ DEFPY(rpki_cache, rpki_cache_cmd, return CMD_SUCCESS; } +DEFPY(rpki_cache_tcp, rpki_cache_tcp_cmd, + "rpki cache tcp $cache TCPPORT [source $bindaddr] preference (1-255)", + RPKI_OUTPUT_STRING + "Install a cache server to current group\n" + "Use TCP\n" + "IP address of cache server\n" + "Hostname of cache server\n" + "TCP port number\n" + "Configure source IP address of RPKI connection\n" + "Define a Source IP Address\n" + "Preference of the cache server\n" + "Preference value\n") +{ + int return_value; + struct listnode *cache_node; + struct cache *current_cache; + struct rpki_vrf *rpki_vrf; + bool init; + + if (vty->node == RPKI_VRF_NODE) + rpki_vrf = VTY_GET_CONTEXT_SUB(rpki_vrf); + else + rpki_vrf = VTY_GET_CONTEXT(rpki_vrf); + + if (!rpki_vrf) + return CMD_WARNING_CONFIG_FAILED; + + if (!rpki_vrf || !rpki_vrf->cache_list) + return CMD_WARNING; + + init = !!list_isempty(rpki_vrf->cache_list); + + for (ALL_LIST_ELEMENTS_RO(rpki_vrf->cache_list, cache_node, + current_cache)) { + if (current_cache->preference == preference) { + vty_out(vty, + "Cache with preference %ld is already configured\n", + preference); + return CMD_WARNING; + } + } + + return_value = add_tcp_cache(rpki_vrf, cache, tcpport, preference, + bindaddr_str); + + if (return_value == ERROR) { + vty_out(vty, "Could not create new rpki cache\n"); + return CMD_WARNING; + } + + if (init) + start(rpki_vrf); + + return CMD_SUCCESS; +} + +DEFPY(rpki_cache_ssh, rpki_cache_ssh_cmd, + "rpki cache ssh $cache (1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY] [source $bindaddr] preference (1-255)", + RPKI_OUTPUT_STRING + "Install a cache server to current group\n" + "Use SSH\n" + "IP address of cache server\n" + "Hostname of cache server\n" + "SSH port number\n" + "SSH user name\n" + "Path to own SSH private key\n" + "Path to Public key of cache server\n" + "Configure source IP address of RPKI connection\n" + "Define a Source IP Address\n" + "Preference of the cache server\n" + "Preference value\n") +{ + int return_value; + struct listnode *cache_node; + struct cache *current_cache; + struct rpki_vrf *rpki_vrf; + bool init; + + if (vty->node == RPKI_VRF_NODE) + rpki_vrf = VTY_GET_CONTEXT_SUB(rpki_vrf); + else + rpki_vrf = VTY_GET_CONTEXT(rpki_vrf); + + if (!rpki_vrf) + return CMD_WARNING_CONFIG_FAILED; + + if (!rpki_vrf || !rpki_vrf->cache_list) + return CMD_WARNING; + + init = !!list_isempty(rpki_vrf->cache_list); + + for (ALL_LIST_ELEMENTS_RO(rpki_vrf->cache_list, cache_node, + current_cache)) { + if (current_cache->preference == preference) { + vty_out(vty, + "Cache with preference %ld is already configured\n", + preference); + return CMD_WARNING; + } + } + +#if defined(FOUND_SSH) + return_value = add_ssh_cache(rpki_vrf, cache, sshport, ssh_uname, + ssh_privkey, server_pubkey, preference, + bindaddr_str); +#else + return_value = SUCCESS; + vty_out(vty, + "ssh sockets are not supported. Please recompile rtrlib and frr with ssh support. If you want to use it\n"); +#endif + + if (return_value == ERROR) { + vty_out(vty, "Could not create new rpki cache\n"); + return CMD_WARNING; + } + + if (init) + start(rpki_vrf); + + return CMD_SUCCESS; +} + DEFPY (no_rpki_cache, no_rpki_cache_cmd, - "no rpki cache [source $bindaddr] preference (1-255)", + "no rpki cache [source $bindaddr] preference (1-255)", NO_STR RPKI_OUTPUT_STRING "Install a cache server to current group\n" + "Use TCP\n" + "Use SSH\n" "IP address of cache server\n" "Hostname of cache server\n" "TCP port number\n" @@ -2257,10 +2384,16 @@ DEFPY (show_rpki_cache_server, if (cache->type == TCP) { if (!json) { vty_out(vty, - "host: %s port: %s, preference: %hhu\n", + "host: %s port: %s, preference: %hhu, protocol: tcp", cache->tr_config.tcp_config->host, cache->tr_config.tcp_config->port, cache->preference); + if (cache->tr_config.tcp_config->bindaddr) + vty_out(vty, ", source: %s\n", + cache->tr_config.tcp_config + ->bindaddr); + else + vty_out(vty, "\n"); } else { json_server = json_object_new_object(); json_object_string_add(json_server, "mode", @@ -2273,6 +2406,12 @@ DEFPY (show_rpki_cache_server, cache->tr_config.tcp_config->port); json_object_int_add(json_server, "preference", cache->preference); + if (cache->tr_config.tcp_config->bindaddr) + json_object_string_add(json_server, + "source", + cache->tr_config + .tcp_config + ->bindaddr); json_object_array_add(json_servers, json_server); } @@ -2281,7 +2420,7 @@ DEFPY (show_rpki_cache_server, } else if (cache->type == SSH) { if (!json) { vty_out(vty, - "host: %s port: %d username: %s server_hostkey_path: %s client_privkey_path: %s, preference: %hhu\n", + "host: %s, port: %d, username: %s, server_hostkey_path: %s, client_privkey_path: %s, preference: %hhu, protocol: ssh", cache->tr_config.ssh_config->host, cache->tr_config.ssh_config->port, cache->tr_config.ssh_config->username, @@ -2290,6 +2429,12 @@ DEFPY (show_rpki_cache_server, cache->tr_config.ssh_config ->client_privkey_path, cache->preference); + if (cache->tr_config.ssh_config->bindaddr) + vty_out(vty, ", source: %s\n", + cache->tr_config.ssh_config + ->bindaddr); + else + vty_out(vty, "\n"); } else { json_server = json_object_new_object(); json_object_string_add(json_server, "mode", @@ -2313,6 +2458,12 @@ DEFPY (show_rpki_cache_server, ->client_privkey_path); json_object_int_add(json_server, "preference", cache->preference); + if (cache->tr_config.ssh_config->bindaddr) + json_object_string_add(json_server, + "source", + cache->tr_config + .ssh_config + ->bindaddr); json_object_array_add(json_servers, json_server); } @@ -2665,6 +2816,8 @@ static void install_cli_commands(void) install_element(RPKI_NODE, &no_rpki_retry_interval_cmd); /* Install rpki cache commands */ + install_element(RPKI_NODE, &rpki_cache_tcp_cmd); + install_element(RPKI_NODE, &rpki_cache_ssh_cmd); install_element(RPKI_NODE, &rpki_cache_cmd); install_element(RPKI_NODE, &no_rpki_cache_cmd); @@ -2687,6 +2840,8 @@ static void install_cli_commands(void) install_element(RPKI_VRF_NODE, &no_rpki_retry_interval_cmd); /* Install rpki cache commands */ + install_element(RPKI_VRF_NODE, &rpki_cache_tcp_cmd); + install_element(RPKI_VRF_NODE, &rpki_cache_ssh_cmd); install_element(RPKI_VRF_NODE, &rpki_cache_cmd); install_element(RPKI_VRF_NODE, &no_rpki_cache_cmd); diff --git a/doc/user/rpki.rst b/doc/user/rpki.rst index fe9e407ca9c0..394327e2ff77 100644 --- a/doc/user/rpki.rst +++ b/doc/user/rpki.rst @@ -131,19 +131,13 @@ The following commands are available for independent of a specific cache server. The default value is 600 seconds. -.. clicmd:: rpki cache (A.B.C.D|WORD) PORT [SSH_USERNAME] [SSH_PRIVKEY_PATH] [KNOWN_HOSTS_PATH] [source A.B.C.D] preference (1-255) +.. clicmd:: rpki cache tcp HOST PORT [source A.B.C.D] preference (1-255) + Add a TCP cache server to the socket. - Add a cache server to the socket. By default, the connection between router - and cache server is based on plain TCP. Protecting the connection between - router and cache server by SSH is optional. Deleting a socket removes the - associated cache server and terminates the existing connection. +.. clicmd:: rpki cache ssh HOST PORT SSH_USERNAME SSH_PRIVKEY_PATH [SERVER_PUBKEY] [source A.B.C.D] preference (1-255) - A.B.C.D|WORD - Address of the cache server. - - PORT - Port number to connect to the cache server + Add a SSH cache server to the socket. SSH_USERNAME SSH username to establish an SSH connection to the cache server. @@ -151,7 +145,7 @@ The following commands are available for independent of a specific cache server. SSH_PRIVKEY_PATH Local path that includes the private key file of the router. - KNOWN_HOSTS_PATH + SERVER_PUBKEY Local path that includes the known hosts file. The default value depends on the configuration of the operating system environment, usually :file:`~/.ssh/known_hosts`. @@ -159,7 +153,6 @@ The following commands are available for independent of a specific cache server. source A.B.C.D Source address of the RPKI connection to access cache server. - .. _validating-bgp-updates: Validating BGP Updates @@ -267,9 +260,9 @@ RPKI Configuration Example rpki polling_period 1000 rpki timeout 10 ! SSH Example: - rpki cache example.com 22 rtr-ssh ./ssh_key/id_rsa preference 1 + rpki cache ssh example.com 22 rtr-ssh ./ssh_key/id_rsa preference 1 ! TCP Example: - rpki cache rpki-validator.realmv6.org 8282 preference 2 + rpki cache tcp rpki-validator.realmv6.org 8282 preference 2 exit ! exit-vrf @@ -278,9 +271,9 @@ RPKI Configuration Example rpki polling_period 1000 rpki timeout 10 ! SSH Example: - rpki cache example.com source 198.51.100.223 22 rtr-ssh ./ssh_key/id_rsa preference 1 + rpki cache ssh example.com source 198.51.100.223 22 rtr-ssh ./ssh_key/id_rsa preference 1 ! TCP Example: - rpki cache rpki-validator.realmv6.org 8282 preference 2 + rpki cache tcp rpki-validator.realmv6.org 8282 preference 2 exit ! router bgp 65001 diff --git a/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf b/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf index 87d721497275..4de177dc2586 100644 --- a/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf +++ b/tests/topotests/bgp_rpki_topo1/r2/bgpd.conf @@ -21,5 +21,5 @@ router bgp 65002 vrf vrf10 ! rpki rpki retry_interval 5 - rpki cache 192.0.2.1 15432 preference 1 + rpki cache tcp 192.0.2.1 15432 preference 1 exit diff --git a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py index a12204f240a9..f52b28a0620c 100644 --- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py +++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py @@ -189,7 +189,7 @@ def _show_rpki_no_connection(rname): """ configure rpki - no rpki cache 192.0.2.1 15432 preference 1 + no rpki cache tcp 192.0.2.1 15432 preference 1 exit """ ) @@ -219,7 +219,7 @@ def test_show_bgp_rpki_prefixes_reconnect(): """ configure rpki - rpki cache 192.0.2.1 15432 preference 1 + rpki cache tcp 192.0.2.1 15432 preference 1 exit """ ) @@ -319,7 +319,7 @@ def test_show_bgp_rpki_prefixes_vrf(): configure vrf vrf10 rpki - rpki cache 192.0.2.3 15432 preference 1 + rpki cache tcp 192.0.2.3 15432 preference 1 exit exit """ From d536fb675bba7bdc61f1efbf3794c09ab965e559 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 21 May 2024 09:00:24 +0300 Subject: [PATCH 124/472] bgpd: Rename SERVER_PUBKEY to KNOWN_HOSTS_PATH SERVER_PUBKEY is not the best name to describe what it really is. Signed-off-by: Donatas Abraitis --- bgpd/bgp_rpki.c | 16 ++++++++-------- doc/user/rpki.rst | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 08a7e1896ff7..f5508a0a7345 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -1922,7 +1922,7 @@ DEFUN (no_rpki_retry_interval, CPP_NOTICE("Remove rpki_cache_cmd") #endif DEFPY(rpki_cache, rpki_cache_cmd, - "rpki cache [source $bindaddr] preference (1-255)", + "rpki cache [source $bindaddr] preference (1-255)", RPKI_OUTPUT_STRING "Install a cache server to current group\n" "IP address of cache server\n" @@ -1931,7 +1931,7 @@ DEFPY(rpki_cache, rpki_cache_cmd, "SSH port number\n" "SSH user name\n" "Path to own SSH private key\n" - "Path to Public key of cache server\n" + "Path to the known hosts file\n" "Configure source IP address of RPKI connection\n" "Define a Source IP Address\n" "Preference of the cache server\n" @@ -1970,7 +1970,7 @@ DEFPY(rpki_cache, rpki_cache_cmd, if (ssh_uname) { #if defined(FOUND_SSH) return_value = add_ssh_cache(rpki_vrf, cache, sshport, ssh_uname, - ssh_privkey, server_pubkey, + ssh_privkey, known_hosts_path, preference, bindaddr_str); #else return_value = SUCCESS; @@ -2050,7 +2050,7 @@ DEFPY(rpki_cache_tcp, rpki_cache_tcp_cmd, } DEFPY(rpki_cache_ssh, rpki_cache_ssh_cmd, - "rpki cache ssh $cache (1-65535)$sshport SSH_UNAME SSH_PRIVKEY [SERVER_PUBKEY] [source $bindaddr] preference (1-255)", + "rpki cache ssh $cache (1-65535)$sshport SSH_UNAME SSH_PRIVKEY [KNOWN_HOSTS_PATH] [source $bindaddr] preference (1-255)", RPKI_OUTPUT_STRING "Install a cache server to current group\n" "Use SSH\n" @@ -2059,7 +2059,7 @@ DEFPY(rpki_cache_ssh, rpki_cache_ssh_cmd, "SSH port number\n" "SSH user name\n" "Path to own SSH private key\n" - "Path to Public key of cache server\n" + "Path to the known hosts file\n" "Configure source IP address of RPKI connection\n" "Define a Source IP Address\n" "Preference of the cache server\n" @@ -2096,7 +2096,7 @@ DEFPY(rpki_cache_ssh, rpki_cache_ssh_cmd, #if defined(FOUND_SSH) return_value = add_ssh_cache(rpki_vrf, cache, sshport, ssh_uname, - ssh_privkey, server_pubkey, preference, + ssh_privkey, known_hosts_path, preference, bindaddr_str); #else return_value = SUCCESS; @@ -2117,7 +2117,7 @@ DEFPY(rpki_cache_ssh, rpki_cache_ssh_cmd, DEFPY (no_rpki_cache, no_rpki_cache_cmd, - "no rpki cache [source $bindaddr] preference (1-255)", + "no rpki cache [source $bindaddr] preference (1-255)", NO_STR RPKI_OUTPUT_STRING "Install a cache server to current group\n" @@ -2129,7 +2129,7 @@ DEFPY (no_rpki_cache, "SSH port number\n" "SSH user name\n" "Path to own SSH private key\n" - "Path to Public key of cache server\n" + "Path to the known hosts file\n" "Configure source IP address of RPKI connection\n" "Define a Source IP Address\n" "Preference of the cache server\n" diff --git a/doc/user/rpki.rst b/doc/user/rpki.rst index 394327e2ff77..98f9b103cdf9 100644 --- a/doc/user/rpki.rst +++ b/doc/user/rpki.rst @@ -135,7 +135,7 @@ The following commands are available for independent of a specific cache server. Add a TCP cache server to the socket. -.. clicmd:: rpki cache ssh HOST PORT SSH_USERNAME SSH_PRIVKEY_PATH [SERVER_PUBKEY] [source A.B.C.D] preference (1-255) +.. clicmd:: rpki cache ssh HOST PORT SSH_USERNAME SSH_PRIVKEY_PATH [KNOWN_HOSTS_PATH] [source A.B.C.D] preference (1-255) Add a SSH cache server to the socket. @@ -145,7 +145,7 @@ The following commands are available for independent of a specific cache server. SSH_PRIVKEY_PATH Local path that includes the private key file of the router. - SERVER_PUBKEY + KNOWN_HOSTS_PATH Local path that includes the known hosts file. The default value depends on the configuration of the operating system environment, usually :file:`~/.ssh/known_hosts`. From e697de58431474cdb06eff79bcbc70de4215e222 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 16 May 2024 16:44:03 +0200 Subject: [PATCH 125/472] isisd: fix heap-after-free with prefix sid > ==2334217==ERROR: AddressSanitizer: heap-use-after-free on address 0x61000001d0a0 at pc 0x563828c8de6f bp 0x7fffbdaee560 sp 0x7fffbdaee558 > READ of size 1 at 0x61000001d0a0 thread T0 > #0 0x563828c8de6e in prefix_sid_cmp isisd/isis_spf.c:187 > #1 0x7f84b8204f71 in hash_get lib/hash.c:142 > #2 0x7f84b82055ec in hash_lookup lib/hash.c:184 > #3 0x563828c8e185 in isis_spf_prefix_sid_lookup isisd/isis_spf.c:209 > #4 0x563828c90642 in isis_spf_add2tent isisd/isis_spf.c:598 > #5 0x563828c91cd0 in process_N isisd/isis_spf.c:824 > #6 0x563828c93852 in isis_spf_process_lsp isisd/isis_spf.c:1041 > #7 0x563828c98dde in isis_spf_loop isisd/isis_spf.c:1821 > #8 0x563828c998de in isis_run_spf isisd/isis_spf.c:1983 > #9 0x563828c99c7b in isis_run_spf_with_protection isisd/isis_spf.c:2009 > #10 0x563828c9a60d in isis_run_spf_cb isisd/isis_spf.c:2090 > #11 0x7f84b835c72d in event_call lib/event.c:2011 > #12 0x7f84b8236d93 in frr_run lib/libfrr.c:1217 > #13 0x563828c21918 in main isisd/isis_main.c:346 > #14 0x7f84b7e4fd09 in __libc_start_main ../csu/libc-start.c:308 > #15 0x563828c20df9 in _start (/usr/lib/frr/isisd+0xf5df9) > > 0x61000001d0a0 is located 96 bytes inside of 184-byte region [0x61000001d040,0x61000001d0f8) > freed by thread T0 here: > #0 0x7f84b88a9b6f in __interceptor_free ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:123 > #1 0x7f84b8263bae in qfree lib/memory.c:130 > #2 0x563828c8e433 in isis_vertex_del isisd/isis_spf.c:249 > #3 0x563828c91c95 in process_N isisd/isis_spf.c:811 > #4 0x563828c93852 in isis_spf_process_lsp isisd/isis_spf.c:1041 > #5 0x563828c98dde in isis_spf_loop isisd/isis_spf.c:1821 > #6 0x563828c998de in isis_run_spf isisd/isis_spf.c:1983 > #7 0x563828c99c7b in isis_run_spf_with_protection isisd/isis_spf.c:2009 > #8 0x563828c9a60d in isis_run_spf_cb isisd/isis_spf.c:2090 > #9 0x7f84b835c72d in event_call lib/event.c:2011 > #10 0x7f84b8236d93 in frr_run lib/libfrr.c:1217 > #11 0x563828c21918 in main isisd/isis_main.c:346 > #12 0x7f84b7e4fd09 in __libc_start_main ../csu/libc-start.c:308 > > previously allocated by thread T0 here: > #0 0x7f84b88aa037 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 > #1 0x7f84b8263a6c in qcalloc lib/memory.c:105 > #2 0x563828c8e262 in isis_vertex_new isisd/isis_spf.c:225 > #3 0x563828c904db in isis_spf_add2tent isisd/isis_spf.c:588 > #4 0x563828c91cd0 in process_N isisd/isis_spf.c:824 > #5 0x563828c93852 in isis_spf_process_lsp isisd/isis_spf.c:1041 > #6 0x563828c98dde in isis_spf_loop isisd/isis_spf.c:1821 > #7 0x563828c998de in isis_run_spf isisd/isis_spf.c:1983 > #8 0x563828c99c7b in isis_run_spf_with_protection isisd/isis_spf.c:2009 > #9 0x563828c9a60d in isis_run_spf_cb isisd/isis_spf.c:2090 > #10 0x7f84b835c72d in event_call lib/event.c:2011 > #11 0x7f84b8236d93 in frr_run lib/libfrr.c:1217 > #12 0x563828c21918 in main isisd/isis_main.c:346 > #13 0x7f84b7e4fd09 in __libc_start_main ../csu/libc-start.c:308 > > SUMMARY: AddressSanitizer: heap-use-after-free isisd/isis_spf.c:187 in prefix_sid_cmp > Shadow bytes around the buggy address: > 0x0c207fffb9c0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 > 0x0c207fffb9d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa > 0x0c207fffb9e0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 > 0x0c207fffb9f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa > 0x0c207fffba00: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd > =>0x0c207fffba10: fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fa > 0x0c207fffba20: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 > 0x0c207fffba30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa > 0x0c207fffba40: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 > 0x0c207fffba50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa > 0x0c207fffba60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > Shadow byte legend (one shadow byte represents 8 application bytes): > Addressable: 00 > Partially addressable: 01 02 03 04 05 06 07 > Heap left redzone: fa > Freed heap region: fd > Stack left redzone: f1 > Stack mid redzone: f2 > Stack right redzone: f3 > Stack after return: f5 > Stack use after scope: f8 > Global redzone: f9 > Global init order: f6 > Poisoned by user: f7 > Container overflow: fc > Array cookie: ac > Intra object redzone: bb > ASan internal: fe > Left alloca redzone: ca > Right alloca redzone: cb > Shadow gap: cc > ==2334217==ABORTING Fixes: 2f7cc7bcd3 ("isisd: detect Prefix-SID collisions and handle them appropriately") Signed-off-by: Louis Scalbert --- isisd/isis_spf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 418e0af16b82..7077263b7038 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -703,6 +703,7 @@ static void isis_spf_add_local(struct isis_spftree *spftree, } else { /* vertex->d_N > cost */ /* f) */ isis_vertex_queue_delete(&spftree->tents, vertex); + hash_release(spftree->prefix_sids, vertex); isis_vertex_del(vertex); } } @@ -808,6 +809,7 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype, /* 4) */ } else { isis_vertex_queue_delete(&spftree->tents, vertex); + hash_release(spftree->prefix_sids, vertex); isis_vertex_del(vertex); } } From 4d0e9e2a9f049ff074aed953c0afc6a3be4da73e Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 22 May 2024 11:30:24 +0200 Subject: [PATCH 126/472] isisd: fix show isis route algorithm crash Fix crash with "show isis route algorithm X" command. Fixes: 88e368b4dc ("isisd: make optional algorithm id in 'show isis route'") Signed-off-by: Louis Scalbert --- isisd/isis_spf.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 418e0af16b82..d63235ce61ae 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -3123,8 +3123,7 @@ DEFUN(show_isis_route, show_isis_route_cmd, #ifndef FABRICD if (argv_find(argv, argc, "algorithm", &idx)) { if (argv_find(argv, argc, "(128-255)", &idx)) - algorithm = (uint8_t)strtoul(argv[idx + 1]->arg, NULL, - 10); + algorithm = (uint8_t)strtoul(argv[idx]->arg, NULL, 10); else all_algorithm = true; } From c2058bb0a0a657d61bb16917ee9b8f90d0dda503 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 22 May 2024 13:30:05 +0200 Subject: [PATCH 127/472] isisd: fix show isis topology display Fix "Area X:" display for fabricd Fixes: f185005b2f ("isisd: fix the display topology command") Signed-off-by: Louis Scalbert --- isisd/isis_spf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index d63235ce61ae..c19fb3244efa 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2357,10 +2357,12 @@ static void show_isis_topology_common(struct vty *vty, int levels, fa_data = (struct isis_flex_algo_data *)fa->data; } else fa_data = NULL; +#endif /* ifndef FABRICD */ vty_out(vty, "Area %s:", area->area_tag ? area->area_tag : "null"); +#ifndef FABRICD if (algo != SR_ALGORITHM_SPF) vty_out(vty, " Algorithm %hhu\n", algo); else From 47640d5e321eeb102d43d4a9b5b7b992ee37bf1b Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 22 May 2024 13:34:01 +0200 Subject: [PATCH 128/472] isisd: fix show isis segment-routing node algorithm Fix an issue where "show isis segment-routing node algorithm" displays "IS-IS X SR-Nodes:" for absent flex-algorithms. > IS-IS L2 SR-Nodes: > > IS-IS L2 SR-Nodes: > [...] Signed-off-by: Louis Scalbert --- isisd/isis_sr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c index af22f56f8bb4..f7830380064e 100644 --- a/isisd/isis_sr.c +++ b/isisd/isis_sr.c @@ -1020,8 +1020,6 @@ static void show_node(struct vty *vty, struct isis_area *area, int level, struct ttable *tt; char buf[128]; - vty_out(vty, " IS-IS %s SR-Nodes:\n\n", circuit_t2string(level)); - /* Prepare table. */ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); ttable_add_row(tt, "System ID|SRGB|SRLB|Algorithm|MSD"); @@ -1062,6 +1060,8 @@ static void show_node(struct vty *vty, struct isis_area *area, int level, if (tt->nrows > 1) { char *table; + vty_out(vty, " IS-IS %s SR-Nodes:\n\n", circuit_t2string(level)); + table = ttable_dump(tt, "\n"); vty_out(vty, "%s\n", table); XFREE(MTYPE_TMP, table); From 5009f7539ad6bf496158499917dcf3f7ab760753 Mon Sep 17 00:00:00 2001 From: zhou-run <166502045+zhou-run@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:04:39 +0800 Subject: [PATCH 129/472] isisd: Fix memory leaks when the transition of neighbor state from non-UP to DOWN When receiving a hello packet, if the neighbor state transitions directly from a non-ISIS_ADJ_UP state (such as ISIS_ADJ_INITIALIZING) to ISIS_ADJ_DOWN state, the neighbor entry cannot be deleted. If the neighbor is removed or the neighbor's System ID changes, it may result in memory leakage in the neighbor entry. Test Scenario: LAN link between Router A and Router B is established. Router A does not configure neighbor authentication, while Router B is configured with neighbor authentication. When the neighbor entry on Router B ages out, the neighbor state on Router A transitions to INIT. If Router B is then removed, the neighbor state on Router A transitions to DOWN and persists. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> fix frrbot styling issues found. fix frrbot styling issues found. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> --- isisd/isis_adjacency.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 7acd3a2b4e56..d23a865ea4a7 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -358,12 +358,15 @@ void isis_adj_state_change(struct isis_adjacency **padj, * purposes */ adj->last_flap = time(NULL); adj->flaps++; - } else if (old_state == ISIS_ADJ_UP) { - circuit->adj_state_changes++; + } else { + if (old_state == ISIS_ADJ_UP) { + circuit->adj_state_changes++; - circuit->upadjcount[level - 1]--; - if (circuit->upadjcount[level - 1] == 0) - isis_tx_queue_clean(circuit->tx_queue); + circuit->upadjcount[level - 1]--; + if (circuit->upadjcount[level - 1] == 0) + isis_tx_queue_clean( + circuit->tx_queue); + } if (new_state == ISIS_ADJ_DOWN) { listnode_delete( @@ -409,10 +412,13 @@ void isis_adj_state_change(struct isis_adjacency **padj, master, send_l2_csnp, circuit, 0, &circuit->t_send_csnp[1]); } - } else if (old_state == ISIS_ADJ_UP) { - circuit->upadjcount[level - 1]--; - if (circuit->upadjcount[level - 1] == 0) - isis_tx_queue_clean(circuit->tx_queue); + } else { + if (old_state == ISIS_ADJ_UP) { + circuit->upadjcount[level - 1]--; + if (circuit->upadjcount[level - 1] == 0) + isis_tx_queue_clean( + circuit->tx_queue); + } if (new_state == ISIS_ADJ_DOWN) { if (adj->circuit->u.p2p.neighbor == adj) From e08495a4a8ad4d2050691d9e5e13662d2635b2e0 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Thu, 16 May 2024 16:36:18 -0700 Subject: [PATCH 130/472] zebra: Deny the routes if ip protocol CLI refers to an undefined rmap Currently zebra does not deny the routes if `ip protocol route-map FOO` commmand is configured with reference to an undefined route-map (FOO in this case). However, on FRR restart, in zebra_route_map_check() routes get denied if route-map name is available but the route-map is not defined. This change was introduced in fd303a4ba14c762550db972317e1e88528768005. Fix: When `ip protocol route-map FOO` CLI is configured with reference to an undefined route-map FOO, let the processing in ip_protocol_rm_add() and ip_protocol_rm_del() go through so that zebra can deny the routes instead of simply returning. This will result in consistent behavior. Testing Done: Before fix: ``` spine-1# configure spine-1(config)# ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# vtysh -c "show run" | grep rmap7 ip protocol bgp route-map rmap7 root@spine-1:mgmt:/var/home/cumulus# spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 02:27:45 B>* 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1, weight 1, 02:27:35 B>* 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2, weight 1, 02:27:40 B>* 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3, weight 1, 02:27:40 B>* 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4, weight 1, 02:27:40 ``` After fix: ``` spine-1(config)# ip protocol bgp route-map route-map67 spine-1(config)# do show ip route Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, A - Babel, D - SHARP, F - PBR, f - OpenFabric, Z - FRR, > - selected route, * - FIB route, q - queued, r - rejected, b - backup t - trapped, o - offload failure C>* 27.0.0.1/32 is directly connected, lo, 00:35:03 B 27.0.0.3/32 [20/0] via fe80::202:ff:fe00:21, downlink_1 inactive, weight 1, 00:34:58 B 27.0.0.4/32 [20/0] via fe80::202:ff:fe00:29, downlink_2 inactive, weight 1, 00:34:57 B 27.0.0.5/32 [20/0] via fe80::202:ff:fe00:31, downlink_3 inactive, weight 1, 00:34:57 B 27.0.0.6/32 [20/0] via fe80::202:ff:fe00:39, downlink_4 inactive, weight 1, 00:34:58 spine-1(config)# root@spine-1:mgmt:/var/home/cumulus# ip route show root@spine-1:mgmt:/var/home/cumulus# ``` Signed-off-by: Pooja Jagadeesh Doijode --- zebra/zebra_routemap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 95da7891083e..c1ec5067d95f 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -299,8 +299,7 @@ int ip_protocol_rm_add(struct zebra_vrf *zvrf, const char *rmap, int rtype, route_map_lookup_by_name(PROTO_RM_NAME(zvrf, afi, rtype)); route_map_counter_increment(PROTO_RM_MAP(zvrf, afi, rtype)); - if (PROTO_RM_MAP(zvrf, afi, rtype)) { - + if (PROTO_RM_NAME(zvrf, afi, rtype)) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( "%u: IPv4 Routemap config for protocol %d scheduling RIB processing", @@ -326,7 +325,7 @@ int ip_protocol_rm_del(struct zebra_vrf *zvrf, const char *rmap, int rtype, if (!rmap || strcmp(rmap, PROTO_RM_NAME(zvrf, afi, rtype)) == 0) { route_map_counter_decrement(PROTO_RM_MAP(zvrf, afi, rtype)); - if (PROTO_RM_MAP(zvrf, afi, rtype)) { + if (PROTO_RM_NAME(zvrf, afi, rtype)) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( "%u: IPv4 Routemap unconfig for protocol %d, scheduling RIB processing", From f69d1313b19047d3d83fc2b36a518355b861dfc4 Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Wed, 3 Apr 2024 16:28:23 +0200 Subject: [PATCH 131/472] ospfd: Solved crash in RI parsing with OSPF TE Iggy Frankovic discovered another ospfd crash when performing fuzzing of OSPF LSA packets. The crash occurs in ospf_te_parse_ri() function when attemping to read Segment Routing subTLVs. The original code doesn't check if the size of the SR subTLVs have the correct length. In presence of erronous LSA, this will cause a buffer overflow and ospfd crash. This patch introduces new verification of the subTLVs size for Router Information TLV. Co-authored-by: Iggy Frankovic Signed-off-by: Olivier Dugeon --- ospfd/ospf_te.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 359dc1f5d4b8..091669d8ed36 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -2456,6 +2456,9 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) switch (ntohs(tlvh->type)) { case RI_SR_TLV_SR_ALGORITHM: + if (TLV_BODY_SIZE(tlvh) < 1 || + TLV_BODY_SIZE(tlvh) > ALGORITHM_COUNT) + break; algo = (struct ri_sr_tlv_sr_algorithm *)tlvh; for (int i = 0; i < ntohs(algo->header.length); i++) { @@ -2480,6 +2483,8 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) break; case RI_SR_TLV_SRGB_LABEL_RANGE: + if (TLV_BODY_SIZE(tlvh) != RI_SR_TLV_LABEL_RANGE_SIZE) + break; range = (struct ri_sr_tlv_sid_label_range *)tlvh; size = GET_RANGE_SIZE(ntohl(range->size)); lower = GET_LABEL(ntohl(range->lower.value)); @@ -2497,6 +2502,8 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) break; case RI_SR_TLV_SRLB_LABEL_RANGE: + if (TLV_BODY_SIZE(tlvh) != RI_SR_TLV_LABEL_RANGE_SIZE) + break; range = (struct ri_sr_tlv_sid_label_range *)tlvh; size = GET_RANGE_SIZE(ntohl(range->size)); lower = GET_LABEL(ntohl(range->lower.value)); @@ -2514,6 +2521,8 @@ static int ospf_te_parse_ri(struct ls_ted *ted, struct ospf_lsa *lsa) break; case RI_SR_TLV_NODE_MSD: + if (TLV_BODY_SIZE(tlvh) < RI_SR_TLV_NODE_MSD_SIZE) + break; msd = (struct ri_sr_tlv_node_msd *)tlvh; if ((CHECK_FLAG(node->flags, LS_NODE_MSD)) && (node->msd == msd->value)) From 5557a289acdaeec8cc63ffc97b5c2abf6dee7b3a Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Fri, 5 Apr 2024 12:57:11 +0200 Subject: [PATCH 132/472] ospfd: Correct Opaque LSA Extended parser Iggy Frankovic discovered another ospfd crash when performing fuzzing of OSPF LSA packets. The crash occurs in ospf_te_parse_ext_link() function when attemping to read Segment Routing Adjacency SID subTLVs. The original code doesn't check if the size of the Extended Link TLVs and subTLVs have the correct length. In presence of erronous LSA, this will cause a buffer overflow and ospfd crashes. This patch introduces new verification of the subTLVs size for Extended Link TLVs and subTLVs. Similar check has been also introduced for the Extended Prefix TLV. Co-authored-by: Iggy Frankovic Signed-off-by: Olivier Dugeon --- ospfd/ospf_te.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index 091669d8ed36..e68f9444f512 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -2620,6 +2620,7 @@ static int ospf_te_parse_ext_pref(struct ls_ted *ted, struct ospf_lsa *lsa) struct ext_tlv_prefix *ext; struct ext_subtlv_prefix_sid *pref_sid; uint32_t label; + uint16_t len, size; /* Get corresponding Subnet from Link State Data Base */ ext = (struct ext_tlv_prefix *)TLV_HDR_TOP(lsa->data); @@ -2641,6 +2642,18 @@ static int ospf_te_parse_ext_pref(struct ls_ted *ted, struct ospf_lsa *lsa) ote_debug(" |- Process Extended Prefix LSA %pI4 for subnet %pFX", &lsa->data->id, &pref); + /* + * Check Extended Prefix TLV size against LSA size + * as only one TLV is allowed per LSA + */ + len = TLV_BODY_SIZE(&ext->header); + size = lsa->size - (OSPF_LSA_HEADER_SIZE + TLV_HDR_SIZE); + if (len != size || len <= 0) { + ote_debug(" |- Wrong TLV size: %u instead of %u", + (uint32_t)len, (uint32_t)size); + return -1; + } + /* Initialize TLV browsing */ ls_pref = subnet->ls_pref; pref_sid = (struct ext_subtlv_prefix_sid *)((char *)(ext) + TLV_HDR_SIZE @@ -2751,8 +2764,20 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) ote_debug(" |- Process Extended Link LSA %pI4 for edge %pI4", &lsa->data->id, &edge->attributes->standard.local); - /* Initialize TLV browsing */ - len = TLV_BODY_SIZE(&ext->header) - EXT_TLV_LINK_SIZE; + /* + * Check Extended Link TLV size against LSA size + * as only one TLV is allowed per LSA + */ + len = TLV_BODY_SIZE(&ext->header); + i = lsa->size - (OSPF_LSA_HEADER_SIZE + TLV_HDR_SIZE); + if (len != i || len <= 0) { + ote_debug(" |- Wrong TLV size: %u instead of %u", + (uint32_t)len, (uint32_t)i); + return -1; + } + + /* Initialize subTLVs browsing */ + len -= EXT_TLV_LINK_SIZE; tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE + EXT_TLV_LINK_SIZE); for (; sum < len; tlvh = TLV_HDR_NEXT(tlvh)) { @@ -2762,6 +2787,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) switch (ntohs(tlvh->type)) { case EXT_SUBTLV_ADJ_SID: + if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_ADJ_SID_SIZE) + break; adj = (struct ext_subtlv_adj_sid *)tlvh; label = CHECK_FLAG(adj->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) @@ -2788,6 +2815,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) break; case EXT_SUBTLV_LAN_ADJ_SID: + if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_LAN_ADJ_SID_SIZE) + break; ladj = (struct ext_subtlv_lan_adj_sid *)tlvh; label = CHECK_FLAG(ladj->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) @@ -2817,6 +2846,8 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) break; case EXT_SUBTLV_RMT_ITF_ADDR: + if (TLV_BODY_SIZE(tlvh) != EXT_SUBTLV_RMT_ITF_ADDR_SIZE) + break; rmt = (struct ext_subtlv_rmt_itf_addr *)tlvh; if (CHECK_FLAG(atr->flags, LS_ATTR_NEIGH_ADDR) && IPV4_ADDR_SAME(&atr->standard.remote, From 8c177d69e32b91b45bda5fc5da6511fa03dc11ca Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Tue, 16 Apr 2024 16:42:06 +0200 Subject: [PATCH 133/472] ospfd: protect call to get_edge() in ospf_te.c During fuzzing, Iggy Frankovic discovered that get_edge() function in ospf_te.c could return null pointer, in particular when the link_id or advertised router IP addresses are fuzzed. As the null pointer returned by get_edge() function is not handlei by calling functions, this could cause ospfd crash. This patch introduces new verification of returned pointer by get_edge() function and stop the processing in case of null pointer. In addition, link ID and advertiser router ID are validated before calling ls_find_edge_by_key() to avoid the creation of a new edge with an invalid key. CVE-2024-34088 Co-authored-by: Iggy Frankovic Signed-off-by: Olivier Dugeon --- ospfd/ospf_te.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index e68f9444f512..d57990e1a174 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -1670,6 +1670,11 @@ static struct ls_edge *get_edge(struct ls_ted *ted, struct ls_node_id adv, struct ls_edge *edge; struct ls_attributes *attr; + /* Check that Link ID and Node ID are valid */ + if (IPV4_NET0(link_id.s_addr) || IPV4_NET0(adv.id.ip.addr.s_addr) || + adv.origin != OSPFv2) + return NULL; + /* Search Edge that corresponds to the Link ID */ key.family = AF_INET; IPV4_ADDR_COPY(&key.k.addr, &link_id); @@ -1743,6 +1748,10 @@ static void ospf_te_update_link(struct ls_ted *ted, struct ls_vertex *vertex, /* Get Corresponding Edge from Link State Data Base */ edge = get_edge(ted, vertex->node->adv, link_data); + if (!edge) { + ote_debug(" |- Found no edge from Link Data. Abort!"); + return; + } attr = edge->attributes; /* re-attached edge to vertex if needed */ @@ -2246,11 +2255,11 @@ static int ospf_te_parse_te(struct ls_ted *ted, struct ospf_lsa *lsa) } /* Get corresponding Edge from Link State Data Base */ - if (IPV4_NET0(attr.standard.local.s_addr) && !attr.standard.local_id) { - ote_debug(" |- Found no TE Link local address/ID. Abort!"); + edge = get_edge(ted, attr.adv, attr.standard.local); + if (!edge) { + ote_debug(" |- Found no edge from Link local add./ID. Abort!"); return -1; } - edge = get_edge(ted, attr.adv, attr.standard.local); old = edge->attributes; ote_debug(" |- Process Traffic Engineering LSA %pI4 for Edge %pI4", @@ -2759,6 +2768,10 @@ static int ospf_te_parse_ext_link(struct ls_ted *ted, struct ospf_lsa *lsa) lnid.id.ip.area_id = lsa->area->area_id; ext = (struct ext_tlv_link *)TLV_HDR_TOP(lsa->data); edge = get_edge(ted, lnid, ext->link_data); + if (!edge) { + ote_debug(" |- Found no edge from Extended Link Data. Abort!"); + return -1; + } atr = edge->attributes; ote_debug(" |- Process Extended Link LSA %pI4 for edge %pI4", From 980d76c403de248139339bfea68946b50f0bb338 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 5 Sep 2022 10:22:52 +0200 Subject: [PATCH 134/472] isisd: fix display of router in show isis database json Display information about a particular router in show isis database in an single value array for compatibility with the display of all routers. Fixes: a2cac12a63 ("isisd: Add json to show isis database command.") Signed-off-by: Louis Scalbert --- isisd/isisd.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/isisd/isisd.c b/isisd/isisd.c index 382a6aa3be4d..2c4cee0607c6 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -2649,6 +2649,7 @@ void show_isis_database_lspdb_json(struct json_object *json, struct lspdb_head *lspdb, const char *sysid_str, int ui_level) { + struct json_object *array_json, *lsp_json; struct isis_lsp *lsp; int lsp_count; struct json_object *lsp_arr_json; @@ -2661,11 +2662,19 @@ void show_isis_database_lspdb_json(struct json_object *json, } if (lsp) { + json_object_object_get_ex(json, "lsps", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "lsps", array_json); + } + lsp_json = json_object_new_object(); + json_object_array_add(array_json, lsp_json); + if (ui_level == ISIS_UI_LEVEL_DETAIL) - lsp_print_detail(lsp, NULL, json, + lsp_print_detail(lsp, NULL, lsp_json, area->dynhostname, area->isis); else - lsp_print_json(lsp, json, area->dynhostname, + lsp_print_json(lsp, lsp_json, area->dynhostname, area->isis); } else if (sysid_str == NULL) { lsp_arr_json = json_object_new_array(); From 9a83c6cf7217070d0a4885bfe82cb331b94f0b41 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 2 Sep 2022 18:03:21 +0200 Subject: [PATCH 135/472] isisd: fix multiple values display in show isis database detail json Multiple occurrences of the same (sub-)TLVs are mixed into a single JSON object. Last values replaces the previous. Display all the occurrences in an array for the following (sub-)TLVs: - is-reach - ip-reach - ext-reach - ext-ip-reach - ipv6-reach - MT - prefix-SID Fixes: a2cac12a63 ("isisd: Add json to show isis database command.") Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 69 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 93ae8c6cb2d9..2fd7e7e2b758 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -2127,9 +2127,14 @@ static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i, struct isis_prefix_sid *sid = (struct isis_prefix_sid *)i; if (json) { - struct json_object *sr_json; + struct json_object *sr_json, *array_json; sr_json = json_object_new_object(); - json_object_object_add(json, "sr", sr_json); + json_object_object_get_ex(json, "sr", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "sr", array_json); + } + json_object_array_add(array_json, sr_json); if (sid->flags & ISIS_PREFIX_SID_VALUE) { json_object_int_add(sr_json, "label", sid->value); } else { @@ -2929,9 +2934,15 @@ static void format_item_oldstyle_reach(uint16_t mtid, struct isis_item *i, snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pPN", r->id); if (json) { - struct json_object *old_json; + struct json_object *old_json, *array_json; old_json = json_object_new_object(); - json_object_object_add(json, "old-reach-style", old_json); + json_object_object_get_ex(json, "old-reach-style", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "old-reach-style", + array_json); + } + json_object_array_add(array_json, old_json); json_object_string_add(old_json, "is-reach", sys_id); json_object_int_add(old_json, "metric", r->metric); } else @@ -3173,9 +3184,14 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i, snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pPN", r->id); if (json) { - struct json_object *reach_json; + struct json_object *reach_json, *array_json; reach_json = json_object_new_object(); - json_object_object_add(json, "ext-reach", reach_json); + json_object_object_get_ex(json, "ext-reach", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "ext-reach", array_json); + } + json_object_array_add(array_json, reach_json); json_object_string_add( reach_json, "mt-id", (mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT"); @@ -3314,13 +3330,21 @@ static void format_item_oldstyle_ip_reach(uint16_t mtid, struct isis_item *i, char prefixbuf[PREFIX2STR_BUFFER]; if (json) { - struct json_object *old_json; + struct json_object *old_json, *array_json; old_json = json_object_new_object(); - json_object_object_add(json, "old-ip-reach-style", old_json); + json_object_object_get_ex(json, "old-ip-reach-style", + &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "old-ip-reach-style", + old_json); + } + json_object_array_add(array_json, old_json); json_object_string_add(old_json, "prefix", prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf))); json_object_int_add(old_json, "metric", r->metric); - } else + return; + } sbuf_push(buf, indent, "IP Reachability: %s (Metric: %hhu)\n", prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf)), r->metric); @@ -3705,9 +3729,14 @@ static void format_item_mt_router_info(uint16_t mtid, struct isis_item *i, struct isis_mt_router_info *info = (struct isis_mt_router_info *)i; if (json) { - struct json_object *mt_json; + struct json_object *mt_json, *array_json; mt_json = json_object_new_object(); - json_object_object_add(json, "mt", mt_json); + json_object_object_get_ex(json, "mt", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "mt", array_json); + } + json_object_array_add(array_json, mt_json); json_object_int_add(mt_json, "mtid", info->mtid); json_object_string_add(mt_json, "overload", info->overload?"true":"false"); json_object_string_add(mt_json, "attached", info->attached?"true":"false"); @@ -3866,12 +3895,17 @@ static void format_item_extended_ip_reach(uint16_t mtid, struct isis_item *i, struct json_object *json, int indent) { struct isis_extended_ip_reach *r = (struct isis_extended_ip_reach *)i; + struct json_object *ext_json, *array_json; char prefixbuf[PREFIX2STR_BUFFER]; if (json) { - struct json_object *ext_json; ext_json = json_object_new_object(); - json_object_object_add(json, "ext-ip-reach", ext_json); + json_object_object_get_ex(json, "ext-ip-reach", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "ext-ip-reach", array_json); + } + json_object_array_add(array_json, ext_json); json_object_string_add( json, "mt-id", (mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT"); @@ -4500,9 +4534,14 @@ static void format_item_ipv6_reach(uint16_t mtid, struct isis_item *i, char prefixbuf[PREFIX2STR_BUFFER]; if (json) { - struct json_object *reach_json; + struct json_object *reach_json, *array_json; reach_json = json_object_new_object(); - json_object_object_add(json, "ipv6-reach", reach_json); + json_object_object_get_ex(json, "ipv6-reach", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "ipv6-reach", array_json); + } + json_object_array_add(array_json, reach_json); json_object_string_add(reach_json, "mt-id", (mtid == ISIS_MT_IPV4_UNICAST) ? "" : "mt"); From 9730e604e696f57e9eb61b5df8a5f40a020870f6 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 5 Sep 2022 10:34:15 +0200 Subject: [PATCH 136/472] isisd: fix keys display in show isis database detail json Some keys are wrongly displayed at the JSON parent level. Add the key at the current level. Fixes: a2cac12a63 ("isisd: Add json to show isis database command.") Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 2fd7e7e2b758..d55ee6497a6a 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -3202,7 +3202,7 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i, isis_mtid2str(mtid)); if (r->subtlvs) - format_item_ext_subtlvs(r->subtlvs, NULL, json, + format_item_ext_subtlvs(r->subtlvs, NULL, reach_json, indent + 2, mtid); } else { sbuf_push(buf, indent, "%s Reachability: %s (Metric: %u)", @@ -3906,21 +3906,22 @@ static void format_item_extended_ip_reach(uint16_t mtid, struct isis_item *i, json_object_object_add(json, "ext-ip-reach", array_json); } json_object_array_add(array_json, ext_json); - json_object_string_add( - json, "mt-id", - (mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT"); - json_object_string_add( - json, "ip-reach", - prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf))); - json_object_int_add(json, "ip-reach-metric", r->metric); - json_object_string_add(json, "down", r->down ? "yes" : ""); + json_object_string_add(ext_json, "mt-id", + (mtid == ISIS_MT_IPV4_UNICAST) + ? "Extended" + : "MT"); + json_object_string_add(ext_json, "ip-reach", + prefix2str(&r->prefix, prefixbuf, + sizeof(prefixbuf))); + json_object_int_add(ext_json, "ip-reach-metric", r->metric); + json_object_string_add(ext_json, "down", r->down ? "yes" : ""); if (mtid != ISIS_MT_IPV4_UNICAST) - json_object_string_add(json, "mt-name", + json_object_string_add(ext_json, "mt-name", isis_mtid2str(mtid)); if (r->subtlvs) { struct json_object *subtlv_json; subtlv_json = json_object_new_object(); - json_object_object_add(json, "subtlvs", subtlv_json); + json_object_object_add(ext_json, "subtlvs", subtlv_json); format_subtlvs(r->subtlvs, NULL, subtlv_json, 0); } } else { @@ -4559,7 +4560,8 @@ static void format_item_ipv6_reach(uint16_t mtid, struct isis_item *i, if (r->subtlvs) { struct json_object *subtlvs_json; subtlvs_json = json_object_new_object(); - json_object_object_add(json, "subtlvs", subtlvs_json); + json_object_object_add(reach_json, "subtlvs", + subtlvs_json); format_subtlvs(r->subtlvs, NULL, subtlvs_json, 0); } } else { From b9870e9131ebeaede3da2a91b639e0cdcc356aea Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 5 Sep 2022 13:21:29 +0200 Subject: [PATCH 137/472] isisd: display MT name in show isis database detail json Only the MT ID is displayed. Display the MT description as well. Fixes: a2cac12a63 ("isisd: Add json to show isis database command.") Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index d55ee6497a6a..e715cc30b6b4 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -3738,6 +3738,8 @@ static void format_item_mt_router_info(uint16_t mtid, struct isis_item *i, } json_object_array_add(array_json, mt_json); json_object_int_add(mt_json, "mtid", info->mtid); + json_object_string_add(mt_json, "mt-description", + isis_mtid2str_fake(info->mtid)); json_object_string_add(mt_json, "overload", info->overload?"true":"false"); json_object_string_add(mt_json, "attached", info->attached?"true":"false"); } else From 2e670cd77980ed20ff9910ae3b7c135bb2387938 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 21 May 2024 16:22:34 +0200 Subject: [PATCH 138/472] isisd: fix display of srv6 subsubtlvs Fix display of srv6 subsubtlvs Fixes: 648a158802 ("isisd: Add SRv6 End.X SID to Sub-TLV format func") Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index e715cc30b6b4..b2e19401e760 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -955,7 +955,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_array_add(arr_adj_json, flags_json); if (adj->subsubtlvs) isis_format_subsubtlvs(adj->subsubtlvs, - NULL, json, + NULL, + arr_adj_json, indent + 4); } } else @@ -1031,7 +1032,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_array_add(arr_adj_json, flags_json); if (lan->subsubtlvs) isis_format_subsubtlvs(lan->subsubtlvs, - NULL, json, + NULL, + arr_adj_json, indent + 4); } } else From c3ccc0a53ba731c7995c3c8407665878f5a3cf34 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 5 Sep 2022 14:12:14 +0200 Subject: [PATCH 139/472] isisd: fix non present level display is show isis database detail json When a level is not present in show isis database detail json, {} is displayed. Display nothing for non present level. Fixes: a2cac12a63 ("isisd: Add json to show isis database command.") Signed-off-by: Louis Scalbert --- isisd/isisd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/isisd/isisd.c b/isisd/isisd.c index 2c4cee0607c6..982df0839b9b 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -2748,6 +2748,8 @@ static void show_isis_database_json(struct json_object *json, const char *sysid_ json_object_object_add(area_json,"area",tag_area_json); json_object_object_add(area_json,"levels",arr_json); for (level = 0; level < ISIS_LEVELS; level++) { + if (lspdb_count(&area->lspdb[level]) == 0) + continue; lsp_json = json_object_new_object(); show_isis_database_lspdb_json(lsp_json, area, level, &area->lspdb[level], From d5879267aa064e127a26b42eba192b87f91896f5 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 21 May 2024 14:48:44 +0200 Subject: [PATCH 140/472] isisd: fix show database json format "show isis database [detail] json" returns invalid or incorrect JSON that is difficult to parse. Fix key with '-' characters, add booleans and null data when possible. Deprecate the old format. Signed-off-by: Louis Scalbert --- isisd/isis_lsp.c | 19 + isisd/isis_tlvs.c | 795 +++++++++++++++++- tests/topotests/isis_topo1/test_isis_topo1.py | 2 +- 3 files changed, 790 insertions(+), 26 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 9d671137e945..1ce57747ffc9 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -746,6 +746,10 @@ void lsp_print_common(struct isis_lsp *lsp, struct vty *vty, struct json_object } } +#if CONFDATE > 20240916 +CPP_NOTICE("Remove JSON in '-' format") +#endif + void lsp_print_json(struct isis_lsp *lsp, struct json_object *json, char dynhost, struct isis *isis) { @@ -759,10 +763,20 @@ void lsp_print_json(struct isis_lsp *lsp, struct json_object *json, own_json = json_object_new_object(); json_object_object_add(json, "lsp", own_json); json_object_string_add(own_json, "id", LSPid); +#if CONFDATE > 20240916 + CPP_NOTICE("remove own key") +#endif json_object_string_add(own_json, "own", lsp->own_lsp ? "*" : " "); + if (lsp->own_lsp) + json_object_boolean_add(own_json, "ownLSP", true); json_object_int_add(json, "pdu-len", lsp->hdr.pdu_len); + json_object_int_add(json, "pduLen", lsp->hdr.pdu_len); snprintfrr(buf, sizeof(buf), "0x%08x", lsp->hdr.seqno); +#if CONFDATE > 20240916 + CPP_NOTICE("remove seq-number key") +#endif json_object_string_add(json, "seq-number", buf); + json_object_string_add(json, "seqNumber", buf); snprintfrr(buf, sizeof(buf), "0x%04hx", lsp->hdr.checksum); json_object_string_add(json, "chksum", buf); if (lsp->hdr.rem_lifetime == 0) { @@ -772,8 +786,13 @@ void lsp_print_json(struct isis_lsp *lsp, struct json_object *json, } else { json_object_int_add(json, "holdtime", lsp->hdr.rem_lifetime); } +#if CONFDATE > 20240916 + CPP_NOTICE("remove att-p-ol key") +#endif json_object_string_add( json, "att-p-ol", lsp_bits2string(lsp->hdr.lsp_bits, b, sizeof(b))); + json_object_string_add(json, "attPOl", + lsp_bits2string(lsp->hdr.lsp_bits, b, sizeof(b))); } void lsp_print_vty(struct isis_lsp *lsp, struct vty *vty, diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index b2e19401e760..c20b1d812971 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -454,6 +454,10 @@ static void format_item_asla_subtlvs(struct isis_asla_subtlvs *asla, asla->use_bw); } +#if CONFDATE > 20240916 +CPP_NOTICE("Remove JSON in '-' format") +#endif + /* mtid parameter is used to manage multi-topology i.e. IPv4 / IPv6 */ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct sbuf *buf, struct json_object *json, @@ -470,7 +474,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "0x%x", exts->adm_group); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "adm-group", aux_buf); + json_object_string_add(json, "admGroup", aux_buf); } else { sbuf_push(buf, indent, "Admin Group: 0x%08x\n", exts->adm_group); @@ -505,10 +513,17 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, } if (IS_SUBTLV(exts, EXT_LLRI)) { if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_int_add(json, "link-local-id", exts->local_llri); json_object_int_add(json, "link-remote-id", exts->remote_llri); + json_object_int_add(json, "linkLocalId", + exts->local_llri); + json_object_int_add(json, "linkRemoteId", + exts->remote_llri); } else { sbuf_push(buf, indent, "Link Local ID: %u\n", exts->local_llri); @@ -520,7 +535,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET, &exts->local_addr, aux_buf, sizeof(aux_buf)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "local-iface-ip", aux_buf); + json_object_string_add(json, "localIfaceIp", aux_buf); } else sbuf_push(buf, indent, "Local Interface IP Address(es): %pI4\n", @@ -530,8 +549,12 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET, &exts->neigh_addr, aux_buf, sizeof(aux_buf)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "remote-iface-ip", aux_buf); + json_object_string_add(json, "remoteIfaceIp", aux_buf); } else sbuf_push(buf, indent, "Remote Interface IP Address(es): %pI4\n", @@ -541,8 +564,12 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET6, &exts->local_addr6, aux_buf, sizeof(aux_buf)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "local-iface-ipv6", aux_buf); + json_object_string_add(json, "localIfaceIpv6", aux_buf); } else sbuf_push(buf, indent, "Local Interface IPv6 Address(es): %pI6\n", @@ -552,8 +579,12 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET6, &exts->neigh_addr6, aux_buf, sizeof(aux_buf)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "remote-iface-ipv6", aux_buf); + json_object_string_add(json, "remoteIfaceIpv6", aux_buf); } else sbuf_push(buf, indent, "Remote Interface IPv6 Address(es): %pI6\n", @@ -563,8 +594,13 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", exts->max_bw); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "max-bandwith-bytes-sec", aux_buf); + json_object_string_add(json, "maxBandwithBytesSec", + aux_buf); } else sbuf_push(buf, indent, "Maximum Bandwidth: %g (Bytes/sec)\n", @@ -574,8 +610,13 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", exts->max_rsv_bw); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add( json, "max-res-bandwith-bytes-sec", aux_buf); + json_object_string_add(json, "maxResBandwithBytesSec", + aux_buf); } else sbuf_push( buf, indent, @@ -585,6 +626,22 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (IS_SUBTLV(exts, EXT_UNRSV_BW)) { if (json) { struct json_object *unrsv_json; + + unrsv_json = json_object_new_object(); + json_object_object_add(json, "unrsvBandwithBytesSec", + unrsv_json); + for (int j = 0; j < MAX_CLASS_TYPE; j += 1) { + snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", j); + snprintfrr(aux_buf, sizeof(aux_buf), "%g", + exts->unrsv_bw[j]); + json_object_string_add(unrsv_json, cnt_buf, + aux_buf); + } + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ unrsv_json = json_object_new_object(); json_object_object_add(json, "unrsv-bandwith-bytes-sec", unrsv_json); @@ -595,6 +652,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_string_add(unrsv_json, cnt_buf, aux_buf); } + /* end old deprecated key format */ } else { sbuf_push(buf, indent, "Unreserved Bandwidth:\n"); for (int j = 0; j < MAX_CLASS_TYPE; j += 2) { @@ -608,7 +666,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, } if (IS_SUBTLV(exts, EXT_TE_METRIC)) { if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_int_add(json, "te-metric", exts->te_metric); + json_object_int_add(json, "teMetric", exts->te_metric); } else sbuf_push(buf, indent, "Traffic Engineering Metric: %u\n", @@ -616,8 +678,13 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, } if (IS_SUBTLV(exts, EXT_RMT_AS)) { if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_int_add(json, "inter-as-te-remote-as", exts->remote_as); + json_object_int_add(json, "interAsTeRemoteAs", + exts->remote_as); } else sbuf_push(buf, indent, "Inter-AS TE Remote AS number: %u\n", @@ -627,8 +694,13 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { inet_ntop(AF_INET6, &exts->remote_ip, aux_buf, sizeof(aux_buf)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add( json, "inter-as-te-remote-asbr-ip", aux_buf); + json_object_string_add(json, "interAsTeRemoteAsbrIp", + aux_buf); } else sbuf_push(buf, indent, "Inter-AS TE Remote ASBR IP address: %pI4\n", @@ -639,12 +711,23 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { struct json_object *avg_json; avg_json = json_object_new_object(); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_object_add(json, "avg-delay", avg_json); json_object_string_add(avg_json, "delay", IS_ANORMAL(exts->delay) ? "Anomalous" : "Normal"); json_object_int_add(avg_json, "micro-sec", exts->delay); + + avg_json = json_object_new_object(); + json_object_object_add(json, "avgDelay", avg_json); + json_object_string_add(avg_json, "delay", + IS_ANORMAL(exts->delay) + ? "Anomalous" + : "Normal"); + json_object_int_add(avg_json, "microSec", exts->delay); } else sbuf_push(buf, indent, "%s Average Link Delay: %u (micro-sec)\n", @@ -656,6 +739,9 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { struct json_object *avg_json; avg_json = json_object_new_object(); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_object_add(json, "max-min-delay", avg_json); json_object_string_add(avg_json, "delay", IS_ANORMAL(exts->min_delay) @@ -666,6 +752,17 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, exts->max_delay & TE_EXT_MASK); json_object_string_add(avg_json, "micro-sec", aux_buf); + avg_json = json_object_new_object(); + json_object_object_add(json, "maxMinDelay", avg_json); + json_object_string_add(avg_json, "delay", + IS_ANORMAL(exts->min_delay) + ? "Anomalous" + : "Normal"); + snprintfrr(aux_buf, sizeof(aux_buf), "%u / %u", + exts->min_delay & TE_EXT_MASK, + exts->max_delay & TE_EXT_MASK); + json_object_string_add(avg_json, "microSec", aux_buf); + } else sbuf_push( buf, indent, @@ -677,8 +774,13 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, } if (IS_SUBTLV(exts, EXT_DELAY_VAR)) { if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_int_add(json, "delay-variation-micro-sec", exts->delay_var & TE_EXT_MASK); + json_object_int_add(json, "delayVariationMicroSec", + exts->delay_var & TE_EXT_MASK); } else sbuf_push(buf, indent, "Delay Variation: %u (micro-sec)\n", @@ -690,6 +792,10 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, (float)((exts->pkt_loss & TE_EXT_MASK) * LOSS_PRECISION)); struct json_object *link_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif link_json = json_object_new_object(); json_object_object_add(json, "link-packet-loss", link_json); @@ -697,8 +803,18 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, IS_ANORMAL(exts->pkt_loss) ? "Anomalous" : "Normal"); + /* typo */ json_object_string_add(link_json, "percentaje", aux_buf); + + link_json = json_object_new_object(); + json_object_object_add(json, "linkPacketLoss", + link_json); + json_object_string_add(link_json, "loss", + IS_ANORMAL(exts->pkt_loss) + ? "Anomalous" + : "Normal"); + json_object_string_add(link_json, "percentage", aux_buf); } else sbuf_push(buf, indent, "%s Link Packet Loss: %g (%%)\n", IS_ANORMAL(exts->pkt_loss) ? "Anomalous" @@ -710,9 +826,15 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", (exts->res_bw)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "unidir-residual-band-bytes-sec", aux_buf); + json_object_string_add(json, + "unidirResidualBandBytesSec", + aux_buf); } else sbuf_push( buf, indent, @@ -723,9 +845,15 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { snprintfrr(aux_buf, sizeof(aux_buf), "%g", (exts->ava_bw)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add( json, "unidir-available-band-bytes-sec", aux_buf); + json_object_string_add(json, + "unidirAvailableBandBytesSec", + aux_buf); } else sbuf_push( buf, indent, @@ -739,6 +867,12 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_string_add(json, "unidir-utilized-band-bytes-sec", aux_buf); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + json_object_string_add(json, + "unidirUtilizedBandBytesSec", + aux_buf); } else sbuf_push( buf, indent, @@ -751,6 +885,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { struct json_object *arr_adj_json, *flags_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ arr_adj_json = json_object_new_array(); json_object_object_add(json, "adj-sid", arr_adj_json); for (adj = (struct isis_adj_sid *)exts->adj_sid.head; @@ -794,6 +933,44 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, : "0"); json_object_array_add(arr_adj_json, flags_json); } + /* end old deprecated key format */ + + arr_adj_json = json_object_new_array(); + json_object_object_add(json, "adjSid", arr_adj_json); + for (adj = (struct isis_adj_sid *)exts->adj_sid.head; + adj; adj = adj->next) { + snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", + adj->sid); + flags_json = json_object_new_object(); + json_object_int_add(flags_json, "sid", adj->sid); + json_object_int_add(flags_json, "weight", + adj->weight); + json_object_boolean_add(flags_json, "flagF", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagB", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagV", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagL", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagS", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagP", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG + ? true + : false); + json_object_array_add(arr_adj_json, flags_json); + } } else for (adj = (struct isis_adj_sid *)exts->adj_sid.head; adj; adj = adj->next) { @@ -826,6 +1003,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct isis_lan_adj_sid *lan; if (json) { struct json_object *arr_adj_json, *flags_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ arr_adj_json = json_object_new_array(); json_object_object_add(json, "lan-adj-sid", arr_adj_json); @@ -876,6 +1058,49 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, : "0"); json_object_array_add(arr_adj_json, flags_json); } + /* end old deprecated key format */ + + arr_adj_json = json_object_new_array(); + json_object_object_add(json, "lanAdjSid", arr_adj_json); + for (lan = (struct isis_lan_adj_sid *)exts->adj_sid.head; + lan; lan = lan->next) { + if (((mtid == ISIS_MT_IPV4_UNICAST) && + (lan->family != AF_INET)) || + ((mtid == ISIS_MT_IPV6_UNICAST) && + (lan->family != AF_INET6))) + continue; + snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", + lan->sid); + flags_json = json_object_new_object(); + json_object_int_add(flags_json, "sid", lan->sid); + json_object_int_add(flags_json, "weight", + lan->weight); + json_object_boolean_add(flags_json, "flagF", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagB", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagV", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagL", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagS", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG + ? true + : false); + json_object_boolean_add(flags_json, "flagP", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG + ? true + : false); + json_object_array_add(arr_adj_json, flags_json); + } } else for (lan = (struct isis_lan_adj_sid *) @@ -918,6 +1143,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (json) { struct json_object *arr_adj_json, *flags_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ arr_adj_json = json_object_new_array(); json_object_object_add(json, "srv6-endx-sid", arr_adj_json); @@ -959,6 +1189,45 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, arr_adj_json, indent + 4); } + /* end old deprecated key format */ + + arr_adj_json = json_object_new_array(); + json_object_object_add(json, "srv6EndSID", arr_adj_json); + for (adj = (struct isis_srv6_endx_sid_subtlv *) + exts->srv6_endx_sid.head; + adj; adj = adj->next) { + snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", + &adj->sid); + flags_json = json_object_new_object(); + json_object_string_addf(flags_json, "sid", + "%pI6", &adj->sid); + json_object_string_add(flags_json, "algorithm", + sr_algorithm_string( + adj->algorithm)); + json_object_int_add(flags_json, "weight", + adj->weight); + json_object_string_add(flags_json, "behavior", + seg6local_action2str( + adj->behavior)); + json_object_boolean_add( + flags_json, "flagB", + !!(adj->flags & + EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG)); + json_object_boolean_add( + flags_json, "flagS", + !!(adj->flags & + EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG)); + json_object_boolean_add( + flags_json, "flagP", + !!(adj->flags & + EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG)); + json_object_array_add(arr_adj_json, flags_json); + if (adj->subsubtlvs) + isis_format_subsubtlvs(adj->subsubtlvs, + NULL, + arr_adj_json, + indent + 4); + } } else for (adj = (struct isis_srv6_endx_sid_subtlv *) exts->srv6_endx_sid.head; @@ -990,6 +1259,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct isis_srv6_lan_endx_sid_subtlv *lan; if (json) { struct json_object *arr_adj_json, *flags_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ arr_adj_json = json_object_new_array(); json_object_object_add(json, "srv6-lan-endx-sid", arr_adj_json); @@ -1036,6 +1310,51 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, arr_adj_json, indent + 4); } + /* end old deprecated key format */ + + arr_adj_json = json_object_new_array(); + json_object_object_add(json, "srv6LanEndxSID", + arr_adj_json); + for (lan = (struct isis_srv6_lan_endx_sid_subtlv *) + exts->srv6_lan_endx_sid.head; + lan; lan = lan->next) { + snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", + &lan->sid); + flags_json = json_object_new_object(); + json_object_string_addf(flags_json, "sid", + "%pI6", &lan->sid); + json_object_int_add(flags_json, "weight", + lan->weight); + json_object_string_add(flags_json, "algorithm", + sr_algorithm_string( + lan->algorithm)); + json_object_int_add(flags_json, "weight", + lan->weight); + json_object_string_add(flags_json, "behavior", + seg6local_action2str( + lan->behavior)); + json_object_boolean_add( + flags_json, "flagB", + !!(lan->flags & + EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG)); + json_object_boolean_add( + flags_json, "flagS", + !!(lan->flags & + EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG)); + json_object_boolean_add( + flags_json, "flagP", + !!(lan->flags & + EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG)); + json_object_string_addf(flags_json, + "neighbor-id", "%pSY", + lan->neighbor_id); + json_object_array_add(arr_adj_json, flags_json); + if (lan->subsubtlvs) + isis_format_subsubtlvs(lan->subsubtlvs, + NULL, + arr_adj_json, + indent + 4); + } } else for (lan = (struct isis_srv6_lan_endx_sid_subtlv *) exts->srv6_lan_endx_sid.head; @@ -2130,6 +2449,7 @@ static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *sr_json, *array_json; + sr_json = json_object_new_object(); json_object_object_get_ex(json, "sr", &array_json); if (!array_json) { @@ -2143,6 +2463,11 @@ static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i, json_object_int_add(sr_json, "index", sid->value); } json_object_int_add(sr_json, "alg", sid->algorithm); + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated non boolean json") +#endif + /* old deprecated keys (no booleans) */ json_object_string_add( sr_json, "readvertised", ((sid->flags & ISIS_PREFIX_SID_READVERTISED) ? "yes" @@ -2164,6 +2489,27 @@ static void format_item_prefix_sid(uint16_t mtid, struct isis_item *i, json_object_string_add( sr_json, "local", ((sid->flags & ISIS_PREFIX_SID_LOCAL) ? "yes" : "")); + /* end deprecated keys (no booleans) */ + + struct json_object *flags_json; + + flags_json = json_object_new_object(); + json_object_object_add(sr_json, "flags", flags_json); + + json_object_boolean_add(flags_json, "readvertised", + !!(sid->flags & + ISIS_PREFIX_SID_READVERTISED)); + json_object_boolean_add(flags_json, "node", + !!(sid->flags & ISIS_PREFIX_SID_NODE)); + json_object_boolean_add(flags_json, "noPHP", + !!(sid->flags & ISIS_PREFIX_SID_NO_PHP)); + json_object_boolean_add(flags_json, "explicitNull", + !!(sid->flags & + ISIS_PREFIX_SID_EXPLICIT_NULL)); + json_object_boolean_add(flags_json, "value", + !!(sid->flags & ISIS_PREFIX_SID_VALUE)); + json_object_boolean_add(flags_json, "local", + !!(sid->flags & ISIS_PREFIX_SID_LOCAL)); } else { sbuf_push(buf, indent, "SR Prefix-SID "); @@ -2293,7 +2639,11 @@ static void format_subtlv_ipv6_source_prefix(struct prefix_ipv6 *p, char prefixbuf[PREFIX2STR_BUFFER]; if (json) { prefix2str(p, prefixbuf, sizeof(prefixbuf)); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "ipv6-src-prefix", prefixbuf); + json_object_string_add(json, "ipv6SrcPrefix", prefixbuf); } else { sbuf_push(buf, indent, "IPv6 Source Prefix: %s\n", prefix2str(p, prefixbuf, sizeof(prefixbuf))); @@ -2395,6 +2745,11 @@ static void format_subsubtlv_srv6_sid_structure( if (json) { struct json_object *sid_struct_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ sid_struct_json = json_object_new_object(); json_object_object_add(json, "srv6-sid-structure", sid_struct_json); @@ -2406,6 +2761,19 @@ static void format_subsubtlv_srv6_sid_structure( sid_struct->func_len); json_object_int_add(sid_struct_json, "arg-len", sid_struct->arg_len); + /* end old deprecated key format */ + + sid_struct_json = json_object_new_object(); + json_object_object_add(json, "srv6SidStructure", + sid_struct_json); + json_object_int_add(sid_struct_json, "locBlockLen", + sid_struct->loc_block_len); + json_object_int_add(sid_struct_json, "locNodeLen", + sid_struct->loc_node_len); + json_object_int_add(sid_struct_json, "funcLen", + sid_struct->func_len); + json_object_int_add(sid_struct_json, "argLen", + sid_struct->arg_len); } else { sbuf_push(buf, indent, "SRv6 SID Structure "); sbuf_push(buf, 0, "Locator Block length: %hhu, ", @@ -2687,6 +3055,11 @@ static void format_item_srv6_end_sid(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *sid_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ sid_json = json_object_new_object(); json_object_object_add(json, "srv6-end-sid", sid_json); json_object_string_add(sid_json, "endpoint-behavior", @@ -2701,6 +3074,21 @@ static void format_item_srv6_end_sid(uint16_t mtid, struct isis_item *i, isis_format_subsubtlvs(sid->subsubtlvs, NULL, subtlvs_json, 0); } + /* end old deprecated key format */ + + sid_json = json_object_new_object(); + json_object_object_add(json, "srv6EndSid", sid_json); + json_object_string_add(sid_json, "endpointBehavior", + seg6local_action2str(sid->behavior)); + json_object_string_addf(sid_json, "sidValue", "%pI6", &sid->sid); + if (sid->subsubtlvs) { + struct json_object *subtlvs_json; + subtlvs_json = json_object_new_object(); + json_object_object_add(sid_json, "subsubtlvs", + subtlvs_json); + isis_format_subsubtlvs(sid->subsubtlvs, NULL, + subtlvs_json, 0); + } } else { sbuf_push(buf, indent, "SRv6 End SID "); sbuf_push(buf, 0, "Endpoint Behavior: %s, ", @@ -2848,9 +3236,13 @@ static void format_item_area_address(uint16_t mtid, struct isis_item *i, memcpy(iso_addr.area_addr, addr->addr, ISO_ADDR_SIZE); iso_addr.addr_len = addr->len; - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_addf(json, "area-addr", "%pIS", &iso_addr); - else + json_object_string_addf(json, "areaAddr", "%pIS", &iso_addr); + } else sbuf_push(buf, indent, "Area Address: %pIS\n", &iso_addr); } @@ -2937,6 +3329,11 @@ static void format_item_oldstyle_reach(uint16_t mtid, struct isis_item *i, snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pPN", r->id); if (json) { struct json_object *old_json, *array_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ old_json = json_object_new_object(); json_object_object_get_ex(json, "old-reach-style", &array_json); if (!array_json) { @@ -2947,6 +3344,18 @@ static void format_item_oldstyle_reach(uint16_t mtid, struct isis_item *i, json_object_array_add(array_json, old_json); json_object_string_add(old_json, "is-reach", sys_id); json_object_int_add(old_json, "metric", r->metric); + /* end old deprecated key format */ + + old_json = json_object_new_object(); + json_object_object_get_ex(json, "oldReachStyle", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "oldReachStyle", + array_json); + } + json_object_array_add(array_json, old_json); + json_object_string_add(old_json, "isReach", sys_id); + json_object_int_add(old_json, "metric", r->metric); } else sbuf_push(buf, indent, "IS Reachability: %s (Metric: %hhu)\n", sys_id, r->metric); @@ -3024,9 +3433,13 @@ static void format_item_lan_neighbor(uint16_t mtid, struct isis_item *i, char sys_id[ISO_SYSID_STRLEN]; snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pSY", n->mac); - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "lan-neighbor", sys_id); - else + json_object_string_add(json, "lanNeighbor", sys_id); + } else sbuf_push(buf, indent, "LAN Neighbor: %s\n", sys_id); } @@ -3099,6 +3512,9 @@ static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i, char buf[255]; struct json_object *lsp_json; lsp_json = json_object_new_object(); +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_object_add(json, "lsp-entry", lsp_json); json_object_string_add(lsp_json, "id", sys_id); snprintfrr(buf,sizeof(buf),"0x%08x",e->seqno); @@ -3106,6 +3522,15 @@ static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i, snprintfrr(buf,sizeof(buf),"0x%04hx",e->checksum); json_object_string_add(lsp_json, "chksum", buf); json_object_int_add(lsp_json, "lifetime", e->checksum); + + lsp_json = json_object_new_object(); + json_object_object_add(json, "lspEntry", lsp_json); + json_object_string_add(lsp_json, "id", sys_id); + snprintfrr(buf, sizeof(buf), "0x%08x", e->seqno); + json_object_string_add(lsp_json, "seq", buf); + snprintfrr(buf, sizeof(buf), "0x%04hx", e->checksum); + json_object_string_add(lsp_json, "chksum", buf); + json_object_int_add(lsp_json, "lifetime", e->checksum); } else sbuf_push( buf, indent, @@ -3187,6 +3612,11 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i, snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pPN", r->id); if (json) { struct json_object *reach_json, *array_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ reach_json = json_object_new_object(); json_object_object_get_ex(json, "ext-reach", &array_json); if (!array_json) { @@ -3203,6 +3633,28 @@ static void format_item_extended_reach(uint16_t mtid, struct isis_item *i, json_object_string_add(reach_json, "mt-name", isis_mtid2str(mtid)); + if (r->subtlvs) + format_item_ext_subtlvs(r->subtlvs, NULL, reach_json, + indent + 2, mtid); + /* end old deprecated key format */ + + reach_json = json_object_new_object(); + json_object_object_get_ex(json, "extReach", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "extReach", array_json); + } + json_object_array_add(array_json, reach_json); + json_object_string_add(reach_json, "mtId", + (mtid == ISIS_MT_IPV4_UNICAST) + ? "Extended" + : "MT"); + json_object_string_add(reach_json, "id", sys_id); + json_object_int_add(reach_json, "metric", r->metric); + if (mtid != ISIS_MT_IPV4_UNICAST) + json_object_string_add(reach_json, "mtName", + isis_mtid2str(mtid)); + if (r->subtlvs) format_item_ext_subtlvs(r->subtlvs, NULL, reach_json, indent + 2, mtid); @@ -3333,6 +3785,11 @@ static void format_item_oldstyle_ip_reach(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *old_json, *array_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ old_json = json_object_new_object(); json_object_object_get_ex(json, "old-ip-reach-style", &array_json); @@ -3345,6 +3802,20 @@ static void format_item_oldstyle_ip_reach(uint16_t mtid, struct isis_item *i, json_object_string_add(old_json, "prefix", prefix2str(&r->prefix, prefixbuf, sizeof(prefixbuf))); json_object_int_add(old_json, "metric", r->metric); + /* end old deprecated key format */ + + old_json = json_object_new_object(); + json_object_object_get_ex(json, "oldIpReachStyle", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "oldIpReachStyle", + old_json); + } + json_object_array_add(array_json, old_json); + json_object_string_add(old_json, "prefix", + prefix2str(&r->prefix, prefixbuf, + sizeof(prefixbuf))); + json_object_int_add(old_json, "metric", r->metric); return; } sbuf_push(buf, indent, "IP Reachability: %s (Metric: %hhu)\n", @@ -3438,6 +3909,10 @@ static void format_tlv_protocols_supported(struct isis_protocols_supported *p, struct json_object *protocol_json; char buf[255]; +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ protocol_json = json_object_new_object(); json_object_object_add(json, "protocols-supported", protocol_json); @@ -3446,6 +3921,16 @@ static void format_tlv_protocols_supported(struct isis_protocols_supported *p, json_object_string_add(protocol_json, buf, nlpid2str(p->protocols[i])); } + + protocol_json = json_object_new_object(); + json_object_object_add(json, "supportedProtocols", + protocol_json); + for (uint8_t i = 0; i < p->count; i++) { + snprintfrr(buf, sizeof(buf), "%d", i); + json_object_string_add(protocol_json, buf, + nlpid2str(p->protocols[i])); + } + /* end old deprecated key format */ } else { sbuf_push(buf, indent, "Protocols Supported: "); for (uint8_t i = 0; i < p->count; i++) { @@ -3661,9 +4146,13 @@ static void format_item_global_ipv6_address(uint16_t mtid, struct isis_item *i, char addrbuf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &a->addr, addrbuf, sizeof(addrbuf)); - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "global-ipv6", addrbuf); - else + json_object_string_add(json, "globalIpv6", addrbuf); + } else sbuf_push(buf, indent, "Global IPv6 Interface Address: %s\n", addrbuf); } @@ -3742,8 +4231,19 @@ static void format_item_mt_router_info(uint16_t mtid, struct isis_item *i, json_object_int_add(mt_json, "mtid", info->mtid); json_object_string_add(mt_json, "mt-description", isis_mtid2str_fake(info->mtid)); + json_object_string_add(mt_json, "mtDescription", + isis_mtid2str(mtid)); + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated non boolean format") +#endif json_object_string_add(mt_json, "overload", info->overload?"true":"false"); json_object_string_add(mt_json, "attached", info->attached?"true":"false"); + + json_object_boolean_add(mt_json, "overloadBit", + !!info->overload); + json_object_boolean_add(mt_json, "attachedbit", + !!info->attached); } else sbuf_push(buf, indent, "MT Router Info: %s%s%s\n", isis_mtid2str_fake(info->mtid), @@ -3826,9 +4326,13 @@ static void format_tlv_te_router_id(const struct in_addr *id, struct sbuf *buf, char addrbuf[INET_ADDRSTRLEN]; inet_ntop(AF_INET, id, addrbuf, sizeof(addrbuf)); - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "te-router-id", addrbuf); - else + json_object_string_add(json, "teRouterId", addrbuf); + } else sbuf_push(buf, indent, "TE Router ID: %s\n", addrbuf); } @@ -3903,6 +4407,10 @@ static void format_item_extended_ip_reach(uint16_t mtid, struct isis_item *i, char prefixbuf[PREFIX2STR_BUFFER]; if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ ext_json = json_object_new_object(); json_object_object_get_ex(json, "ext-ip-reach", &array_json); if (!array_json) { @@ -3928,6 +4436,33 @@ static void format_item_extended_ip_reach(uint16_t mtid, struct isis_item *i, json_object_object_add(ext_json, "subtlvs", subtlv_json); format_subtlvs(r->subtlvs, NULL, subtlv_json, 0); } + /* end old deprecated key format */ + + ext_json = json_object_new_object(); + json_object_object_get_ex(json, "extIpReach", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "extIpReach", array_json); + } + json_object_array_add(array_json, ext_json); + json_object_string_add(ext_json, "mtId", + (mtid == ISIS_MT_IPV4_UNICAST) + ? "Extended" + : "MT"); + json_object_string_add(ext_json, "ipReach", + prefix2str(&r->prefix, prefixbuf, + sizeof(prefixbuf))); + json_object_int_add(ext_json, "ipReachMetric", r->metric); + json_object_boolean_add(ext_json, "down", !!r->down); + if (mtid != ISIS_MT_IPV4_UNICAST) + json_object_string_add(ext_json, "mtName", + isis_mtid2str(mtid)); + if (r->subtlvs) { + struct json_object *subtlv_json; + subtlv_json = json_object_new_object(); + json_object_object_add(ext_json, "subtlvs", subtlv_json); + format_subtlvs(r->subtlvs, NULL, subtlv_json, 0); + } } else { sbuf_push(buf, indent, "%s IP Reachability: %s (Metric: %u)%s", (mtid == ISIS_MT_IPV4_UNICAST) ? "Extended" : "MT", @@ -4185,9 +4720,13 @@ static void format_tlv_te_router_id_ipv6(const struct in6_addr *id, char addrbuf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, id, addrbuf, sizeof(addrbuf)); - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "ipv6-te-router-id", addrbuf); - else + json_object_string_add(json, "ipv6TeRouterId", addrbuf); + } else sbuf_push(buf, indent, "IPv6 TE Router ID: %s\n", addrbuf); } @@ -4264,6 +4803,11 @@ static void format_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf, if (json) { struct json_object *spine_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated format */ spine_json = json_object_new_object(); json_object_object_add(json, "spine-leaf-extension", spine_json); @@ -4282,6 +4826,25 @@ static void format_tlv_spine_leaf(const struct isis_spine_leaf *spine_leaf, spine_leaf->is_spine ? "yes" : ""); json_object_string_add(spine_json, "flag-backup", spine_leaf->is_backup ? "yes" : ""); + /* end old deprecated format */ + + spine_json = json_object_new_object(); + json_object_object_add(json, "spineLeafExtension", spine_json); + if (spine_leaf->has_tier) { + snprintfrr(aux_buf, sizeof(aux_buf), "%hhu", + spine_leaf->tier); + json_object_string_add(spine_json, "tier", + (spine_leaf->tier == + ISIS_TIER_UNDEFINED) + ? "undefined" + : aux_buf); + } + json_object_boolean_add(spine_json, "flagLeaf", + spine_leaf->is_leaf ? true : false); + json_object_boolean_add(spine_json, "flagSpine", + spine_leaf->is_spine ? true : false); + json_object_boolean_add(spine_json, "flagBackup", + spine_leaf->is_backup ? true : false); } else { sbuf_push(buf, indent, "Spine-Leaf-Extension:\n"); if (spine_leaf->has_tier) { @@ -4423,6 +4986,11 @@ format_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj, snprintfrr(sys_id, ISO_SYSID_STRLEN, "%pSY", threeway_adj->neighbor_id); if (json) { struct json_object *three_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ three_json = json_object_new_object(); json_object_object_add(json, "p2p-three-way-adj", three_json); json_object_string_add( @@ -4431,11 +4999,28 @@ format_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj, json_object_int_add(three_json, "state", threeway_adj->state); json_object_int_add(three_json, "ext-local-circuit-id", threeway_adj->local_circuit_id); - if (!threeway_adj->neighbor_set) - return; - json_object_string_add(three_json, "neigh-system-id", sys_id); - json_object_int_add(three_json, "neigh-ext-circuit-id", - threeway_adj->neighbor_circuit_id); + if (threeway_adj->neighbor_set) { + json_object_string_add(three_json, "neigh-system-id", + sys_id); + json_object_int_add(three_json, "neigh-ext-circuit-id", + threeway_adj->neighbor_circuit_id); + } + /* end old deprecated key format */ + + three_json = json_object_new_object(); + json_object_object_add(json, "p2pThreeWayAdj", three_json); + json_object_string_add(three_json, "stateName", + isis_threeway_state_name( + threeway_adj->state)); + json_object_int_add(three_json, "state", threeway_adj->state); + json_object_int_add(three_json, "extLocalCircuitId", + threeway_adj->local_circuit_id); + if (threeway_adj->neighbor_set) { + json_object_string_add(three_json, "neighSystemId", + sys_id); + json_object_int_add(three_json, "neighExtCircuitId", + threeway_adj->neighbor_circuit_id); + } } else { sbuf_push(buf, indent, "P2P Three-Way Adjacency:\n"); sbuf_push(buf, indent, " State: %s (%d)\n", @@ -4540,6 +5125,43 @@ static void format_item_ipv6_reach(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *reach_json, *array_json; + + reach_json = json_object_new_object(); + json_object_object_get_ex(json, "ipv6Reach", &array_json); + if (!array_json) { + array_json = json_object_new_array(); + json_object_object_add(json, "ipv6Reach", array_json); + } + json_object_array_add(array_json, reach_json); + json_object_string_add(reach_json, "mtId", + (mtid == ISIS_MT_IPV4_UNICAST) ? "" + : "mt"); + json_object_string_add(reach_json, "prefix", + prefix2str(&r->prefix, prefixbuf, + sizeof(prefixbuf))); + json_object_int_add(reach_json, "metric", r->metric); + json_object_boolean_add(reach_json, "down", + r->down ? true : false); + json_object_boolean_add(reach_json, "external", + r->external ? true : false); + if (mtid != ISIS_MT_IPV4_UNICAST) { + json_object_string_add(reach_json, "mt-name", + isis_mtid2str(mtid)); + json_object_string_add(reach_json, "mtName", + isis_mtid2str(mtid)); + } + if (r->subtlvs) { + struct json_object *subtlvs_json; + subtlvs_json = json_object_new_object(); + json_object_object_add(reach_json, "subtlvs", + subtlvs_json); + format_subtlvs(r->subtlvs, NULL, subtlvs_json, 0); + } + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated JSON key format */ reach_json = json_object_new_object(); json_object_object_get_ex(json, "ipv6-reach", &array_json); if (!array_json) { @@ -4568,6 +5190,7 @@ static void format_item_ipv6_reach(uint16_t mtid, struct isis_item *i, subtlvs_json); format_subtlvs(r->subtlvs, NULL, subtlvs_json, 0); } + /* end deprecated key format */ } else { sbuf_push(buf, indent, "%sIPv6 Reachability: %s (Metric: %u)%s%s", @@ -4779,6 +5402,11 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, /* Router ID and Flags */ struct json_object *cap_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* deprecated JSON key format */ cap_json = json_object_new_object(); json_object_object_add(json, "router-capability", cap_json); inet_ntop(AF_INET, &router_cap->router_id, addrbuf, sizeof(addrbuf)); @@ -4789,10 +5417,26 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, json_object_string_add( cap_json, "flag-s", router_cap->flags & ISIS_ROUTER_CAP_FLAG_S ? "1" : "0"); + /* end deprecated JSON key format */ + + cap_json = json_object_new_object(); + json_object_object_add(json, "routerCapability", cap_json); + inet_ntop(AF_INET, &router_cap->router_id, addrbuf, sizeof(addrbuf)); + json_object_string_add(cap_json, "id", addrbuf); + json_object_boolean_add(cap_json, "flagD", + !!(router_cap->flags & ISIS_ROUTER_CAP_FLAG_D)); + json_object_boolean_add(cap_json, "flagS", + !!(router_cap->flags & ISIS_ROUTER_CAP_FLAG_S)); + /* Segment Routing Global Block as per RFC8667 section #3.1 */ if (router_cap->srgb.range_size != 0) { struct json_object *gb_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* deprecated old key format */ gb_json = json_object_new_object(); json_object_object_add(json, "segment-routing-gb", gb_json); json_object_string_add(gb_json, "ipv4", @@ -4805,23 +5449,52 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, router_cap->srgb.lower_bound); json_object_int_add(gb_json, "global-block-range", router_cap->srgb.range_size); + + gb_json = json_object_new_object(); + json_object_object_add(json, "segmentRoutingGb", gb_json); + json_object_boolean_add(gb_json, "ipv4", + !!IS_SR_IPV4(&router_cap->srgb)); + json_object_boolean_add(gb_json, "ipv6", + !!IS_SR_IPV6(&router_cap->srgb)); + json_object_int_add(gb_json, "globalBlockBase", + router_cap->srgb.lower_bound); + json_object_int_add(gb_json, "globalBlockRange", + router_cap->srgb.range_size); } /* Segment Routing Local Block as per RFC8667 section #3.3 */ if (router_cap->srlb.range_size != 0) { struct json_object *lb_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ lb_json = json_object_new_object(); json_object_object_add(json, "segment-routing-lb", lb_json); json_object_int_add(lb_json, "global-block-base", router_cap->srlb.lower_bound); json_object_int_add(lb_json, "global-block-range", router_cap->srlb.range_size); + /* end old deprecated key format */ + + lb_json = json_object_new_object(); + json_object_object_add(json, "segmentRoutingLb", lb_json); + json_object_int_add(lb_json, "globalBlockBase", + router_cap->srlb.lower_bound); + json_object_int_add(lb_json, "globalBlockRange", + router_cap->srlb.range_size); } /* Segment Routing Algorithms as per RFC8667 section #3.2 */ if (router_cap->algo[0] != SR_ALGORITHM_UNSET) { char buf[255]; struct json_object *alg_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ alg_json = json_object_new_object(); json_object_object_add(json, "segment-routing-algorithm", alg_json); @@ -4833,6 +5506,20 @@ static void format_tlv_router_cap_json(const struct isis_router_cap *router_cap, ? "SPF" : "Strict SPF"); } + /* end old deprecated key format */ + + alg_json = json_object_new_object(); + json_object_object_add(json, "segmentRoutingAlgorithm", + alg_json); + for (int i = 0; i < SR_ALGORITHM_COUNT; i++) { + if (router_cap->algo[i] != SR_ALGORITHM_UNSET) { + snprintfrr(buf, sizeof(buf), "%d", i); + json_object_string_add(alg_json, buf, + router_cap->algo[i] == 0 + ? "SPF" + : "Strict SPF"); + } + } } /* Segment Routing Node MSD as per RFC8491 section #2 */ @@ -5676,16 +6363,24 @@ static void format_item_auth(uint16_t mtid, struct isis_item *i, struct isis_auth *auth = (struct isis_auth *)i; char obuf[768]; - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "test-auth", "ok"); - else + json_object_string_add(json, "testAuth", "ok"); + } else sbuf_push(buf, indent, "Authentication:\n"); switch (auth->type) { case ISIS_PASSWD_TYPE_CLEARTXT: zlog_sanitize(obuf, sizeof(obuf), auth->value, auth->length); - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "auth-pass", obuf); - else + json_object_string_add(json, "authPass", obuf); + } else sbuf_push(buf, indent, " Password: %s\n", obuf); break; case ISIS_PASSWD_TYPE_HMAC_MD5: @@ -5693,15 +6388,23 @@ static void format_item_auth(uint16_t mtid, struct isis_item *i, snprintf(obuf + 2 * j, sizeof(obuf) - 2 * j, "%02hhx", auth->value[j]); } - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "auth-hmac-md5", obuf); - else + json_object_string_add(json, "authHmacMd5", obuf); + } else sbuf_push(buf, indent, " HMAC-MD5: %s\n", obuf); break; default: - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_int_add(json, "auth-unknown", auth->type); - else + json_object_int_add(json, "authUnknown", auth->type); + } else sbuf_push(buf, indent, " Unknown (%hhu)\n", auth->type); break; @@ -5816,12 +6519,25 @@ static void format_tlv_purge_originator(struct isis_purge_originator *poi, if (json) { struct json_object *purge_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old deprecated key format */ purge_json = json_object_new_object(); json_object_object_add(json, "purge_originator", purge_json); json_object_string_add(purge_json, "id", gen_id); if (poi->sender_set) json_object_string_add(purge_json, "rec-from", sen_id); + /* end old deprecated key format */ + + purge_json = json_object_new_object(); + json_object_object_add(json, "purgeOriginator", purge_json); + + json_object_string_add(purge_json, "id", gen_id); + if (poi->sender_set) + json_object_string_add(purge_json, "recFrom", sen_id); } else { sbuf_push(buf, indent, "Purge Originator Identification:\n"); sbuf_push(buf, indent, " Generator: %s\n", gen_id); @@ -6364,6 +7080,11 @@ static void format_item_srv6_locator(uint16_t mtid, struct isis_item *i, if (json) { struct json_object *loc_json; + +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif + /* old json key format */ loc_json = json_object_new_object(); json_object_object_add(json, "srv6-locator", loc_json); json_object_int_add(loc_json, "mt-id", mtid); @@ -6385,6 +7106,26 @@ static void format_item_srv6_locator(uint16_t mtid, struct isis_item *i, subtlvs_json); format_subtlvs(loc->subtlvs, NULL, subtlvs_json, 0); } + /* old deprecated key format */ + + loc_json = json_object_new_object(); + json_object_object_add(json, "srv6Locator", loc_json); + json_object_int_add(loc_json, "mtId", mtid); + json_object_string_addf(loc_json, "prefix", "%pFX", + &loc->prefix); + json_object_int_add(loc_json, "metric", loc->metric); + json_object_boolean_add(loc_json, "flagD", + !!CHECK_FLAG(loc->flags, + ISIS_TLV_SRV6_LOCATOR_FLAG_D)); + json_object_int_add(loc_json, "algorithm", loc->algorithm); + json_object_string_add(loc_json, "MTName", isis_mtid2str(mtid)); + if (loc->subtlvs) { + struct json_object *subtlvs_json; + subtlvs_json = json_object_new_object(); + json_object_object_add(loc_json, "subtlvs", + subtlvs_json); + format_subtlvs(loc->subtlvs, NULL, subtlvs_json, 0); + } } else { sbuf_push(buf, indent, "SRv6 Locator: %pFX (Metric: %u)%s", &loc->prefix, loc->metric, @@ -6668,9 +7409,13 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, struct json_ob &tlvs->area_addresses, buf, json, indent); if (tlvs->mt_router_info_empty) { - if (json) + if (json) { +#if CONFDATE > 20240916 + CPP_NOTICE("remove deprecated key format with -") +#endif json_object_string_add(json, "mt-router-info", "none"); - else + json_object_object_add(json, "mtRouterInfo", NULL); + } else sbuf_push(buf, indent, "MT Router Info: None\n"); } else { format_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_ROUTER_INFO, diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py index 532e70859c34..b388f52bd9bd 100644 --- a/tests/topotests/isis_topo1/test_isis_topo1.py +++ b/tests/topotests/isis_topo1/test_isis_topo1.py @@ -685,7 +685,7 @@ def _check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected): ) database_json = json.loads(isis_database_output) - att_p_ol = database_json["areas"][0]["levels"][1]["att-p-ol"] + att_p_ol = database_json["areas"][0]["levels"][1]["lsps"][0]["attPOl"] if att_p_ol == att_p_ol_expected: return True return "{} peer with expected att_p_ol {} got {} ".format( From 2864b96332056e1244dfa0ba8c235976ee0b0d99 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 21 May 2024 11:48:56 +0200 Subject: [PATCH 141/472] isisd: add json display of extended admin groups Add JSON display of extended admin groups Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index c20b1d812971..6c6cab87cded 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -492,8 +492,23 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (IS_SUBTLV(exts, EXT_EXTEND_ADM_GRP) && admin_group_nb_words(&exts->ext_admin_group) != 0) { - if (!json) { - /* TODO json after fix show database detail json */ + if (json) { + struct json_object *ext_adm_grp_json; + size_t i; + ext_adm_grp_json = json_object_new_object(); + json_object_object_add(json, "extendedAdminGroup", + ext_adm_grp_json); + for (i = 0; + i < admin_group_nb_words(&exts->ext_admin_group); + i++) { + snprintfrr(cnt_buf, sizeof(cnt_buf), "%lu", + (unsigned long)i); + json_object_string_addf(ext_adm_grp_json, + cnt_buf, "0x%x", + exts->ext_admin_group + .bitmap.data[i]); + } + } else { sbuf_push(buf, indent, "Ext Admin Group: %s\n", admin_group_string( admin_group_buf, From 1c397942a46999a850ada62ea015a658373150c6 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 21 May 2024 11:48:58 +0200 Subject: [PATCH 142/472] isisd: fix crash when displaying asla in json Fix crash when displaying ASLAs (Application Specific Link-Attributes) with JSON Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 113 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 6c6cab87cded..3bb8a4824698 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -348,9 +348,120 @@ copy_item_ext_subtlvs(struct isis_ext_subtlvs *exts, uint16_t mtid) } static void format_item_asla_subtlvs(struct isis_asla_subtlvs *asla, + struct json_object *ext_json, struct sbuf *buf, int indent) { char admin_group_buf[ADMIN_GROUP_PRINT_MAX_SIZE]; + struct json_object *json; + char cnt_buf[255]; + size_t i; + int j; + + if (ext_json) { + json = json_object_new_object(); + json_object_object_add(ext_json, "asla", json); + json_object_boolean_add(json, "legacyFlag", asla->legacy); + json_object_string_addf(json, "standardApp", "0x%02x", + asla->standard_apps); + if (IS_SUBTLV(asla, EXT_ADM_GRP)) + json_object_string_addf(json, "adminGroup", "0x%x", + asla->admin_group); + if (IS_SUBTLV(asla, EXT_EXTEND_ADM_GRP) && + admin_group_nb_words(&asla->ext_admin_group) != 0) { + struct json_object *ext_adm_grp_json; + + ext_adm_grp_json = json_object_new_object(); + json_object_object_add(json, "extendedAdminGroup", + ext_adm_grp_json); + for (i = 0; + i < admin_group_nb_words(&asla->ext_admin_group); + i++) { + snprintfrr(cnt_buf, sizeof(cnt_buf), "%lu", + (unsigned long)i); + json_object_string_addf(ext_adm_grp_json, + cnt_buf, "0x%x", + asla->ext_admin_group + .bitmap.data[i]); + } + } + if (IS_SUBTLV(asla, EXT_MAX_BW)) + json_object_string_addf(json, "maxBandwithBytesSec", + "%g", asla->max_bw); + if (IS_SUBTLV(asla, EXT_MAX_RSV_BW)) + json_object_string_addf(json, "maxResBandwithBytesSec", + "%g", asla->max_rsv_bw); + if (IS_SUBTLV(asla, EXT_UNRSV_BW)) { + struct json_object *unrsv_json = + json_object_new_object(); + + json_object_object_add(json, "unrsvBandwithBytesSec", + unrsv_json); + for (j = 0; j < MAX_CLASS_TYPE; j += 1) { + snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", j); + json_object_string_addf(unrsv_json, cnt_buf, + "%g", asla->unrsv_bw[j]); + } + } + if (IS_SUBTLV(asla, EXT_TE_METRIC)) + json_object_int_add(json, "teMetric", asla->te_metric); + + /* Extended metrics */ + if (IS_SUBTLV(asla, EXT_DELAY)) { + struct json_object *avg_json; + + avg_json = json_object_new_object(); + json_object_object_add(json, "avgDelay", avg_json); + json_object_string_add(avg_json, "delay", + IS_ANORMAL(asla->delay) + ? "Anomalous" + : "Normal"); + json_object_int_add(avg_json, "microSec", asla->delay); + } + if (IS_SUBTLV(asla, EXT_MM_DELAY)) { + struct json_object *avg_json; + + avg_json = json_object_new_object(); + json_object_object_add(json, "maxMinDelay", avg_json); + json_object_string_add(avg_json, "delay", + IS_ANORMAL(asla->min_delay) + ? "Anomalous" + : "Normal"); + json_object_string_addf(avg_json, "microSec", "%u / %u", + asla->min_delay & TE_EXT_MASK, + asla->max_delay & TE_EXT_MASK); + } + if (IS_SUBTLV(asla, EXT_DELAY_VAR)) + json_object_int_add(json, "delayVariationMicroSec", + asla->delay_var & TE_EXT_MASK); + if (IS_SUBTLV(asla, EXT_PKT_LOSS)) { + struct json_object *link_json; + + link_json = json_object_new_object(); + json_object_object_add(json, "linkPacketLoss", + link_json); + json_object_string_add(link_json, "loss", + IS_ANORMAL(asla->pkt_loss) + ? "Anomalous" + : "Normal"); + json_object_string_addf(link_json, "percentage", "%g", + (float)((asla->pkt_loss & + TE_EXT_MASK) * + LOSS_PRECISION)); + } + if (IS_SUBTLV(asla, EXT_RES_BW)) + json_object_string_addf(json, + "unidirResidualBandBytesSec", + "%g", (asla->res_bw)); + if (IS_SUBTLV(asla, EXT_AVA_BW)) + json_object_string_addf(json, + "unidirAvailableBandBytesSec", + "%g", (asla->ava_bw)); + if (IS_SUBTLV(asla, EXT_USE_BW)) + json_object_string_addf(json, + "unidirUtilizedBandBytesSec", + "%g", (asla->use_bw)); + return; + } sbuf_push(buf, indent, "Application Specific Link Attributes:\n"); sbuf_push(buf, indent + 2, @@ -1399,7 +1510,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, } } for (ALL_LIST_ELEMENTS_RO(exts->aslas, node, asla)) - format_item_asla_subtlvs(asla, buf, indent); + format_item_asla_subtlvs(asla, json, buf, indent); } static void free_item_ext_subtlvs(struct isis_ext_subtlvs *exts) From 048609103c339ef1264ce9ff003647974323d341 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 23 May 2024 23:02:03 +0300 Subject: [PATCH 143/472] bgpd: Add sanity check for capability lengths before processing them This is for CAPABILITY messages, not for OPEN message capabilities. Signed-off-by: Donatas Abraitis --- bgpd/bgp_open.c | 64 +++++++++++++++++------------------ bgpd/bgp_open.h | 2 ++ bgpd/bgp_packet.c | 86 +++++++++++++++++++++++++++++++---------------- 3 files changed, 91 insertions(+), 61 deletions(-) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index e163df5954ee..248d478fe1a3 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -47,22 +47,22 @@ const struct message capcode_str[] = { }; /* Minimum sizes for length field of each cap (so not inc. the header) */ -static const size_t cap_minsizes[] = { - [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN, - [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN, - [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN, - [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN, - [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN, - [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN, - [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN, - [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN, - [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN, - [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN, - [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN, - [CAPABILITY_CODE_LLGR] = CAPABILITY_CODE_LLGR_LEN, - [CAPABILITY_CODE_ROLE] = CAPABILITY_CODE_ROLE_LEN, - [CAPABILITY_CODE_SOFT_VERSION] = CAPABILITY_CODE_SOFT_VERSION_LEN, - [CAPABILITY_CODE_PATHS_LIMIT] = CAPABILITY_CODE_PATHS_LIMIT_LEN, +const size_t cap_minsizes[] = { + [CAPABILITY_CODE_MP] = CAPABILITY_CODE_MP_LEN, + [CAPABILITY_CODE_REFRESH] = CAPABILITY_CODE_REFRESH_LEN, + [CAPABILITY_CODE_ORF] = CAPABILITY_CODE_ORF_LEN, + [CAPABILITY_CODE_RESTART] = CAPABILITY_CODE_RESTART_LEN, + [CAPABILITY_CODE_AS4] = CAPABILITY_CODE_AS4_LEN, + [CAPABILITY_CODE_ADDPATH] = CAPABILITY_CODE_ADDPATH_LEN, + [CAPABILITY_CODE_DYNAMIC] = CAPABILITY_CODE_DYNAMIC_LEN, + [CAPABILITY_CODE_ENHE] = CAPABILITY_CODE_ENHE_LEN, + [CAPABILITY_CODE_FQDN] = CAPABILITY_CODE_MIN_FQDN_LEN, + [CAPABILITY_CODE_ENHANCED_RR] = CAPABILITY_CODE_ENHANCED_LEN, + [CAPABILITY_CODE_EXT_MESSAGE] = CAPABILITY_CODE_EXT_MESSAGE_LEN, + [CAPABILITY_CODE_LLGR] = CAPABILITY_CODE_LLGR_LEN, + [CAPABILITY_CODE_ROLE] = CAPABILITY_CODE_ROLE_LEN, + [CAPABILITY_CODE_SOFT_VERSION] = CAPABILITY_CODE_SOFT_VERSION_LEN, + [CAPABILITY_CODE_PATHS_LIMIT] = CAPABILITY_CODE_PATHS_LIMIT_LEN, }; /* value the capability must be a multiple of. @@ -70,22 +70,22 @@ static const size_t cap_minsizes[] = { * Other capabilities whose data doesn't fall on convenient boundaries for this * table should be set to 1. */ -static const size_t cap_modsizes[] = { - [CAPABILITY_CODE_MP] = 4, - [CAPABILITY_CODE_REFRESH] = 1, - [CAPABILITY_CODE_ORF] = 1, - [CAPABILITY_CODE_RESTART] = 1, - [CAPABILITY_CODE_AS4] = 4, - [CAPABILITY_CODE_ADDPATH] = 4, - [CAPABILITY_CODE_DYNAMIC] = 1, - [CAPABILITY_CODE_ENHE] = 6, - [CAPABILITY_CODE_FQDN] = 1, - [CAPABILITY_CODE_ENHANCED_RR] = 1, - [CAPABILITY_CODE_EXT_MESSAGE] = 1, - [CAPABILITY_CODE_LLGR] = 1, - [CAPABILITY_CODE_ROLE] = 1, - [CAPABILITY_CODE_SOFT_VERSION] = 1, - [CAPABILITY_CODE_PATHS_LIMIT] = 5, +const size_t cap_modsizes[] = { + [CAPABILITY_CODE_MP] = 4, + [CAPABILITY_CODE_REFRESH] = 1, + [CAPABILITY_CODE_ORF] = 1, + [CAPABILITY_CODE_RESTART] = 1, + [CAPABILITY_CODE_AS4] = 4, + [CAPABILITY_CODE_ADDPATH] = 4, + [CAPABILITY_CODE_DYNAMIC] = 1, + [CAPABILITY_CODE_ENHE] = 6, + [CAPABILITY_CODE_FQDN] = 1, + [CAPABILITY_CODE_ENHANCED_RR] = 1, + [CAPABILITY_CODE_EXT_MESSAGE] = 1, + [CAPABILITY_CODE_LLGR] = 1, + [CAPABILITY_CODE_ROLE] = 1, + [CAPABILITY_CODE_SOFT_VERSION] = 1, + [CAPABILITY_CODE_PATHS_LIMIT] = 5, }; /* BGP-4 Multiprotocol Extentions lead us to the complex world. We can diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index a01e49ceba51..3a8cba9b7d33 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -112,5 +112,7 @@ extern as_t peek_for_as4_capability(struct peer *peer, uint16_t length); extern const struct message capcode_str[]; extern const struct message orf_type_str[]; extern const struct message orf_mode_str[]; +extern const size_t cap_minsizes[]; +extern const size_t cap_modsizes[]; #endif /* _QUAGGA_BGP_OPEN_H */ diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 9c194eac1c2a..47aed53bc73d 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -3406,6 +3406,22 @@ static void bgp_dynamic_capability_orf(uint8_t *pnt, int action, } } +static void bgp_dynamic_capability_role(uint8_t *pnt, int action, + struct peer *peer) +{ + uint8_t role; + + if (action == CAPABILITY_ACTION_SET) { + SET_FLAG(peer->cap, PEER_CAP_ROLE_RCV); + memcpy(&role, pnt + 3, sizeof(role)); + + peer->remote_role = role; + } else { + UNSET_FLAG(peer->cap, PEER_CAP_ROLE_RCV); + peer->remote_role = ROLE_UNDEFINED; + } +} + static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action, struct capability_header *hdr, struct peer *peer) @@ -3775,6 +3791,46 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, capability = lookup_msg(capcode_str, hdr->code, "Unknown"); + /* Length sanity check, type-specific, for known capabilities */ + switch (hdr->code) { + case CAPABILITY_CODE_MP: + case CAPABILITY_CODE_REFRESH: + case CAPABILITY_CODE_ORF: + case CAPABILITY_CODE_RESTART: + case CAPABILITY_CODE_AS4: + case CAPABILITY_CODE_ADDPATH: + case CAPABILITY_CODE_DYNAMIC: + case CAPABILITY_CODE_ENHE: + case CAPABILITY_CODE_FQDN: + case CAPABILITY_CODE_ENHANCED_RR: + case CAPABILITY_CODE_EXT_MESSAGE: + case CAPABILITY_CODE_ROLE: + case CAPABILITY_CODE_SOFT_VERSION: + case CAPABILITY_CODE_PATHS_LIMIT: + if (hdr->length < cap_minsizes[hdr->code]) { + zlog_info("%pBP: %s Capability length error: got %u, expected at least %u", + peer, capability, hdr->length, + (unsigned int)cap_minsizes[hdr->code]); + bgp_notify_send(peer->connection, + BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_MALFORMED_ATTR); + goto done; + } + if (hdr->length && + hdr->length % cap_modsizes[hdr->code] != 0) { + zlog_info("%pBP %s Capability length error: got %u, expected a multiple of %u", + peer, capability, hdr->length, + (unsigned int)cap_modsizes[hdr->code]); + bgp_notify_send(peer->connection, + BGP_NOTIFY_OPEN_ERR, + BGP_NOTIFY_OPEN_MALFORMED_ATTR); + goto done; + } + break; + default: + break; + } + switch (hdr->code) { case CAPABILITY_CODE_SOFT_VERSION: bgp_dynamic_capability_software_version(pnt, action, @@ -3832,15 +3888,6 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, } break; case CAPABILITY_CODE_RESTART: - if ((hdr->length - 2) % 4) { - zlog_err("%pBP: Received invalid Graceful-Restart capability length %d", - peer, hdr->length); - bgp_notify_send(peer->connection, - BGP_NOTIFY_CEASE, - BGP_NOTIFY_SUBCODE_UNSPECIFIC); - goto done; - } - bgp_dynamic_capability_graceful_restart(pnt, action, hdr, peer); break; @@ -3868,26 +3915,7 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, case CAPABILITY_CODE_EXT_MESSAGE: break; case CAPABILITY_CODE_ROLE: - if (hdr->length != CAPABILITY_CODE_ROLE_LEN) { - zlog_err("%pBP: Capability (%s) length error", - peer, capability); - bgp_notify_send(peer->connection, - BGP_NOTIFY_CEASE, - BGP_NOTIFY_SUBCODE_UNSPECIFIC); - goto done; - } - - uint8_t role; - - if (action == CAPABILITY_ACTION_SET) { - SET_FLAG(peer->cap, PEER_CAP_ROLE_RCV); - memcpy(&role, pnt + 3, sizeof(role)); - - peer->remote_role = role; - } else { - UNSET_FLAG(peer->cap, PEER_CAP_ROLE_RCV); - peer->remote_role = ROLE_UNDEFINED; - } + bgp_dynamic_capability_role(pnt, action, peer); break; default: flog_warn(EC_BGP_UNRECOGNIZED_CAPABILITY, From 150eb73054902511b4be78666ab9895a7509a4ce Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 24 May 2024 08:50:49 +0300 Subject: [PATCH 144/472] bgpd: Send a notification if we receive CAPABILITY message if not exepected Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 47aed53bc73d..a32ee7886154 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -3952,8 +3952,8 @@ int bgp_capability_receive(struct peer_connection *connection, if (bgp_debug_neighbor_events(peer)) zlog_debug("%s rcv CAPABILITY", peer->host); - /* If peer does not have the capability, send notification. */ - if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV)) { + if (!CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_ADV) || + !CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) { flog_err(EC_BGP_NO_CAP, "%s [Error] BGP dynamic capability is not enabled", peer->host); From 0d079e01e55c35f466dc4982d9c2964f81a70140 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 24 May 2024 09:58:30 +0300 Subject: [PATCH 145/472] bgpd: Check if FQDN capability length is in valid ranges If FQDN capability comes as dynamic capability we should check if the encoding is proper. Before this patch we returned an error if the hostname/domainname length check was > end. But technically, if the length is also == end, this is a malformed capability, because we use the data incorrectly after we check the length. This causes heap overflow (when compiled with address-sanitizer). Signed-off-by: Iggy Frankovic Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index a32ee7886154..86f85dd86662 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -3433,7 +3433,7 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action, if (action == CAPABILITY_ACTION_SET) { /* hostname */ - if (data + 1 > end) { + if (data + 1 >= end) { zlog_err("%pBP: Received invalid FQDN capability (host name length)", peer); return; @@ -3463,7 +3463,7 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action, peer->hostname = XSTRDUP(MTYPE_BGP_PEER_HOST, str); } - if (data + 1 > end) { + if (data + 1 >= end) { zlog_err("%pBP: Received invalid FQDN capability (domain name length)", peer); return; From 773a45ef29e0ab128492f2ed8a9bb014f5d75b70 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Fri, 17 May 2024 12:03:20 -0700 Subject: [PATCH 146/472] bgpd: Return success if lcomm/comm/extcomm name or entry is not found Problem: Currently bgp prints `Can't find community-list` and returns CMD_WARNING_CONFIG_FAILED error if name or an entry for community, large-community and ext-community is not found. This causes frr-reload to fail. Fix: Return success if community, large-community and ext-community name or an entry is not found. Ticket:#3900813 Testing Done: Before fix: ``` root@tor-4:mgmt:/var/home/cumulus# cat /etc/frr/frr.conf bgp large-community-list standard lc22 seq 10 permit 4200857911:011:01 4200857911:011:011555 no bgp large-community-list standard lc22 seq 10 permit 4200857911:011:01 root@tor-4:mgmt:/var/home/cumulus# systemctl reload frr Job for frr.service failed. See "systemctl status frr.service" and "journalctl -xeu frr.service" for details. Syslog: 2024-05-21T21:02:51.525965+00:00 tor-4 frrinit.sh[2349145]: % Can't find community-list 2024-05-21T21:02:51.526487+00:00 tor-4 staticd[6167]: [VTVCM-Y2NW3] Configuration Read in Took: 00:00:00 2024-05-21T21:02:51.526595+00:00 tor-4 frrinit.sh[2349155]: [2349155|staticd] done 2024-05-21T21:02:51.526826+00:00 tor-4 frrinit.sh[2349145]: line 176: Failure to communicate[13] to bgpd, line: no bgp large-community-list standard lc22 seq 10 permit 4200857911:011:01 2024-05-21T21:02:51.527928+00:00 tor-4 frrinit.sh[2349153]: [2349153|watchfrr] done 2024-05-21T21:02:51.528382+00:00 tor-4 frrinit.sh[2349145]: [2349145|bgpd] Configuration file[/etc/frr/frr.conf] processing failure: 13 ``` After fix: ``` root@tor-4:mgmt:/var/home/cumulus# cat /etc/frr/frr.conf bgp large-community-list standard lc22 seq 10 permit 4200857911:011:01 4200857911:011:011555 no bgp large-community-list standard lc22 seq 10 permit 4200857911:011:01 root@tor-4:mgmt:/var/home/cumulus# systemctl reload frr root@tor-4:mgmt:/var/home/cumulus# root@tor-4:mgmt:/var/home/cumulus# vtysh -c "show run" | grep lc22 bgp large-community-list standard lc22 seq 10 permit 4200857911:11:1 4200857911:11:11555 root@tor-4:mgmt:/var/home/cumulus# ``` Signed-off-by: Pooja Jagadeesh Doijode Signed-off-by: Chirag Shah --- bgpd/bgp_clist.c | 44 +++++++++++++++++++------------------------- bgpd/bgp_clist.h | 18 +++++++++--------- bgpd/bgp_vty.c | 46 ++++++++++------------------------------------ 3 files changed, 38 insertions(+), 70 deletions(-) diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index 8336d6f3115f..153cbd6e5015 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -904,9 +904,9 @@ int community_list_set(struct community_list_handler *ch, const char *name, } /* Unset community-list */ -int community_list_unset(struct community_list_handler *ch, const char *name, - const char *str, const char *seq, int direct, - int style) +void community_list_unset(struct community_list_handler *ch, const char *name, + const char *str, const char *seq, int direct, + int style) { struct community_list_master *cm = NULL; struct community_entry *entry = NULL; @@ -916,14 +916,14 @@ int community_list_unset(struct community_list_handler *ch, const char *name, /* Lookup community list. */ list = community_list_lookup(ch, name, 0, COMMUNITY_LIST_MASTER); if (list == NULL) - return COMMUNITY_LIST_ERR_CANT_FIND_LIST; + return; cm = community_list_master_lookup(ch, COMMUNITY_LIST_MASTER); /* Delete all of entry belongs to this community-list. */ if (!str) { community_list_delete(cm, list); route_map_notify_dependencies(name, RMAP_EVENT_CLIST_DELETED); - return 0; + return; } if (style == COMMUNITY_LIST_STANDARD) @@ -936,12 +936,10 @@ int community_list_unset(struct community_list_handler *ch, const char *name, entry = community_list_entry_lookup(list, str, direct); if (!entry) - return COMMUNITY_LIST_ERR_CANT_FIND_LIST; + return; community_list_entry_delete(cm, list, entry); route_map_notify_dependencies(name, RMAP_EVENT_CLIST_DELETED); - - return 0; } bool lcommunity_list_any_match(struct lcommunity *lcom, @@ -1172,9 +1170,9 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name, /* Unset community-list. When str is NULL, delete all of community-list entry belongs to the specified name. */ -int lcommunity_list_unset(struct community_list_handler *ch, const char *name, - const char *str, const char *seq, int direct, - int style) +void lcommunity_list_unset(struct community_list_handler *ch, const char *name, + const char *str, const char *seq, int direct, + int style) { struct community_list_master *cm = NULL; struct community_entry *entry = NULL; @@ -1185,14 +1183,14 @@ int lcommunity_list_unset(struct community_list_handler *ch, const char *name, /* Lookup community list. */ list = community_list_lookup(ch, name, 0, LARGE_COMMUNITY_LIST_MASTER); if (list == NULL) - return COMMUNITY_LIST_ERR_CANT_FIND_LIST; + return; cm = community_list_master_lookup(ch, LARGE_COMMUNITY_LIST_MASTER); /* Delete all of entry belongs to this community-list. */ if (!str) { community_list_delete(cm, list); route_map_notify_dependencies(name, RMAP_EVENT_LLIST_DELETED); - return 0; + return; } if (style == LARGE_COMMUNITY_LIST_STANDARD) @@ -1201,7 +1199,7 @@ int lcommunity_list_unset(struct community_list_handler *ch, const char *name, regex = bgp_regcomp(str); if (!lcom && !regex) - return COMMUNITY_LIST_ERR_MALFORMED_VAL; + return; if (lcom) entry = community_list_entry_lookup(list, lcom, direct); @@ -1214,12 +1212,10 @@ int lcommunity_list_unset(struct community_list_handler *ch, const char *name, bgp_regex_free(regex); if (!entry) - return COMMUNITY_LIST_ERR_CANT_FIND_LIST; + return; community_list_entry_delete(cm, list, entry); route_map_notify_dependencies(name, RMAP_EVENT_LLIST_DELETED); - - return 0; } /* Set extcommunity-list. */ @@ -1299,9 +1295,9 @@ int extcommunity_list_set(struct community_list_handler *ch, const char *name, * When str is NULL, delete all extcommunity-list entries belonging to the * specified name. */ -int extcommunity_list_unset(struct community_list_handler *ch, const char *name, - const char *str, const char *seq, int direct, - int style) +void extcommunity_list_unset(struct community_list_handler *ch, + const char *name, const char *str, const char *seq, + int direct, int style) { struct community_list_master *cm = NULL; struct community_entry *entry = NULL; @@ -1311,14 +1307,14 @@ int extcommunity_list_unset(struct community_list_handler *ch, const char *name, /* Lookup extcommunity list. */ list = community_list_lookup(ch, name, 0, EXTCOMMUNITY_LIST_MASTER); if (list == NULL) - return COMMUNITY_LIST_ERR_CANT_FIND_LIST; + return; cm = community_list_master_lookup(ch, EXTCOMMUNITY_LIST_MASTER); /* Delete all of entry belongs to this extcommunity-list. */ if (!str) { community_list_delete(cm, list); route_map_notify_dependencies(name, RMAP_EVENT_ECLIST_DELETED); - return 0; + return; } if (style == EXTCOMMUNITY_LIST_STANDARD) @@ -1331,12 +1327,10 @@ int extcommunity_list_unset(struct community_list_handler *ch, const char *name, entry = community_list_entry_lookup(list, str, direct); if (!entry) - return COMMUNITY_LIST_ERR_CANT_FIND_LIST; + return; community_list_entry_delete(cm, list, entry); route_map_notify_dependencies(name, RMAP_EVENT_ECLIST_DELETED); - - return 0; } /* Initializa community-list. Return community-list handler. */ diff --git a/bgpd/bgp_clist.h b/bgpd/bgp_clist.h index a435b92ce183..339548305463 100644 --- a/bgpd/bgp_clist.h +++ b/bgpd/bgp_clist.h @@ -124,22 +124,22 @@ extern void community_list_terminate(struct community_list_handler *ch); extern int community_list_set(struct community_list_handler *ch, const char *name, const char *str, const char *seq, int direct, int style); -extern int community_list_unset(struct community_list_handler *ch, - const char *name, const char *str, - const char *seq, int direct, int style); +extern void community_list_unset(struct community_list_handler *ch, + const char *name, const char *str, + const char *seq, int direct, int style); extern int extcommunity_list_set(struct community_list_handler *ch, const char *name, const char *str, const char *seq, int direct, int style); -extern int extcommunity_list_unset(struct community_list_handler *ch, - const char *name, const char *str, - const char *seq, int direct, int style); +extern void extcommunity_list_unset(struct community_list_handler *ch, + const char *name, const char *str, + const char *seq, int direct, int style); extern int lcommunity_list_set(struct community_list_handler *ch, const char *name, const char *str, const char *seq, int direct, int style); extern bool lcommunity_list_valid(const char *community, int style); -extern int lcommunity_list_unset(struct community_list_handler *ch, - const char *name, const char *str, - const char *seq, int direct, int style); +extern void lcommunity_list_unset(struct community_list_handler *ch, + const char *name, const char *str, + const char *seq, int direct, int style); extern struct community_list_master * community_list_master_lookup(struct community_list_handler *ch, int master); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index bdeae6d0c46d..6d78f929c4d4 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -21827,16 +21827,11 @@ DEFUN (no_community_list_standard_all, argv_find(argv, argc, "COMMUNITY_LIST_NAME", &idx); cl_name_or_number = argv[idx]->arg; - int ret = community_list_unset(bgp_clist, cl_name_or_number, str, seq, - direct, style); + community_list_unset(bgp_clist, cl_name_or_number, str, seq, direct, + style); XFREE(MTYPE_TMP, str); - if (ret < 0) { - community_list_perror(vty, ret); - return CMD_WARNING_CONFIG_FAILED; - } - return CMD_SUCCESS; } @@ -21940,16 +21935,11 @@ DEFUN (no_community_list_expanded_all, argv_find(argv, argc, "COMMUNITY_LIST_NAME", &idx); cl_name_or_number = argv[idx]->arg; - int ret = community_list_unset(bgp_clist, cl_name_or_number, str, seq, - direct, style); + community_list_unset(bgp_clist, cl_name_or_number, str, seq, direct, + style); XFREE(MTYPE_TMP, str); - if (ret < 0) { - community_list_perror(vty, ret); - return CMD_WARNING_CONFIG_FAILED; - } - return CMD_SUCCESS; } @@ -22105,7 +22095,6 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc, static int lcommunity_list_unset_vty(struct vty *vty, int argc, struct cmd_token **argv, int style) { - int ret; int direct = 0; char *str = NULL; int idx = 0; @@ -22138,18 +22127,13 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc, argv_find(argv, argc, "LCOMMUNITY_LIST_NAME", &idx); /* Unset community list. */ - ret = lcommunity_list_unset(bgp_clist, argv[idx]->arg, str, seq, direct, - style); + lcommunity_list_unset(bgp_clist, argv[idx]->arg, str, seq, direct, + style); /* Free temporary community list string allocated by argv_concat(). */ XFREE(MTYPE_TMP, str); - if (ret < 0) { - community_list_perror(vty, ret); - return CMD_WARNING_CONFIG_FAILED; - } - return CMD_SUCCESS; } @@ -22546,16 +22530,11 @@ DEFUN (no_extcommunity_list_standard_all, argv_find(argv, argc, "EXTCOMMUNITY_LIST_NAME", &idx); cl_number_or_name = argv[idx]->arg; - int ret = extcommunity_list_unset(bgp_clist, cl_number_or_name, str, - seq, direct, style); + extcommunity_list_unset(bgp_clist, cl_number_or_name, str, seq, direct, + style); XFREE(MTYPE_TMP, str); - if (ret < 0) { - community_list_perror(vty, ret); - return CMD_WARNING_CONFIG_FAILED; - } - return CMD_SUCCESS; } @@ -22611,16 +22590,11 @@ DEFUN (no_extcommunity_list_expanded_all, argv_find(argv, argc, "EXTCOMMUNITY_LIST_NAME", &idx); cl_number_or_name = argv[idx]->arg; - int ret = extcommunity_list_unset(bgp_clist, cl_number_or_name, str, - seq, direct, style); + extcommunity_list_unset(bgp_clist, cl_number_or_name, str, seq, direct, + style); XFREE(MTYPE_TMP, str); - if (ret < 0) { - community_list_perror(vty, ret); - return CMD_WARNING_CONFIG_FAILED; - } - return CMD_SUCCESS; } From a7c3317abafa011c64c78ce35017724d691e0ae0 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Fri, 17 May 2024 12:37:24 -0700 Subject: [PATCH 147/472] bgpd: Removed unused COMMUNITY_LIST_ERR_CANT_FIND_LIST Removed the unused COMMUNITY_LIST_ERR_CANT_FIND_LIST Ticket:#3900813 Testing Done: precommit Signed-off-by: Pooja Jagadeesh Doijode --- bgpd/bgp_clist.h | 8 +++----- bgpd/bgp_vty.c | 3 --- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_clist.h b/bgpd/bgp_clist.h index 339548305463..29bd880c937e 100644 --- a/bgpd/bgp_clist.h +++ b/bgpd/bgp_clist.h @@ -109,11 +109,9 @@ struct community_list_handler { }; /* Error code of community-list. */ -#define COMMUNITY_LIST_ERR_CANT_FIND_LIST -1 -#define COMMUNITY_LIST_ERR_MALFORMED_VAL -2 -#define COMMUNITY_LIST_ERR_STANDARD_CONFLICT -3 -#define COMMUNITY_LIST_ERR_EXPANDED_CONFLICT -4 - +#define COMMUNITY_LIST_ERR_MALFORMED_VAL -1 +#define COMMUNITY_LIST_ERR_STANDARD_CONFLICT -2 +#define COMMUNITY_LIST_ERR_EXPANDED_CONFLICT -3 /* Handler. */ extern struct community_list_handler *bgp_clist; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 6d78f929c4d4..be9942afb6ea 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -21715,9 +21715,6 @@ static const char *community_direct_str(int direct) static void community_list_perror(struct vty *vty, int ret) { switch (ret) { - case COMMUNITY_LIST_ERR_CANT_FIND_LIST: - vty_out(vty, "%% Can't find community-list\n"); - break; case COMMUNITY_LIST_ERR_MALFORMED_VAL: vty_out(vty, "%% Malformed community-list value\n"); break; From d15cc4741beacc0de0a036e35c4b23196cdbda48 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Thu, 23 May 2024 21:49:28 +0800 Subject: [PATCH 148/472] ospfd: add instance id for one command Add the specific instance id for the command: ``` show ip ospf [{(1-65535)$instance|vrf }] graceful-restart helper [detail] [json] ``` Signed-off-by: anlan_cs --- ospfd/ospf_vty.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 301320bb0a2b..7cb51976f564 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -10755,10 +10755,11 @@ DEFUN (ospf_route_aggregation_timer, DEFPY (show_ip_ospf_gr_helper, show_ip_ospf_gr_helper_cmd, - "show ip ospf [vrf ] graceful-restart helper [detail] [json]", + "show ip ospf [{(1-65535)$instance|vrf }] graceful-restart helper [detail] [json]", SHOW_STR IP_STR "OSPF information\n" + "Instance ID\n" VRF_CMD_HELP_STR "All VRFs\n" "OSPF Graceful Restart\n" @@ -10779,8 +10780,20 @@ DEFPY (show_ip_ospf_gr_helper, int inst = 0; bool detail = false; + if (instance && instance != ospf_instance) + return CMD_NOT_MY_INSTANCE; + + ospf = ospf_lookup_instance(instance); + if (!ospf || !ospf->oi_running) + return CMD_SUCCESS; + OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + if (instance && vrf_name) { + vty_out(vty, "%% VRF is not supported in instance mode\n"); + return CMD_WARNING; + } + if (argv_find(argv, argc, "detail", &idx)) detail = true; From b212c4d0760818880f510b1412d055677d7c0f9d Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Thu, 23 May 2024 22:08:28 +0800 Subject: [PATCH 149/472] doc: adjust one ospf command Signed-off-by: anlan_cs --- doc/user/ospfd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index ad0b25aec41a..70c15e73deb0 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -987,7 +987,7 @@ Showing Information User can get that information as JSON format when ``json`` keyword at the end of cli is presented. -.. clicmd:: show ip ospf graceful-restart helper [detail] [json] +.. clicmd:: show ip ospf [{(1-65535)|vrf }] graceful-restart helper [detail] [json] Displays the Graceful Restart Helper details including helper config changes. From 496ede2495b7131c102b379bd9bbb71bc7514edd Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 26 May 2024 18:43:43 +0300 Subject: [PATCH 150/472] bgpd: Convert unk_ecom to boolean Signed-off-by: Donatas Abraitis --- bgpd/bgp_ecommunity.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index d392b6585c95..253538557c3d 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -1143,7 +1143,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) char encbuf[128]; for (i = 0; i < ecom->size; i++) { - int unk_ecom = 0; + bool unk_ecom = false; memset(encbuf, 0x00, sizeof(encbuf)); /* Space between each value. */ @@ -1187,7 +1187,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) encbuf, sizeof(encbuf), pnt, format); } else - unk_ecom = 1; + unk_ecom = true; } else { ecommunity_rt_soo_str(encbuf, sizeof(encbuf), pnt, type, sub_type, @@ -1210,7 +1210,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) ecommunity_color_str(encbuf, sizeof(encbuf), pnt); } else { - unk_ecom = 1; + unk_ecom = true; } } else if (type == ECOMMUNITY_ENCODE_EVPN) { if (filter == ECOMMUNITY_ROUTE_TARGET) @@ -1303,14 +1303,14 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) "DF: (alg: %u, pref: %u)", alg, pref); } else - unk_ecom = 1; + unk_ecom = true; } else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH) { sub_type = *pnt++; if (sub_type == ECOMMUNITY_REDIRECT_IP_NH) { snprintf(encbuf, sizeof(encbuf), "FS:redirect IP 0x%x", *(pnt + 5)); } else - unk_ecom = 1; + unk_ecom = true; } else if (type == ECOMMUNITY_ENCODE_TRANS_EXP || type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 || type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_3) { @@ -1357,7 +1357,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) snprintf(encbuf, sizeof(encbuf), "FS:redirect VRF %s", buf); } else if (type != ECOMMUNITY_ENCODE_TRANS_EXP) - unk_ecom = 1; + unk_ecom = true; else if (sub_type == ECOMMUNITY_TRAFFIC_ACTION) { char action[64]; @@ -1390,7 +1390,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) snprintf(encbuf, sizeof(encbuf), "FS:marking %u", *(pnt + 5)); } else - unk_ecom = 1; + unk_ecom = true; } else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) { sub_type = *pnt++; if (sub_type == ECOMMUNITY_LINK_BANDWIDTH) @@ -1400,24 +1400,24 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf), pnt); else - unk_ecom = 1; + unk_ecom = true; } else if (type == ECOMMUNITY_ENCODE_IP_NON_TRANS) { sub_type = *pnt++; if (sub_type == ECOMMUNITY_NODE_TARGET) ecommunity_node_target_str( encbuf, sizeof(encbuf), pnt, format); else - unk_ecom = 1; + unk_ecom = true; } else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) { sub_type = *pnt++; if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE) ecommunity_origin_validation_state_str( encbuf, sizeof(encbuf), pnt); else - unk_ecom = 1; + unk_ecom = true; } else { sub_type = *pnt++; - unk_ecom = 1; + unk_ecom = true; } if (unk_ecom) From 3d21e3ebf17c1046839d4c26966c3c7547dc2091 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 26 May 2024 18:45:01 +0300 Subject: [PATCH 151/472] bgpd: Add a safety check for ecommunity_ecom2str Just in case we have enough data according to the community unit size. It should be 8 or 20 (for now). Signed-off-by: Donatas Abraitis --- bgpd/bgp_ecommunity.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 253538557c3d..88f139cafdeb 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -1153,6 +1153,18 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) /* Retrieve value field */ pnt = ecom->val + (i * ecom->unit_size); + uint8_t *data = pnt; + uint8_t *end = data + ecom->unit_size; + size_t len = end - data; + + /* Sanity check for extended communities lenght, to avoid + * overrun when dealing with bits, e.g. ptr_get_be64(). + */ + if (len < ecom->unit_size) { + unk_ecom = true; + goto unknown; + } + /* High-order octet is the type */ type = *pnt++; @@ -1420,6 +1432,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) unk_ecom = true; } +unknown: if (unk_ecom) snprintf(encbuf, sizeof(encbuf), "UNK:%d, %d", type, sub_type); From 0f5834d49960807881ec1c8020349476255f2271 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 26 May 2024 18:49:22 +0300 Subject: [PATCH 152/472] bgpd: Make sure we have enough data to handle extended link bandwidth Extended link bandwidth is encoded inside extended community as a ipv6-address specific extended community, but with a malformed packet we should do the sanity check here to have enough data. Especially before doing ptr_get_be64(). Reported-by: Iggy Frankovic Signed-off-by: Donatas Abraitis --- bgpd/bgp_ecommunity.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 88f139cafdeb..66898d07bc21 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -1048,13 +1048,17 @@ static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt, return len; } -static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) +static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt, + size_t length) { int len = 0; - as_t as; - uint64_t bw; + as_t as = 0; + uint64_t bw = 0; char bps_buf[20] = { 0 }; + if (length < IPV6_ECOMMUNITY_SIZE) + goto done; + pnt += 2; /* Reserved */ pnt = ptr_get_be64(pnt, &bw); (void)ptr_get_be32(pnt, &as); @@ -1071,6 +1075,7 @@ static int ipv6_ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt) else snprintfrr(bps_buf, sizeof(bps_buf), "%" PRIu64 " bps", bw * 8); +done: len = snprintfrr(buf, bufsz, "LB:%u:%" PRIu64 " (%s)", as, bw, bps_buf); return len; } @@ -1192,7 +1197,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) type == ECOMMUNITY_ENCODE_AS4) { ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf), - pnt); + pnt, len); } else if (sub_type == ECOMMUNITY_NODE_TARGET && type == ECOMMUNITY_ENCODE_IP) { ecommunity_node_target_str( @@ -1410,7 +1415,7 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter) ecom->disable_ieee_floating); else if (sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH) ipv6_ecommunity_lb_str(encbuf, sizeof(encbuf), - pnt); + pnt, len); else unk_ecom = true; } else if (type == ECOMMUNITY_ENCODE_IP_NON_TRANS) { From 107e3a586d46829c3bc4355429a249604a0e8ffd Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Sun, 26 May 2024 22:12:28 +0000 Subject: [PATCH 153/472] doc: add missing required newline in .rst formatting Signed-off-by: Christian Hopps --- doc/developer/topotests.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index b89b63029b1d..e1702c47c781 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -46,6 +46,7 @@ The version of protobuf package that is installed on your system will determine which versions of the python protobuf packages you need to install. .. code:: shell + # - Either - For protobuf version <= 3.12 python3 -m pip install 'protobuf<4' From 95426606b1e7e8c7a395be5de5787cf7d9485f06 Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Mon, 27 May 2024 12:20:25 +0530 Subject: [PATCH 154/472] tests: Organizing variables using format method Using format method to look code more presentable and readable Signed-off-by: y-bharath14 --- .../test_all_protocol_startup.py | 409 ++++++++++-------- 1 file changed, 230 insertions(+), 179 deletions(-) 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 e067cdb7634d..b4bc1e14ad6a 100644 --- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py +++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py @@ -54,7 +54,7 @@ def build_topo(tgen): router = tgen.add_router("r1") for i in range(0, 10): - tgen.add_switch("sw%d" % i).add_link(router) + tgen.add_switch("sw{}".format(i)).add_link(router) ##################################################### @@ -67,7 +67,7 @@ def build_topo(tgen): def setup_module(module): global fatal_error - print("\n\n** %s: Setup Topology" % module.__name__) + print("\n\n** {}: Setup Topology".format(module.__name__)) print("******************************************\n") thisDir = os.path.dirname(os.path.realpath(__file__)) @@ -85,34 +85,36 @@ def setup_module(module): # # Main router for i in range(1, 2): - net["r%s" % i].loadConf("mgmtd", "%s/r%s/zebra.conf" % (thisDir, i)) - net["r%s" % i].loadConf("zebra", "%s/r%s/zebra.conf" % (thisDir, i)) - net["r%s" % i].loadConf("ripd", "%s/r%s/ripd.conf" % (thisDir, i)) - net["r%s" % i].loadConf("ripngd", "%s/r%s/ripngd.conf" % (thisDir, i)) - net["r%s" % i].loadConf("ospfd", "%s/r%s/ospfd.conf" % (thisDir, i)) + net["r{}".format(i)].loadConf("mgmtd", "{}/r{}/zebra.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("zebra", "{}/r{}/zebra.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("ripd", "{}/r{}/ripd.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("ripngd", "{}/r{}/ripngd.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("ospfd", "{}/r{}/ospfd.conf".format(thisDir, i)) if net["r1"].checkRouterVersion("<", "4.0"): - net["r%s" % i].loadConf( - "ospf6d", "%s/r%s/ospf6d.conf-pre-v4" % (thisDir, i) + net["r{}".format(i)].loadConf( + "ospf6d", "{}/r{}/ospf6d.conf-pre-v4".format(thisDir, i) ) else: - net["r%s" % i].loadConf("ospf6d", "%s/r%s/ospf6d.conf" % (thisDir, i)) - net["r%s" % i].loadConf("isisd", "%s/r%s/isisd.conf" % (thisDir, i)) - net["r%s" % i].loadConf("bgpd", "%s/r%s/bgpd.conf" % (thisDir, i)) - if net["r%s" % i].daemon_available("ldpd"): + net["r{}".format(i)].loadConf( + "ospf6d", "{}/r{}/ospf6d.conf".format(thisDir, i) + ) + net["r{}".format(i)].loadConf("isisd", "{}/r{}/isisd.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("bgpd", "{}/r{}/bgpd.conf".format(thisDir, i)) + if net["r{}".format(i)].daemon_available("ldpd"): # Only test LDPd if it's installed and Kernel >= 4.5 - net["r%s" % i].loadConf("ldpd", "%s/r%s/ldpd.conf" % (thisDir, i)) - net["r%s" % i].loadConf("sharpd") - net["r%s" % i].loadConf("nhrpd", "%s/r%s/nhrpd.conf" % (thisDir, i)) - net["r%s" % i].loadConf("babeld", "%s/r%s/babeld.conf" % (thisDir, i)) - net["r%s" % i].loadConf("pbrd", "%s/r%s/pbrd.conf" % (thisDir, i)) - tgen.gears["r%s" % i].start() + net["r{}".format(i)].loadConf("ldpd", "{}/r{}/ldpd.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("sharpd") + net["r{}".format(i)].loadConf("nhrpd", "{}/r{}/nhrpd.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("babeld", "{}/r{}/babeld.conf".format(thisDir, i)) + net["r{}".format(i)].loadConf("pbrd", "{}/r{}/pbrd.conf".format(thisDir, i)) + tgen.gears["r{}".format(i)].start() # For debugging after starting FRR daemons, uncomment the next line # tgen.mininet_cli() def teardown_module(module): - print("\n\n** %s: Shutdown Topology" % module.__name__) + print("\n\n** {}: Shutdown Topology".format(module.__name__)) print("******************************************\n") tgen = get_topogen() tgen.stop_topology() @@ -133,7 +135,7 @@ def test_router_running(): # Starting Routers for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error # For debugging after starting FRR daemons, uncomment the next line @@ -158,7 +160,9 @@ def test_error_messages_vtysh(): # # VTYSH output from router - vtystdout = net["r%s" % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip() + vtystdout = ( + net["r{}".format(i)].cmd('vtysh -c "show version" 2> /dev/null').rstrip() + ) # Fix newlines (make them all the same) vtystdout = ("\n".join(vtystdout.splitlines()) + "\n").rstrip() @@ -166,16 +170,20 @@ def test_error_messages_vtysh(): vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL) if vtystdout == "": - print("r%s StdOut ok" % i) + print("r{} StdOut ok".format(i)) - assert vtystdout == "", "Vtysh StdOut Output check failed for router r%s" % i + assert ( + vtystdout == "" + ), "Vtysh StdOut Output check failed for router r{}".format(i) # # Second checking Standard Error # # VTYSH StdErr output from router - vtystderr = net["r%s" % i].cmd('vtysh -c "show version" > /dev/null').rstrip() + vtystderr = ( + net["r{}".format(i)].cmd('vtysh -c "show version" > /dev/null').rstrip() + ) # Fix newlines (make them all the same) vtystderr = ("\n".join(vtystderr.splitlines()) + "\n").rstrip() @@ -183,13 +191,15 @@ def test_error_messages_vtysh(): # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL) if vtystderr == "": - print("r%s StdErr ok" % i) + print("r{} StdErr ok".format(i)) - assert vtystderr == "", "Vtysh StdErr Output check failed for router r%s" % i + assert ( + vtystderr == "" + ), "Vtysh StdErr Output check failed for router r{}".format(i) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -213,37 +223,37 @@ def test_error_messages_daemons(): error_logs = "" for i in range(1, 2): - log = net["r%s" % i].getStdErr("ripd") + log = net["r{}".format(i)].getStdErr("ripd") if log: - error_logs += "r%s RIPd StdErr Output:\n" % i + error_logs += "r{} RIPd StdErr Output:\n".format(i) error_logs += log - log = net["r%s" % i].getStdErr("ripngd") + log = net["r{}".format(i)].getStdErr("ripngd") if log: - error_logs += "r%s RIPngd StdErr Output:\n" % i + error_logs += "r{} RIPngd StdErr Output:\n".format(i) error_logs += log - log = net["r%s" % i].getStdErr("ospfd") + log = net["r{}".format(i)].getStdErr("ospfd") if log: - error_logs += "r%s OSPFd StdErr Output:\n" % i + error_logs += "r{} OSPFd StdErr Output:\n".format(i) error_logs += log - log = net["r%s" % i].getStdErr("ospf6d") + log = net["r{}".format(i)].getStdErr("ospf6d") if log: - error_logs += "r%s OSPF6d StdErr Output:\n" % i + error_logs += "r{} OSPF6d StdErr Output:\n".format(i) error_logs += log - log = net["r%s" % i].getStdErr("isisd") + log = net["r{}".format(i)].getStdErr("isisd") # ISIS shows debugging enabled status on StdErr # Remove these messages log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip() if log: - error_logs += "r%s ISISd StdErr Output:\n" % i + error_logs += "r{} ISISd StdErr Output:\n".format(i) error_logs += log - log = net["r%s" % i].getStdErr("bgpd") + log = net["r{}".format(i)].getStdErr("bgpd") if log: - error_logs += "r%s BGPd StdErr Output:\n" % i + error_logs += "r{} BGPd StdErr Output:\n".format(i) error_logs += log - if net["r%s" % i].daemon_available("ldpd"): - log = net["r%s" % i].getStdErr("ldpd") + if net["r{}".format(i)].daemon_available("ldpd"): + log = net["r{}".format(i)].getStdErr("ldpd") if log: - error_logs += "r%s LDPd StdErr Output:\n" % i + error_logs += "r{} LDPd StdErr Output:\n".format(i) error_logs += log log = net["r1"].getStdErr("nhrpd") @@ -251,27 +261,27 @@ def test_error_messages_daemons(): # Ignore these log = re.sub(r".*YANG model.*not embedded.*", "", log).rstrip() if log: - error_logs += "r%s NHRPd StdErr Output:\n" % i + error_logs += "r{} NHRPd StdErr Output:\n".format(i) error_logs += log log = net["r1"].getStdErr("babeld") if log: - error_logs += "r%s BABELd StdErr Output:\n" % i + error_logs += "r{} BABELd StdErr Output:\n".format(i) error_logs += log log = net["r1"].getStdErr("pbrd") if log: - error_logs += "r%s PBRd StdErr Output:\n" % i + error_logs += "r{} PBRd StdErr Output:\n".format(i) error_logs += log - log = net["r%s" % i].getStdErr("zebra") + log = net["r{}".format(i)].getStdErr("zebra") if log: - error_logs += "r%s Zebra StdErr Output:\n" % i + error_logs += "r{} Zebra StdErr Output:\n".format(i) error_logs += log if error_logs: sys.stderr.write( - "Failed check for StdErr Output on daemons:\n%s\n" % error_logs + "Failed check for StdErr Output on daemons:\n{}\n".format(error_logs) ) # Ignoring the issue if told to ignore (ie not yet fixed) @@ -317,18 +327,20 @@ def test_converge_protocols(): # Make sure that all daemons are running failures = 0 for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error print("Show that v4 routes are right\n") - v4_routesFile = "%s/r%s/ipv4_routes.ref" % (thisDir, i) + v4_routesFile = "{}/r{}/ipv4_routes.ref".format(thisDir, i) expected = ( - net["r%s" % i].cmd("sort {} 2> /dev/null".format(v4_routesFile)).rstrip() + net["r{}".format(i)] + .cmd("sort {} 2> /dev/null".format(v4_routesFile)) + .rstrip() ) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd( "vtysh -c \"show ip route\" | sed -e '/^Codes: /,/^\\s*$/d' | sort 2> /dev/null" ) @@ -344,24 +356,26 @@ def test_converge_protocols(): title2="Expected IP RoutingTable", ) if diff: - sys.stderr.write("r%s failed IP Routing table check:\n%s\n" % (i, diff)) + sys.stderr.write("r{} failed IP Routing table check:\n{}\n".format(i, diff)) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) - assert failures == 0, "IP Routing table failed for r%s\n%s" % (i, diff) + assert failures == 0, "IP Routing table failed for r{}\n{}".format(i, diff) failures = 0 print("Show that v6 routes are right\n") - v6_routesFile = "%s/r%s/ipv6_routes.ref" % (thisDir, i) + v6_routesFile = "{}/r{}/ipv6_routes.ref".format(thisDir, i) expected = ( - net["r%s" % i].cmd("sort {} 2> /dev/null".format(v6_routesFile)).rstrip() + net["r{}".format(i)] + .cmd("sort {} 2> /dev/null".format(v6_routesFile)) + .rstrip() ) expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd( "vtysh -c \"show ipv6 route\" | sed -e '/^Codes: /,/^\\s*$/d' | sort 2> /dev/null" ) @@ -377,20 +391,24 @@ def test_converge_protocols(): title2="Expected IPv6 RoutingTable", ) if diff: - sys.stderr.write("r%s failed IPv6 Routing table check:\n%s\n" % (i, diff)) + sys.stderr.write( + "r{} failed IPv6 Routing table check:\n{}\n".format(i, diff) + ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) - assert failures == 0, "IPv6 Routing table failed for r%s\n%s" % (i, diff) + assert failures == 0, "IPv6 Routing table failed for r{}\n{}".format(i, diff) def route_get_nhg_id(route_str): net = get_topogen().net - output = net["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str) + output = net["r1"].cmd( + 'vtysh -c "show ip route {} nexthop-group"'.format(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 + assert match is not None, "Nexthop Group ID not found for sharpd route {}".format( + route_str ) nhg_id = int(match.group(1)) @@ -410,7 +428,7 @@ def verify_nexthop_group(nhg_id, recursive=False, ecmp=0): while not found and count < 10: count += 1 # Verify NHG is valid/installed - output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id) + output = net["r1"].cmd('vtysh -c "show nexthop-group rib {}"'.format(nhg_id)) valid = re.search(r"Valid", output) if valid is None: found = False @@ -449,20 +467,24 @@ def verify_nexthop_group(nhg_id, recursive=False, ecmp=0): continue found = True - assert valid is not None, "Nexthop Group ID=%d not marked Valid" % nhg_id + assert valid is not None, "Nexthop Group ID={} not marked Valid".format(nhg_id) if ecmp or recursive: - assert ecmpcount is not None, "Nexthop Group ID=%d has no depends" % nhg_id + assert ecmpcount is not None, "Nexthop Group ID={} has no depends".format( + nhg_id + ) if ecmp: - assert len(depends) == ecmp, ( - "Nexthop Group ID=%d doesn't match ecmp size" % nhg_id - ) + assert ( + len(depends) == ecmp + ), "Nexthop Group ID={} doesn't match ecmp size".format(nhg_id) else: - assert len(depends) == 1, ( - "Nexthop Group ID=%d should only have one recursive depend" % nhg_id + assert ( + len(depends) == 1 + ), "Nexthop Group ID={} should only have one recursive depend".format( + nhg_id ) else: - assert installed is not None, ( - "Nexthop Group ID=%d not marked Installed" % nhg_id + assert installed is not None, "Nexthop Group ID={} not marked Installed".format( + nhg_id ) @@ -600,7 +622,7 @@ def test_nexthop_groups(): dups = [] nhg_id = route_get_nhg_id("6.6.6.1/32") while (len(dups) != 4) and count < 10: - output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id) + output = net["r1"].cmd('vtysh -c "show nexthop-group rib {}"'.format(nhg_id)) dups = re.findall(r"(via 1\.1\.1\.1)", output) if len(dups) != 4: @@ -608,9 +630,10 @@ def test_nexthop_groups(): sleep(1) # Should find 3, itself is inactive - assert len(dups) == 4, ( - "Route 6.6.6.1/32 with Nexthop Group ID=%d has wrong number of resolved nexthops" - % nhg_id + assert ( + len(dups) == 4 + ), "Route 6.6.6.1/32 with Nexthop Group ID={} has wrong number of resolved nexthops".format( + nhg_id ) ## Remove all NHG routes @@ -640,7 +663,7 @@ def test_rip_status(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = "%s/r%s/rip_status.ref" % (thisDir, i) + refTableFile = "{}/r{}/rip_status.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -649,7 +672,7 @@ def test_rip_status(): # Actual output from router actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd('vtysh -c "show ip rip status" 2> /dev/null') .rstrip() ) @@ -670,16 +693,20 @@ def test_rip_status(): # Empty string if it matches, otherwise diff contains unified diff if diff: - sys.stderr.write("r%s failed IP RIP status check:\n%s\n" % (i, diff)) + sys.stderr.write( + "r{} failed IP RIP status check:\n{}\n".format(i, diff) + ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) - assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff) + assert failures == 0, "IP RIP status failed for router r{}:\n{}".format( + i, diff + ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -697,7 +724,7 @@ def test_ripng_status(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = "%s/r%s/ripng_status.ref" % (thisDir, i) + refTableFile = "{}/r{}/ripng_status.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -706,7 +733,7 @@ def test_ripng_status(): # Actual output from router actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null') .rstrip() ) @@ -730,20 +757,19 @@ def test_ripng_status(): # Empty string if it matches, otherwise diff contains unified diff if diff: sys.stderr.write( - "r%s failed IPv6 RIPng status check:\n%s\n" % (i, diff) + "r{} failed IPv6 RIPng status check:\n{}\n".format(i, diff) ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) - assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % ( - i, - diff, + assert failures == 0, "IPv6 RIPng status failed for router r{}:\n{}".format( + i, diff ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -761,7 +787,7 @@ def test_ospfv2_interfaces(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = "%s/r%s/show_ip_ospf_interface.ref" % (thisDir, i) + refTableFile = "{}/r{}/show_ip_ospf_interface.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -770,7 +796,7 @@ def test_ospfv2_interfaces(): # Actual output from router actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd('vtysh -c "show ip ospf interface" 2> /dev/null') .rstrip() ) @@ -803,11 +829,11 @@ def test_ospfv2_interfaces(): # Empty string if it matches, otherwise diff contains unified diff if diff: sys.stderr.write( - "r%s failed SHOW IP OSPF INTERFACE check:\n%s\n" % (i, diff) + "r{} failed SHOW IP OSPF INTERFACE check:\n{}\n".format(i, diff) ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) # Ignoring the issue if told to ignore (ie not yet fixed) if failures != 0: @@ -821,11 +847,11 @@ def test_ospfv2_interfaces(): assert ( failures == 0 - ), "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff) + ), "SHOW IP OSPF INTERFACE failed for router r{}:\n{}".format(i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -843,7 +869,7 @@ def test_isis_interfaces(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = "%s/r%s/show_isis_interface_detail.ref" % (thisDir, i) + refTableFile = "{}/r{}/show_isis_interface_detail.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -852,7 +878,7 @@ def test_isis_interfaces(): # Actual output from router actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd('vtysh -c "show isis interface detail" 2> /dev/null') .rstrip() ) @@ -876,19 +902,19 @@ def test_isis_interfaces(): # Empty string if it matches, otherwise diff contains unified diff if diff: sys.stderr.write( - "r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n" % (i, diff) + "r{} failed SHOW ISIS INTERFACE DETAIL check:\n{}\n".format(i, diff) ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) assert ( failures == 0 - ), "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff) + ), "SHOW ISIS INTERFACE DETAIL failed for router r{}:\n{}".format(i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -906,7 +932,7 @@ def test_bgp_summary(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = "%s/r%s/show_ip_bgp_summary.ref" % (thisDir, i) + refTableFile = "{}/r{}/show_ip_bgp_summary.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected_original = open(refTableFile).read().rstrip() @@ -933,7 +959,7 @@ def test_bgp_summary(): ]: # Actual output from router actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd( 'vtysh -c "show ip bgp summary ' + arguments + '" 2> /dev/null' ) @@ -1049,22 +1075,19 @@ def test_bgp_summary(): # Empty string if it matches, otherwise diff contains unified diff if diff: sys.stderr.write( - "r%s failed SHOW IP BGP SUMMARY check:\n%s\n" % (i, diff) + "r{} failed SHOW IP BGP SUMMARY check:\n{}\n".format(i, diff) ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) assert ( failures == 0 - ), "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % ( - i, - diff, - ) + ), "SHOW IP BGP SUMMARY failed for router r{}:\n{}".format(i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -1082,7 +1105,7 @@ def test_bgp_ipv6_summary(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = "%s/r%s/show_bgp_ipv6_summary.ref" % (thisDir, i) + refTableFile = "{}/r{}/show_bgp_ipv6_summary.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -1091,7 +1114,7 @@ def test_bgp_ipv6_summary(): # Actual output from router actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null') .rstrip() ) @@ -1147,20 +1170,19 @@ def test_bgp_ipv6_summary(): # Empty string if it matches, otherwise diff contains unified diff if diff: sys.stderr.write( - "r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n" % (i, diff) + "r{} failed SHOW BGP IPv6 SUMMARY check:\n{}\n".format(i, diff) ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) - assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % ( - i, - diff, - ) + assert ( + failures == 0 + ), "SHOW BGP IPv6 SUMMARY failed for router r{}:\n{}".format(i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -1177,11 +1199,13 @@ def test_nht(): thisDir = os.path.dirname(os.path.realpath(__file__)) for i in range(1, 2): - nhtFile = "%s/r%s/ip_nht.ref" % (thisDir, i) + nhtFile = "{}/r{}/ip_nht.ref".format(thisDir, i) expected = open(nhtFile).read().rstrip() expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) - actual = net["r%s" % i].cmd('vtysh -c "show ip nht" 2> /dev/null').rstrip() + actual = ( + net["r{}".format(i)].cmd('vtysh -c "show ip nht" 2> /dev/null').rstrip() + ) actual = re.sub(r"fd [0-9]+", "fd XX", actual) actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) @@ -1193,15 +1217,17 @@ def test_nht(): ) if diff: - assert 0, "r%s failed ip nht check:\n%s\n" % (i, diff) + assert 0, "r{} failed ip nht check:\n{}\n".format(i, diff) else: print("show ip nht is ok\n") - nhtFile = "%s/r%s/ipv6_nht.ref" % (thisDir, i) + nhtFile = "{}/r{}/ipv6_nht.ref".format(thisDir, i) expected = open(nhtFile).read().rstrip() expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) - actual = net["r%s" % i].cmd('vtysh -c "show ipv6 nht" 2> /dev/null').rstrip() + actual = ( + net["r{}".format(i)].cmd('vtysh -c "show ipv6 nht" 2> /dev/null').rstrip() + ) actual = re.sub(r"fd [0-9]+", "fd XX", actual) actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) @@ -1213,7 +1239,7 @@ def test_nht(): ) if diff: - assert 0, "r%s failed ipv6 nht check:\n%s\n" % (i, diff) + assert 0, "r{} failed ipv6 nht check:\n{}\n".format(i, diff) else: print("show ipv6 nht is ok\n") @@ -1233,7 +1259,7 @@ def test_bgp_ipv4(): diffresult = {} for i in range(1, 2): success = 0 - for refTableFile in glob.glob("%s/r%s/show_bgp_ipv4*.ref" % (thisDir, i)): + for refTableFile in glob.glob("{}/r{}/show_bgp_ipv4*.ref".format(thisDir, i)): if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -1242,7 +1268,9 @@ def test_bgp_ipv4(): # Actual output from router actual = ( - net["r%s" % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip() + net["r{}".format(i)] + .cmd('vtysh -c "show bgp ipv4" 2> /dev/null') + .rstrip() ) # Remove summary line (changed recently) actual = re.sub(r"Total number.*", "", actual) @@ -1264,24 +1292,26 @@ def test_bgp_ipv4(): diffresult[refTableFile] = diff else: success = 1 - print("template %s matched: r%s ok" % (refTableFile, i)) + print("template {} matched: r{} ok".format(refTableFile, i)) break if not success: resultstr = "No template matched.\n" for f in diffresult.keys(): - resultstr += "template %s: r%s failed SHOW BGP IPv4 check:\n%s\n" % ( - f, - i, - diffresult[f], + resultstr += ( + "template {}: r{} failed SHOW BGP IPv4 check:\n{}\n".format( + f, + i, + diffresult[f], + ) ) raise AssertionError( - "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr) + "SHOW BGP IPv4 failed for router r{}:\n{}".format(i, resultstr) ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -1300,7 +1330,7 @@ def test_bgp_ipv6(): diffresult = {} for i in range(1, 2): success = 0 - for refTableFile in glob.glob("%s/r%s/show_bgp_ipv6*.ref" % (thisDir, i)): + for refTableFile in glob.glob("{}/r{}/show_bgp_ipv6*.ref".format(thisDir, i)): if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -1309,7 +1339,9 @@ def test_bgp_ipv6(): # Actual output from router actual = ( - net["r%s" % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip() + net["r{}".format(i)] + .cmd('vtysh -c "show bgp ipv6" 2> /dev/null') + .rstrip() ) # Remove summary line (changed recently) actual = re.sub(r"Total number.*", "", actual) @@ -1331,23 +1363,25 @@ def test_bgp_ipv6(): diffresult[refTableFile] = diff else: success = 1 - print("template %s matched: r%s ok" % (refTableFile, i)) + print("template {} matched: r{} ok".format(refTableFile, i)) if not success: resultstr = "No template matched.\n" for f in diffresult.keys(): - resultstr += "template %s: r%s failed SHOW BGP IPv6 check:\n%s\n" % ( - f, - i, - diffresult[f], + resultstr += ( + "template {}: r{} failed SHOW BGP IPv6 check:\n{}\n".format( + f, + i, + diffresult[f], + ) ) raise AssertionError( - "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr) + "SHOW BGP IPv6 failed for router r{}:\n{}".format(i, resultstr) ) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -1364,13 +1398,15 @@ def test_route_map(): print("*******************************************************\n") failures = 0 for i in range(1, 2): - refroutemap = "%s/r%s/show_route_map.ref" % (thisDir, i) + refroutemap = "{}/r{}/show_route_map.ref".format(thisDir, i) if os.path.isfile(refroutemap): expected = open(refroutemap).read().rstrip() expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1) actual = ( - net["r%s" % i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip() + net["r{}".format(i)] + .cmd('vtysh -c "show route-map" 2> /dev/null') + .rstrip() ) actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1) @@ -1383,15 +1419,15 @@ def test_route_map(): if diff: sys.stderr.write( - "r%s failed show route-map command Check:\n%s\n" % (i, diff) + "r{} failed show route-map command Check:\n{}\n".format(i, diff) ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) assert ( failures == 0 - ), "Show route-map command failed for router r%s:\n%s" % (i, diff) + ), "Show route-map command failed for router r{}:\n{}".format(i, diff) def test_nexthop_groups_with_route_maps(): @@ -1418,28 +1454,34 @@ def test_nexthop_groups_with_route_maps(): 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 + 'vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src {}"'.format( + 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) + net["r1"].cmd( + 'vtysh -c "sharp install routes {} nexthop-group test 1"'.format(route_str) + ) - verify_route_nexthop_group("%s/32" % route_str) + verify_route_nexthop_group("{}/32".format(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" % ( + output = net["r1"].cmd("ip route show {}/32".format(route_str)) + match = re.search(r"src {}".format(src_str), output) + assert match is not None, "Route {}/32 not installed with src {}".format( 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 "sharp remove routes {} 1"'.format(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 + 'vtysh -c "c t" -c "no route-map NH-SRC permit 111" # -c "set src {}"'.format( + src_str + ) ) net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"') @@ -1449,7 +1491,9 @@ def test_nexthop_groups_with_route_maps(): 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 + 'vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit {}/32"'.format( + permit_route_str + ) ) net["r1"].cmd( 'vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"' @@ -1459,35 +1503,42 @@ def test_nexthop_groups_with_route_maps(): # This route should be permitted net["r1"].cmd( - 'vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str + 'vtysh -c "sharp install routes {} nexthop-group test 1"'.format( + permit_route_str + ) ) - verify_route_nexthop_group("%s/32" % permit_route_str) + verify_route_nexthop_group("{}/32".format(permit_route_str)) # This route should be denied net["r1"].cmd( - 'vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str + 'vtysh -c "sharp install routes {} nexthop-group test 1"'.format(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) + output = net["r1"].cmd('vtysh -c "show nexthop-group rib {}"'.format(nhg_id)) match = re.search(r"Valid", output) - assert match is None, "Nexthop Group ID=%d should not be marked Valid" % nhg_id + assert match is None, "Nexthop Group ID={} should not be marked Valid".format( + nhg_id + ) match = re.search(r"Installed", output) - assert match is None, "Nexthop Group ID=%d should not be marked Installed" % nhg_id + assert match is None, "Nexthop Group ID={} should not be marked Installed".format( + 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 "sharp remove routes {} 1"'.format(permit_route_str)) + net["r1"].cmd('vtysh -c "sharp remove routes {} 1"'.format(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 + 'vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit {}/32"'.format( + permit_route_str + ) ) @@ -1550,7 +1601,7 @@ def test_mpls_interfaces(): print("******************************************\n") failures = 0 for i in range(1, 2): - refTableFile = "%s/r%s/show_mpls_ldp_interface.ref" % (thisDir, i) + refTableFile = "{}/r{}/show_mpls_ldp_interface.ref".format(thisDir, i) if os.path.isfile(refTableFile): # Read expected result from file expected = open(refTableFile).read().rstrip() @@ -1559,7 +1610,7 @@ def test_mpls_interfaces(): # Actual output from router actual = ( - net["r%s" % i] + net["r{}".format(i)] .cmd('vtysh -c "show mpls ldp interface" 2> /dev/null') .rstrip() ) @@ -1579,22 +1630,22 @@ def test_mpls_interfaces(): # Empty string if it matches, otherwise diff contains unified diff if diff: sys.stderr.write( - "r%s failed MPLS LDP Interface status Check:\n%s\n" % (i, diff) + "r{} failed MPLS LDP Interface status Check:\n{}\n".format(i, diff) ) failures += 1 else: - print("r%s ok" % i) + print("r{} ok".format(i)) if failures > 0: fatal_error = "MPLS LDP Interface status failed" assert ( failures == 0 - ), "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff) + ), "MPLS LDP Interface status failed for router r{}:\n{}".format(i, diff) # Make sure that all daemons are running for i in range(1, 2): - fatal_error = net["r%s" % i].checkRouterRunning() + fatal_error = net["r{}".format(i)].checkRouterRunning() assert fatal_error == "", fatal_error @@ -1707,8 +1758,8 @@ def test_shutdown_check_memleak(): thisDir = os.path.dirname(os.path.realpath(__file__)) for i in range(1, 2): - net["r%s" % i].stopRouter() - net["r%s" % i].report_memory_leaks( + net["r{}".format(i)].stopRouter() + net["r{}".format(i)].report_memory_leaks( os.environ.get("TOPOTESTS_CHECK_MEMLEAK"), os.path.basename(__file__) ) From 1f5446d2fc83e2eba9e693bc5f439723d5f48865 Mon Sep 17 00:00:00 2001 From: zhou-run <166502045+zhou-run@users.noreply.github.com> Date: Mon, 27 May 2024 11:08:53 +0800 Subject: [PATCH 155/472] isisd: When operating multiple areas, the system ID behaves abnormally. When clearing the net in one of the areas, the system ID is unconditionally cleared, even if the net does not include the current system ID. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: When operating multiple areas, the system ID behaves abnormally. When deleting one of the areas, even if the net under the area includes the current system ID, the system ID still remains. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: fix frrbot styling issues found fix frrbot styling issues found Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: fix frrbot styling issues found fix frrbot styling issues found Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: Resolve compilation issues. The higher version updates 'struct area_addr' to 'struct iso_address'. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: fix frrbot styling issues found fix frrbot styling issues found Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> --- isisd/isis_nb_config.c | 7 +++++-- isisd/isisd.c | 10 ++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 763b8b73d270..0a343ddc2966 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -252,11 +252,12 @@ int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args) return NB_ERR_INCONSISTENCY; listnode_delete(area->area_addrs, addrp); - XFREE(MTYPE_ISIS_AREA_ADDR, addrp); /* * Last area address - reset the SystemID for this router */ - if (listcount(area->area_addrs) == 0) { + if (!memcmp(addrp->area_addr + addrp->addr_len, area->isis->sysid, + ISIS_SYS_ID_LEN) && + listcount(area->area_addrs) == 0) { for (ALL_LIST_ELEMENTS_RO(area->circuit_list, cnode, circuit)) for (lvl = IS_LEVEL_1; lvl <= IS_LEVEL_2; ++lvl) { if (circuit->u.bc.is_dr[lvl - 1]) @@ -268,6 +269,8 @@ int isis_instance_area_address_destroy(struct nb_cb_destroy_args *args) zlog_debug("Router has no SystemID"); } + XFREE(MTYPE_ISIS_AREA_ADDR, addrp); + return NB_OK; } diff --git a/isisd/isisd.c b/isisd/isisd.c index 382a6aa3be4d..2ed49398394c 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -496,6 +496,7 @@ void isis_area_destroy(struct isis_area *area) { struct listnode *node, *nnode; struct isis_circuit *circuit; + struct iso_address *addr; QOBJ_UNREG(area); @@ -545,6 +546,15 @@ void isis_area_destroy(struct isis_area *area) if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) isis_redist_area_finish(area); + if (listcount(area->area_addrs) > 0) { + addr = listgetdata(listhead(area->area_addrs)); + if (!memcmp(addr->area_addr + addr->addr_len, area->isis->sysid, + ISIS_SYS_ID_LEN)) { + memset(area->isis->sysid, 0, ISIS_SYS_ID_LEN); + area->isis->sysid_set = 0; + } + } + list_delete(&area->area_addrs); for (int i = SPF_PREFIX_PRIO_CRITICAL; i <= SPF_PREFIX_PRIO_MEDIUM; From 171d2583d0373b456335477dea6688d2e9e95db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Kwa=C5=9Bny?= Date: Mon, 27 May 2024 11:03:30 +0200 Subject: [PATCH 156/472] bgpd: fixed failing remove of vrf if there is a stale l3vni Problem statement: ================== When a vrf is deleted from the kernel, before its removed from the FRR config, zebra gets to delete the the vrf and assiciated state. It does so by sending a request to delete the l3 vni associated with the vrf followed by a request to delete the vrf itself. 2023/10/06 06:22:18 ZEBRA: [JAESH-BABB8] Send L3_VNI_DEL 1001 VRF testVRF1001 to bgp 2023/10/06 06:22:18 ZEBRA: [XC3P3-1DG4D] MESSAGE: ZEBRA_VRF_DELETE testVRF1001 The zebra client communication is asynchronous and about 1/5 cases the bgp client process them in a different order. 2023/10/06 06:22:18 BGP: [VP18N-HB5R6] VRF testVRF1001(766) is to be deleted. 2023/10/06 06:22:18 BGP: [RH4KQ-X3CYT] VRF testVRF1001(766) is to be disabled. 2023/10/06 06:22:18 BGP: [X8ZE0-9TS5H] VRF disable testVRF1001 id 766 2023/10/06 06:22:18 BGP: [X67AQ-923PR] Deregistering VRF 766 2023/10/06 06:22:18 BGP: [K52W0-YZ4T8] VRF Deletion: testVRF1001(4294967295) .. and a bit later : 2023/10/06 06:22:18 BGP: [MRXGD-9MHNX] DJERNAES: process L3VNI 1001 DEL 2023/10/06 06:22:18 BGP: [NCEPE-BKB1G][EC 33554467] Cannot process L3VNI 1001 Del - Could not find BGP instance When the bgp vrf config is removed later it fails on the sanity check if l3vni is removed. if (bgp->l3vni) { vty_out(vty, "%% Please unconfigure l3vni %u\n", bgp->l3vni); return CMD_WARNING_CONFIG_FAILED; } Solution: ========= The solution is to make bgp cleanup the l3vni a bgp instance is going down. The fix: ======== The fix is to add a function in bgp_evpn.c to be responsible for for deleting the local vni, if it should be needed, and call the function from bgp_instance_down(). Testing: ======== Created a test, which can run in container lab that remove the vrf on the host before removing the vrf and the bgp config form frr. Running this test in a loop trigger the problem 18 times of 100 runs. After the fix it did not fail. To verify the fix a log message (which is not in the code any longer) were used when we had a stale l3vni and needed to call bgp_evpn_local_l3vni_del() to do the cleanup. This were hit 20 times in 100 test runs. Signed-off-by: Kacper Kwasny bgpd: braces {} are not necessary for single line block Signed-off-by: Kacper Kwasny --- bgpd/bgp_evpn.c | 11 +++++++++++ bgpd/bgp_evpn.h | 1 + bgpd/bgpd.c | 3 +++ 3 files changed, 15 insertions(+) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index ce9666d6115a..495b60853f4f 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -6971,6 +6971,17 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id) return 0; } +/* + * When bgp instance goes down also clean up what might have been left over + * from evpn. + */ +void bgp_evpn_instance_down(struct bgp *bgp) +{ + /* If we have a stale local vni, delete it */ + if (bgp->l3vni) + bgp_evpn_local_l3vni_del(bgp->l3vni, bgp->vrf_id); +} + /* * Handle del of a local VNI. */ diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 11a6f45dd090..ff2cb6ea91d0 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -153,6 +153,7 @@ extern int bgp_evpn_local_l3vni_add(vni_t vni, vrf_id_t vrf_id, struct in_addr originator_ip, int filter, ifindex_t svi_ifindex, bool is_anycast_mac); extern int bgp_evpn_local_l3vni_del(vni_t vni, vrf_id_t vrf_id); +extern void bgp_evpn_instance_down(struct bgp *bgp); extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni); extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, struct in_addr originator_ip, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 09e64cf9ec31..a804f095fa10 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3872,6 +3872,9 @@ void bgp_instance_down(struct bgp *bgp) struct listnode *node; struct listnode *next; + /* Cleanup evpn instance state */ + bgp_evpn_instance_down(bgp); + /* Stop timers. */ if (bgp->t_rmap_def_originate_eval) EVENT_OFF(bgp->t_rmap_def_originate_eval); From 4d06e27569ae09cfb44cfa07b2c8d027ecf0fd72 Mon Sep 17 00:00:00 2001 From: Andrew Cooks Date: Tue, 21 May 2024 09:47:20 +1000 Subject: [PATCH 157/472] ospf6d: replace OSPF6_LSA_HEADER_END macro Replacing the macro with an inline function allows the compiler to check the parameter type. Use the replacement function consistently to reduce the number of open coded pointer cast plus offset calculations. use tools/indent.py to reformat all occurences of its use. Signed-off-by: Andrew Cooks --- ospf6d/ospf6_abr.c | 37 +++++++++++++------------------- ospf6d/ospf6_asbr.c | 27 +++++++++++------------- ospf6d/ospf6_gr.c | 4 +--- ospf6d/ospf6_intra.c | 50 +++++++++++++++++--------------------------- ospf6d/ospf6_lsa.c | 10 ++++----- ospf6d/ospf6_lsa.h | 7 ++++++- ospf6d/ospf6_lsdb.c | 5 ++--- ospf6d/ospf6_nssa.c | 27 ++++++++++-------------- ospf6d/ospf6_spf.c | 20 +++++++++--------- 9 files changed, 81 insertions(+), 106 deletions(-) diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index d3ff759d33ed..aec947a6988b 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -553,9 +553,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, lsa_header = (struct ospf6_lsa_header *)buffer; if (route->type == OSPF6_DEST_TYPE_ROUTER) { - router_lsa = (struct ospf6_inter_router_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + router_lsa = (struct ospf6_inter_router_lsa *) + ospf6_lsa_header_end(lsa_header); p = (caddr_t)router_lsa + sizeof(struct ospf6_inter_router_lsa); /* Fill Inter-Area-Router-LSA */ @@ -566,9 +565,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, router_lsa->router_id = ADV_ROUTER_IN_PREFIX(&route->prefix); type = htons(OSPF6_LSTYPE_INTER_ROUTER); } else { - prefix_lsa = (struct ospf6_inter_prefix_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + prefix_lsa = (struct ospf6_inter_prefix_lsa *) + ospf6_lsa_header_end(lsa_header); p = (caddr_t)prefix_lsa + sizeof(struct ospf6_inter_prefix_lsa); /* Fill Inter-Area-Prefix-LSA */ @@ -1018,9 +1016,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) oa->name); } - prefix_lsa = - (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); + prefix_lsa = (struct ospf6_inter_prefix_lsa *) + ospf6_lsa_header_end(lsa->header); prefix.family = AF_INET6; prefix.prefixlen = prefix_lsa->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, prefix_lsa, @@ -1039,11 +1036,9 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) oa->name); } - router_lsa = - (struct ospf6_inter_router_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); - ospf6_linkstate_prefix(router_lsa->router_id, htonl(0), - &prefix); + router_lsa = (struct ospf6_inter_router_lsa *) + ospf6_lsa_header_end(lsa->header); + ospf6_linkstate_prefix(router_lsa->router_id, htonl(0), &prefix); if (is_debug) inet_ntop(AF_INET, &router_lsa->router_id, buf, sizeof(buf)); @@ -1433,9 +1428,8 @@ static char *ospf6_inter_area_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, char tbuf[16]; if (lsa != NULL) { - prefix_lsa = - (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); + prefix_lsa = (struct ospf6_inter_prefix_lsa *) + ospf6_lsa_header_end(lsa->header); ospf6_prefix_in6_addr(&in6, prefix_lsa, &prefix_lsa->prefix); if (buf) { @@ -1457,7 +1451,7 @@ static int ospf6_inter_area_prefix_lsa_show(struct vty *vty, struct ospf6_inter_prefix_lsa *prefix_lsa; char buf[INET6_ADDRSTRLEN]; - prefix_lsa = (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END( + prefix_lsa = (struct ospf6_inter_prefix_lsa *)ospf6_lsa_header_end( lsa->header); if (use_json) { @@ -1494,9 +1488,8 @@ static char *ospf6_inter_area_router_lsa_get_prefix_str(struct ospf6_lsa *lsa, struct ospf6_inter_router_lsa *router_lsa; if (lsa != NULL) { - router_lsa = - (struct ospf6_inter_router_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); + router_lsa = (struct ospf6_inter_router_lsa *) + ospf6_lsa_header_end(lsa->header); if (buf) @@ -1514,7 +1507,7 @@ static int ospf6_inter_area_router_lsa_show(struct vty *vty, struct ospf6_inter_router_lsa *router_lsa; char buf[64]; - router_lsa = (struct ospf6_inter_router_lsa *)OSPF6_LSA_HEADER_END( + router_lsa = (struct ospf6_inter_router_lsa *)ospf6_lsa_header_end( lsa->header); ospf6_options_printbuf(router_lsa->options, buf, sizeof(buf)); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 701704cdc80d..2065527c9377 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -102,9 +102,8 @@ struct ospf6_lsa *ospf6_as_external_lsa_originate(struct ospf6_route *route, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - as_external_lsa = (struct ospf6_as_external_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + as_external_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( + lsa_header); p = (caddr_t)((caddr_t)as_external_lsa + sizeof(struct ospf6_as_external_lsa)); @@ -217,7 +216,7 @@ static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa) if (!lsa) return 0; - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( lsa->header); if (!CHECK_FLAG(external->bits_metric, OSPF6_ASBR_BIT_T)) @@ -521,7 +520,7 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa) type = ntohs(lsa->header->type); oa = lsa->lsdb->data; - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( lsa->header); if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) @@ -726,7 +725,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa, int type; bool debug = false; - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( lsa->header); if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) || (IS_OSPF6_DEBUG_NSSA)) @@ -2425,7 +2424,7 @@ static char *ospf6_as_external_lsa_get_prefix_str(struct ospf6_lsa *lsa, char tbuf[16]; if (lsa) { - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( lsa->header); if (pos == 0) { @@ -2460,7 +2459,7 @@ static int ospf6_as_external_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, char buf[64]; assert(lsa->header); - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( lsa->header); /* bits */ @@ -3028,8 +3027,8 @@ ospf6_originate_summary_lsa(struct ospf6 *ospf6, return; } - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END - (aggr_lsa->header); + external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( + aggr_lsa->header); metric = (unsigned long)OSPF6_ASBR_METRIC(external); tag = ospf6_as_external_lsa_get_tag(aggr_lsa); mtype = CHECK_FLAG(external->bits_metric, @@ -3177,8 +3176,7 @@ ospf6_handle_external_aggr_modify(struct ospf6 *ospf6, return OSPF6_FAILURE; } - asel = (struct ospf6_as_external_lsa *) - OSPF6_LSA_HEADER_END(lsa->header); + asel = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end(lsa->header); metric = (unsigned long)OSPF6_ASBR_METRIC(asel); tag = ospf6_as_external_lsa_get_tag(lsa); mtype = CHECK_FLAG(asel->bits_metric, @@ -3367,9 +3365,8 @@ static void ospf6_handle_aggregated_exnl_rt(struct ospf6 *ospf6, lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL), htonl(info->id), ospf6->router_id, ospf6->lsdb); if (lsa) { - ext_lsa = (struct ospf6_as_external_lsa - *)((char *)(lsa->header) - + sizeof(struct ospf6_lsa_header)); + ext_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( + lsa->header); if (rt->prefix.prefixlen != ext_lsa->prefix.prefix_length) return; diff --git a/ospf6d/ospf6_gr.c b/ospf6d/ospf6_gr.c index 34cb9706bd38..ab119a4ea4eb 100644 --- a/ospf6d/ospf6_gr.c +++ b/ospf6d/ospf6_gr.c @@ -54,9 +54,7 @@ static int ospf6_gr_lsa_originate(struct ospf6_interface *oi, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - grace_lsa = - (struct ospf6_grace_lsa *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + grace_lsa = (struct ospf6_grace_lsa *)ospf6_lsa_header_end(lsa_header); /* Put grace period. */ grace_lsa->tlv_period.header.type = htons(GRACE_PERIOD_TYPE); diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index cb036752e8a3..48a7012adac7 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -242,9 +242,7 @@ void ospf6_router_lsa_originate(struct event *thread) memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - router_lsa = - (struct ospf6_router_lsa *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + router_lsa = (struct ospf6_router_lsa *)ospf6_lsa_header_end(lsa_header); ospf6_router_lsa_options_set(oa, router_lsa); @@ -305,10 +303,8 @@ void ospf6_router_lsa_originate(struct event *thread) /* Reset Buffer to fill next Router LSA */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - router_lsa = - (struct ospf6_router_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + router_lsa = (struct ospf6_router_lsa *) + ospf6_lsa_header_end(lsa_header); ospf6_router_lsa_options_set(oa, router_lsa); @@ -568,16 +564,14 @@ void ospf6_network_lsa_originate(struct event *thread) memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; network_lsa = - (struct ospf6_network_lsa *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + (struct ospf6_network_lsa *)ospf6_lsa_header_end(lsa_header); /* Collect the interface's Link-LSAs to describe network's optional capabilities */ type = htons(OSPF6_LSTYPE_LINK); for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) { - link_lsa = (struct ospf6_link_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end( + lsa->header); network_lsa->options[0] |= link_lsa->options[0]; network_lsa->options[1] |= link_lsa->options[1]; network_lsa->options[2] |= link_lsa->options[2]; @@ -800,8 +794,7 @@ void ospf6_link_lsa_originate(struct event *thread) /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end(lsa_header); /* Fill Link-LSA */ link_lsa->priority = oi->priority; @@ -1042,9 +1035,8 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread) /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( + lsa_header); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER); @@ -1159,10 +1151,8 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread) /* Prepare next buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - intra_prefix_lsa = - (struct ospf6_intra_prefix_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) + ospf6_lsa_header_end(lsa_header); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER); @@ -1269,9 +1259,8 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread) /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - intra_prefix_lsa = (struct ospf6_intra_prefix_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( + lsa_header); /* Fill Intra-Area-Prefix-LSA */ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_NETWORK); @@ -1668,7 +1657,8 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa, } intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *) - OSPF6_LSA_HEADER_END(lsa->header); + ospf6_lsa_header_end( + lsa->header); if (intra_prefix_lsa->ref_adv_router == oa->ospf6->router_id) { @@ -1749,9 +1739,8 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa) oa = OSPF6_AREA(lsa->lsdb->data); - intra_prefix_lsa = - (struct ospf6_intra_prefix_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( + lsa->header); if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_ROUTER) || intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_NETWORK)) ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router, @@ -1979,9 +1968,8 @@ void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa) oa = OSPF6_AREA(lsa->lsdb->data); - intra_prefix_lsa = - (struct ospf6_intra_prefix_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); + intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end( + lsa->header); prefix_num = ntohs(intra_prefix_lsa->prefix_num); start = (caddr_t)intra_prefix_lsa diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index bc39579653c0..24643164c5fd 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -63,10 +63,10 @@ struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa) static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, json_object *json_obj, bool use_json) { - uint8_t *start, *end, *current; + char *start, *end, *current; - start = (uint8_t *)lsa->header + sizeof(struct ospf6_lsa_header); - end = (uint8_t *)lsa->header + ntohs(lsa->header->length); + start = ospf6_lsa_header_end(lsa->header); + end = (char *)lsa->header + ntohs(lsa->header->length); if (use_json) { json_object_string_add(json_obj, "lsaType", "unknown"); @@ -234,8 +234,8 @@ int ospf6_lsa_is_changed(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2) if (length <= 0) return 0; - return memcmp(OSPF6_LSA_HEADER_END(lsa1->header), - OSPF6_LSA_HEADER_END(lsa2->header), length); + return memcmp(ospf6_lsa_header_end(lsa1->header), + ospf6_lsa_header_end(lsa2->header), length); } /* ospf6 age functions */ diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index c9ac27df88e9..0fa632449f59 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -87,10 +87,15 @@ struct ospf6_lsa_header { uint16_t length; /* LSA length */ }; -#define OSPF6_LSA_HEADER_END(h) ((caddr_t)(h) + sizeof(struct ospf6_lsa_header)) #define OSPF6_LSA_SIZE(h) (ntohs(((struct ospf6_lsa_header *)(h))->length)) #define OSPF6_LSA_END(h) \ ((caddr_t)(h) + ntohs(((struct ospf6_lsa_header *)(h))->length)) + +static inline char *ospf6_lsa_header_end(struct ospf6_lsa_header *header) +{ + return (char *)header + sizeof(struct ospf6_lsa_header); +} + #define OSPF6_LSA_IS_TYPE(t, L) \ ((L)->header->type == htons(OSPF6_LSTYPE_##t) ? 1 : 0) #define OSPF6_LSA_IS_SAME(L1, L2) \ diff --git a/ospf6d/ospf6_lsdb.c b/ospf6d/ospf6_lsdb.c index c9cbdf8e928b..9aca5550a671 100644 --- a/ospf6d/ospf6_lsdb.c +++ b/ospf6d/ospf6_lsdb.c @@ -229,9 +229,8 @@ struct ospf6_lsa *ospf6_find_inter_prefix_lsa(struct ospf6 *ospf6, struct ospf6_inter_prefix_lsa *prefix_lsa; struct prefix prefix; - prefix_lsa = - (struct ospf6_inter_prefix_lsa *)OSPF6_LSA_HEADER_END( - lsa->header); + prefix_lsa = (struct ospf6_inter_prefix_lsa *) + ospf6_lsa_header_end(lsa->header); prefix.family = AF_INET6; prefix.prefixlen = prefix_lsa->prefix.prefix_length; ospf6_prefix_in6_addr(&prefix.u.prefix6, prefix_lsa, diff --git a/ospf6d/ospf6_nssa.c b/ospf6d/ospf6_nssa.c index 405ae9052893..ea2be20cf355 100644 --- a/ospf6d/ospf6_nssa.c +++ b/ospf6d/ospf6_nssa.c @@ -52,10 +52,8 @@ static int ospf6_abr_nssa_am_elected(struct ospf6_area *oa) /* Verify all the router LSA to compare the router ID */ for (ALL_LSDB_TYPED(oa->lsdb, type, lsa)) { - - router_lsa = (struct ospf6_router_lsa - *)((caddr_t)lsa->header - + sizeof(struct ospf6_lsa_header)); + router_lsa = (struct ospf6_router_lsa *)ospf6_lsa_header_end( + lsa->header); /* ignore non-ABR routers */ if (!CHECK_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B)) @@ -416,7 +414,7 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area, } /* find the translated Type-5 for this Type-7 */ - nssa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + nssa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( type7->header); prefix.family = AF_INET6; prefix.prefixlen = nssa->prefix.prefix_length; @@ -437,12 +435,10 @@ static struct ospf6_lsa *ospf6_lsa_translated_nssa_new(struct ospf6_area *area, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - extnew = (struct ospf6_as_external_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); - ext = (struct ospf6_as_external_lsa - *)((caddr_t)(type7->header) - + sizeof(struct ospf6_lsa_header)); + extnew = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( + lsa_header); + ext = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( + type7->header); old_ptr = (caddr_t)((caddr_t)ext + sizeof(struct ospf6_as_external_lsa)); new_ptr = (caddr_t)((caddr_t)extnew @@ -550,7 +546,7 @@ struct ospf6_lsa *ospf6_translated_nssa_refresh(struct ospf6_area *area, "%s: try to find translated Type-5 LSA for %s", __func__, type7->name); - ext_lsa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + ext_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( type7->header); prefix.family = AF_INET6; prefix.prefixlen = ext_lsa->prefix.prefix_length; @@ -618,7 +614,7 @@ static void ospf6_abr_translate_nssa(struct ospf6_area *area, struct ospf6 *ospf6; ospf6 = area->ospf6; - nssa_lsa = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + nssa_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( lsa->header); if (!CHECK_FLAG(nssa_lsa->prefix.prefix_options, @@ -1244,9 +1240,8 @@ void ospf6_nssa_lsa_originate(struct ospf6_route *route, /* prepare buffer */ memset(buffer, 0, sizeof(buffer)); lsa_header = (struct ospf6_lsa_header *)buffer; - as_external_lsa = (struct ospf6_as_external_lsa - *)((caddr_t)lsa_header - + sizeof(struct ospf6_lsa_header)); + as_external_lsa = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( + lsa_header); p = (caddr_t)((caddr_t)as_external_lsa + sizeof(struct ospf6_as_external_lsa)); diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index e39ae504a238..93120df99915 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -130,10 +130,10 @@ static struct ospf6_vertex *ospf6_vertex_create(struct ospf6_lsa *lsa) v->lsa = lsa; /* capability bits + options */ - v->capability = *(uint8_t *)(OSPF6_LSA_HEADER_END(lsa->header)); - v->options[0] = *(uint8_t *)(OSPF6_LSA_HEADER_END(lsa->header) + 1); - v->options[1] = *(uint8_t *)(OSPF6_LSA_HEADER_END(lsa->header) + 2); - v->options[2] = *(uint8_t *)(OSPF6_LSA_HEADER_END(lsa->header) + 3); + v->capability = *(uint8_t *)(ospf6_lsa_header_end(lsa->header)); + v->options[0] = *(uint8_t *)(ospf6_lsa_header_end(lsa->header) + 1); + v->options[1] = *(uint8_t *)(ospf6_lsa_header_end(lsa->header) + 2); + v->options[2] = *(uint8_t *)(ospf6_lsa_header_end(lsa->header) + 3); v->nh_list = list_new(); v->nh_list->cmp = (int (*)(void *, void *))ospf6_nexthop_cmp; @@ -206,7 +206,7 @@ static char *ospf6_lsdesc_backlink(struct ospf6_lsa *lsa, caddr_t lsdesc, size = (OSPF6_LSA_IS_TYPE(ROUTER, lsa) ? sizeof(struct ospf6_router_lsdesc) : sizeof(struct ospf6_network_lsdesc)); - for (backlink = OSPF6_LSA_HEADER_END(lsa->header) + 4; + for (backlink = ospf6_lsa_header_end(lsa->header) + 4; backlink + size <= OSPF6_LSA_END(lsa->header); backlink += size) { assert(!(OSPF6_LSA_IS_TYPE(NETWORK, lsa) && VERTEX_IS_TYPE(NETWORK, v))); @@ -290,7 +290,7 @@ static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v, != lsa->header->id) continue; - link_lsa = (struct ospf6_link_lsa *)OSPF6_LSA_HEADER_END( + link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end( lsa->header); if (IS_OSPF6_DEBUG_SPF(PROCESS)) { inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, @@ -510,7 +510,7 @@ void ospf6_spf_calculation(uint32_t router_id, size = (VERTEX_IS_TYPE(ROUTER, v) ? sizeof(struct ospf6_router_lsdesc) : sizeof(struct ospf6_network_lsdesc)); - for (lsdesc = OSPF6_LSA_HEADER_END(v->lsa->header) + 4; + for (lsdesc = ospf6_lsa_header_end(v->lsa->header) + 4; lsdesc + size <= OSPF6_LSA_END(v->lsa->header); lsdesc += size) { lsa = ospf6_lsdesc_lsa(lsdesc, v); @@ -1063,7 +1063,7 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, } if (IS_OSPF6_DEBUG_SPF(PROCESS)) { - lsd = OSPF6_LSA_HEADER_END(rtr_lsa->header) + 4; + lsd = ospf6_lsa_header_end(rtr_lsa->header) + 4; interface_id = ROUTER_LSDESC_GET_IFID(lsd); inet_ntop(AF_INET, &interface_id, ifbuf, sizeof(ifbuf)); zlog_debug( @@ -1074,7 +1074,7 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, /* Append Next Link State ID LSA */ lsa_header = rtr_lsa->header; - memcpy(new_header, (OSPF6_LSA_HEADER_END(rtr_lsa->header) + 4), + memcpy(new_header, (ospf6_lsa_header_end(rtr_lsa->header) + 4), (ntohs(lsa_header->length) - lsa_length)); new_header += (ntohs(lsa_header->length) - lsa_length); num_lsa--; @@ -1137,7 +1137,7 @@ int ospf6_ase_calculate_route(struct ospf6 *ospf6, struct ospf6_lsa *lsa, return 0; } - external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END( + external = (struct ospf6_as_external_lsa *)ospf6_lsa_header_end( lsa->header); prefix.family = AF_INET6; prefix.prefixlen = external->prefix.prefix_length; From 954f2ac5819cd943d592d6bf42125146e74c6c1c Mon Sep 17 00:00:00 2001 From: Andrew Cooks Date: Tue, 21 May 2024 10:39:47 +1000 Subject: [PATCH 158/472] ospf6d: replace OSPF6_LSA_END with ospf6_lsa_end Replacing the macro with an inline function enables better type checking. No functional change. Signed-off-by: Andrew Cooks --- ospf6d/ospf6_intra.c | 15 +++++++++------ ospf6d/ospf6_lsa.c | 4 ++-- ospf6d/ospf6_lsa.h | 7 +++++-- ospf6d/ospf6_spf.c | 4 ++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c index 48a7012adac7..b06796ada02c 100644 --- a/ospf6d/ospf6_intra.c +++ b/ospf6d/ospf6_intra.c @@ -705,7 +705,8 @@ static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, } start = (char *)link_lsa + sizeof(struct ospf6_link_lsa); - end = (char *)lsa->header + ntohs(lsa->header->length); + end = ospf6_lsa_end(lsa->header); + for (current = start; current < end; current += OSPF6_PREFIX_SIZE(prefix)) { prefix = (struct ospf6_prefix *)current; @@ -864,7 +865,7 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa, start = (char *)intra_prefix_lsa + sizeof(struct ospf6_intra_prefix_lsa); - end = (char *)lsa->header + ntohs(lsa->header->length); + end = ospf6_lsa_end(lsa->header); current = start; while (current + sizeof(struct ospf6_prefix) <= end) { @@ -935,7 +936,8 @@ static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, start = (char *)intra_prefix_lsa + sizeof(struct ospf6_intra_prefix_lsa); - end = (char *)lsa->header + ntohs(lsa->header->length); + end = ospf6_lsa_end(lsa->header); + for (current = start; current < end; current += OSPF6_PREFIX_SIZE(prefix)) { prefix = (struct ospf6_prefix *)current; @@ -1315,7 +1317,8 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread) prefix_num = (unsigned short)ntohl(link_lsa->prefix_num); start = (char *)link_lsa + sizeof(struct ospf6_link_lsa); - end = (char *)lsa->header + ntohs(lsa->header->length); + end = ospf6_lsa_end(lsa->header); + for (current = start; current < end && prefix_num; current += OSPF6_PREFIX_SIZE(op)) { op = (struct ospf6_prefix *)current; @@ -1770,7 +1773,7 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa) prefix_num = ntohs(intra_prefix_lsa->prefix_num); start = (caddr_t)intra_prefix_lsa + sizeof(struct ospf6_intra_prefix_lsa); - end = OSPF6_LSA_END(lsa->header); + end = ospf6_lsa_end(lsa->header); for (current = start; current < end; current += OSPF6_PREFIX_SIZE(op)) { op = (struct ospf6_prefix *)current; if (prefix_num == 0) @@ -1974,7 +1977,7 @@ void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa) prefix_num = ntohs(intra_prefix_lsa->prefix_num); start = (caddr_t)intra_prefix_lsa + sizeof(struct ospf6_intra_prefix_lsa); - end = OSPF6_LSA_END(lsa->header); + end = ospf6_lsa_end(lsa->header); for (current = start; current < end; current += OSPF6_PREFIX_SIZE(op)) { op = (struct ospf6_prefix *)current; if (prefix_num == 0) diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index 24643164c5fd..b907ccbc208e 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -66,7 +66,7 @@ static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa, char *start, *end, *current; start = ospf6_lsa_header_end(lsa->header); - end = (char *)lsa->header + ntohs(lsa->header->length); + end = ospf6_lsa_end(lsa->header); if (use_json) { json_object_string_add(json_obj, "lsaType", "unknown"); @@ -548,7 +548,7 @@ void ospf6_lsa_show_dump(struct vty *vty, struct ospf6_lsa *lsa, json_object *json = NULL; start = (uint8_t *)lsa->header; - end = (uint8_t *)lsa->header + ntohs(lsa->header->length); + end = (uint8_t *)ospf6_lsa_end(lsa->header); if (use_json) { json = json_object_new_object(); diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 0fa632449f59..714cd5883d5e 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -88,14 +88,17 @@ struct ospf6_lsa_header { }; #define OSPF6_LSA_SIZE(h) (ntohs(((struct ospf6_lsa_header *)(h))->length)) -#define OSPF6_LSA_END(h) \ - ((caddr_t)(h) + ntohs(((struct ospf6_lsa_header *)(h))->length)) static inline char *ospf6_lsa_header_end(struct ospf6_lsa_header *header) { return (char *)header + sizeof(struct ospf6_lsa_header); } +static inline char *ospf6_lsa_end(struct ospf6_lsa_header *header) +{ + return (char *)header + ntohs(header->length); +} + #define OSPF6_LSA_IS_TYPE(t, L) \ ((L)->header->type == htons(OSPF6_LSTYPE_##t) ? 1 : 0) #define OSPF6_LSA_IS_SAME(L1, L2) \ diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 93120df99915..7d6dcf8e36bb 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -207,7 +207,7 @@ static char *ospf6_lsdesc_backlink(struct ospf6_lsa *lsa, caddr_t lsdesc, ? sizeof(struct ospf6_router_lsdesc) : sizeof(struct ospf6_network_lsdesc)); for (backlink = ospf6_lsa_header_end(lsa->header) + 4; - backlink + size <= OSPF6_LSA_END(lsa->header); backlink += size) { + backlink + size <= ospf6_lsa_end(lsa->header); backlink += size) { assert(!(OSPF6_LSA_IS_TYPE(NETWORK, lsa) && VERTEX_IS_TYPE(NETWORK, v))); @@ -511,7 +511,7 @@ void ospf6_spf_calculation(uint32_t router_id, ? sizeof(struct ospf6_router_lsdesc) : sizeof(struct ospf6_network_lsdesc)); for (lsdesc = ospf6_lsa_header_end(v->lsa->header) + 4; - lsdesc + size <= OSPF6_LSA_END(v->lsa->header); + lsdesc + size <= ospf6_lsa_end(v->lsa->header); lsdesc += size) { lsa = ospf6_lsdesc_lsa(lsdesc, v); if (lsa == NULL) From 0dd99a673344107375378736d7355ccc542b9b70 Mon Sep 17 00:00:00 2001 From: Andrew Cooks Date: Tue, 28 May 2024 14:07:14 +1000 Subject: [PATCH 159/472] ospf6d: replace OSPF6_LSA_SIZE with ospf6_lsa_size Dropping the macro enables better compiler type checking. The macro was not used consistently when reading the lsa size from the header, so this change also aims to use the replacement inline function consistently. Keeping the inline function has (marginal) utility in that it ensures that the endian conversion is consistently performed. Signed-off-by: Andrew Cooks --- ospf6d/ospf6_lsa.c | 18 ++++++++--------- ospf6d/ospf6_lsa.h | 7 +++++-- ospf6d/ospf6_message.c | 45 +++++++++++++++++++++--------------------- ospf6d/ospf6_snmp.c | 2 +- ospf6d/ospf6_spf.c | 23 +++++++++++---------- 5 files changed, 49 insertions(+), 46 deletions(-) diff --git a/ospf6d/ospf6_lsa.c b/ospf6d/ospf6_lsa.c index b907ccbc208e..017751825f6b 100644 --- a/ospf6d/ospf6_lsa.c +++ b/ospf6d/ospf6_lsa.c @@ -201,10 +201,10 @@ int ospf6_lsa_is_differ(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2) return 1; /* compare body */ - if (ntohs(lsa1->header->length) != ntohs(lsa2->header->length)) + if (ospf6_lsa_size(lsa1->header) != ospf6_lsa_size(lsa2->header)) return 1; - len = ntohs(lsa1->header->length) - sizeof(struct ospf6_lsa_header); + len = ospf6_lsa_size(lsa1->header) - sizeof(struct ospf6_lsa_header); return memcmp(lsa1->header + 1, lsa2->header + 1, len); } @@ -214,7 +214,7 @@ int ospf6_lsa_is_changed(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2) if (OSPF6_LSA_IS_MAXAGE(lsa1) ^ OSPF6_LSA_IS_MAXAGE(lsa2)) return 1; - if (ntohs(lsa1->header->length) != ntohs(lsa2->header->length)) + if (ospf6_lsa_size(lsa1->header) != ospf6_lsa_size(lsa2->header)) return 1; /* Going beyond LSA headers to compare the payload only makes sense, * when both LSAs aren't header-only. */ @@ -228,7 +228,7 @@ int ospf6_lsa_is_changed(struct ospf6_lsa *lsa1, struct ospf6_lsa *lsa2) if (CHECK_FLAG(lsa1->flag, OSPF6_LSA_HEADERONLY)) return 0; - length = OSPF6_LSA_SIZE(lsa1->header) - sizeof(struct ospf6_lsa_header); + length = ospf6_lsa_size(lsa1->header) - sizeof(struct ospf6_lsa_header); /* Once upper layer verifies LSAs received, length underrun should * become a warning. */ if (length <= 0) @@ -613,7 +613,7 @@ void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa, json_object_int_add(json_obj, "checksum", ntohs(lsa->header->checksum)); json_object_int_add(json_obj, "length", - ntohs(lsa->header->length)); + ospf6_lsa_size(lsa->header)); json_object_int_add(json_obj, "flag", lsa->flag); json_object_int_add(json_obj, "lock", lsa->lock); json_object_int_add(json_obj, "reTxCount", lsa->retrans_count); @@ -630,7 +630,7 @@ void ospf6_lsa_show_internal(struct vty *vty, struct ospf6_lsa *lsa, (unsigned long)ntohl(lsa->header->seqnum)); vty_out(vty, "CheckSum: %#06hx Length: %hu\n", ntohs(lsa->header->checksum), - ntohs(lsa->header->length)); + ospf6_lsa_size(lsa->header)); vty_out(vty, "Flag: %x \n", lsa->flag); vty_out(vty, "Lock: %d \n", lsa->lock); vty_out(vty, "ReTx Count: %d\n", lsa->retrans_count); @@ -720,7 +720,7 @@ struct ospf6_lsa *ospf6_lsa_create(struct ospf6_lsa_header *header) uint16_t lsa_size = 0; /* size of the entire LSA */ - lsa_size = ntohs(header->length); /* XXX vulnerable */ + lsa_size = ospf6_lsa_size(header); /* XXX vulnerable */ lsa = ospf6_lsa_alloc(lsa_size); @@ -947,7 +947,7 @@ unsigned short ospf6_lsa_checksum(struct ospf6_lsa_header *lsa_header) buffer - (uint8_t *)&lsa_header->age; /* should be 2 */ /* Skip the AGE field */ - uint16_t len = ntohs(lsa_header->length) - type_offset; + uint16_t len = ospf6_lsa_size(lsa_header) - type_offset; /* Checksum offset starts from "type" field, not the beginning of the lsa_header struct. The offset is 14, rather than 16. */ @@ -963,7 +963,7 @@ int ospf6_lsa_checksum_valid(struct ospf6_lsa_header *lsa_header) buffer - (uint8_t *)&lsa_header->age; /* should be 2 */ /* Skip the AGE field */ - uint16_t len = ntohs(lsa_header->length) - type_offset; + uint16_t len = ospf6_lsa_size(lsa_header) - type_offset; return (fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0); diff --git a/ospf6d/ospf6_lsa.h b/ospf6d/ospf6_lsa.h index 714cd5883d5e..4fc2f0dd1889 100644 --- a/ospf6d/ospf6_lsa.h +++ b/ospf6d/ospf6_lsa.h @@ -87,8 +87,6 @@ struct ospf6_lsa_header { uint16_t length; /* LSA length */ }; -#define OSPF6_LSA_SIZE(h) (ntohs(((struct ospf6_lsa_header *)(h))->length)) - static inline char *ospf6_lsa_header_end(struct ospf6_lsa_header *header) { return (char *)header + sizeof(struct ospf6_lsa_header); @@ -99,6 +97,11 @@ static inline char *ospf6_lsa_end(struct ospf6_lsa_header *header) return (char *)header + ntohs(header->length); } +static inline uint16_t ospf6_lsa_size(struct ospf6_lsa_header *header) +{ + return ntohs(header->length); +} + #define OSPF6_LSA_IS_TYPE(t, L) \ ((L)->header->type == htons(OSPF6_LSTYPE_##t) ? 1 : 0) #define OSPF6_LSA_IS_SAME(L1, L2) \ diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index d13799c0e81d..a6ee8d8b0162 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -221,12 +221,12 @@ void ospf6_lsupdate_print(struct ospf6_header *oh, int action) && action == OSPF6_ACTION_RECV) || (IS_OSPF6_DEBUG_MESSAGE(oh->type, SEND) && action == OSPF6_ACTION_SEND)) { - - for (p = (char *)((caddr_t)lsupdate - + sizeof(struct ospf6_lsupdate)); - p < OSPF6_MESSAGE_END(oh) - && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh); - p += OSPF6_LSA_SIZE(p)) { + for (p = (char *)((caddr_t)lsupdate + + sizeof(struct ospf6_lsupdate)); + p < OSPF6_MESSAGE_END(oh) && + p + ospf6_lsa_size((struct ospf6_lsa_header *)p) <= + OSPF6_MESSAGE_END(oh); + p += ospf6_lsa_size((struct ospf6_lsa_header *)p)) { ospf6_lsa_header_print_raw( (struct ospf6_lsa_header *)p); } @@ -1414,7 +1414,7 @@ ospf6_lsaseq_examin(struct ospf6_lsa_header *lsah, /* start of buffered data */ return MSG_NG; } /* save on ntohs() calls here and in the LSA validator */ - lsalen = OSPF6_LSA_SIZE(lsah); + lsalen = ospf6_lsa_size(lsah); if (lsalen < OSPF6_LSA_HEADER_SIZE) { zlog_warn( "%s: malformed LSA header #%u, declared length is %u B", @@ -1646,9 +1646,10 @@ static void ospf6_lsupdate_recv(struct in6_addr *src, struct in6_addr *dst, /* Process LSAs */ for (p = (char *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate)); - p < OSPF6_MESSAGE_END(oh) - && p + OSPF6_LSA_SIZE(p) <= OSPF6_MESSAGE_END(oh); - p += OSPF6_LSA_SIZE(p)) { + p < OSPF6_MESSAGE_END(oh) && + p + ospf6_lsa_size((struct ospf6_lsa_header *)p) <= + OSPF6_MESSAGE_END(oh); + p += ospf6_lsa_size((struct ospf6_lsa_header *)p)) { ospf6_receive_lsa(on, (struct ospf6_lsa_header *)p); } @@ -2702,7 +2703,7 @@ static uint16_t ospf6_make_lsupdate_list(struct ospf6_neighbor *on, stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE); for (ALL_LSDB(on->lsupdate_list, lsa, lsanext)) { - if ((length + OSPF6_LSA_SIZE(lsa->header) + OSPF6_HEADER_SIZE) > + if ((length + ospf6_lsa_size(lsa->header) + OSPF6_HEADER_SIZE) > ospf6_packet_max(on->ospf6_if)) { ospf6_fill_header(on->ospf6_if, (*op)->s, length + OSPF6_HEADER_SIZE); @@ -2719,9 +2720,9 @@ static uint16_t ospf6_make_lsupdate_list(struct ospf6_neighbor *on, stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE); } ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); - stream_put((*op)->s, lsa->header, OSPF6_LSA_SIZE(lsa->header)); + stream_put((*op)->s, lsa->header, ospf6_lsa_size(lsa->header)); (*lsa_cnt)++; - length += OSPF6_LSA_SIZE(lsa->header); + length += ospf6_lsa_size(lsa->header); assert(lsa->lock == 2); ospf6_lsdb_remove(lsa, on->lsupdate_list); } @@ -2739,7 +2740,7 @@ static uint16_t ospf6_make_ls_retrans_list(struct ospf6_neighbor *on, stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE); for (ALL_LSDB(on->retrans_list, lsa, lsanext)) { - if ((length + OSPF6_LSA_SIZE(lsa->header) + OSPF6_HEADER_SIZE) > + if ((length + ospf6_lsa_size(lsa->header) + OSPF6_HEADER_SIZE) > ospf6_packet_max(on->ospf6_if)) { ospf6_fill_header(on->ospf6_if, (*op)->s, length + OSPF6_HEADER_SIZE); @@ -2763,9 +2764,9 @@ static uint16_t ospf6_make_ls_retrans_list(struct ospf6_neighbor *on, stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE); } ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); - stream_put((*op)->s, lsa->header, OSPF6_LSA_SIZE(lsa->header)); + stream_put((*op)->s, lsa->header, ospf6_lsa_size(lsa->header)); (*lsa_cnt)++; - length += OSPF6_LSA_SIZE(lsa->header); + length += ospf6_lsa_size(lsa->header); } return length; } @@ -2849,9 +2850,9 @@ int ospf6_lsupdate_send_neighbor_now(struct ospf6_neighbor *on, /* skip over fixed header */ stream_forward_endp(op->s, OSPF6_LS_UPD_MIN_SIZE); ospf6_lsa_age_update_to_send(lsa, on->ospf6_if->transdelay); - stream_put(op->s, lsa->header, OSPF6_LSA_SIZE(lsa->header)); - length = OSPF6_HEADER_SIZE + OSPF6_LS_UPD_MIN_SIZE - + OSPF6_LSA_SIZE(lsa->header); + stream_put(op->s, lsa->header, ospf6_lsa_size(lsa->header)); + length = OSPF6_HEADER_SIZE + OSPF6_LS_UPD_MIN_SIZE + + ospf6_lsa_size(lsa->header); ospf6_fill_header(on->ospf6_if, op->s, length); ospf6_fill_lsupdate_header(op->s, 1); op->length = length; @@ -2877,7 +2878,7 @@ static uint16_t ospf6_make_lsupdate_interface(struct ospf6_interface *oi, stream_forward_endp((*op)->s, OSPF6_LS_UPD_MIN_SIZE); for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext)) { - if (length + OSPF6_LSA_SIZE(lsa->header) + OSPF6_HEADER_SIZE > + if (length + ospf6_lsa_size(lsa->header) + OSPF6_HEADER_SIZE > ospf6_packet_max(oi)) { ospf6_fill_header(oi, (*op)->s, length + OSPF6_HEADER_SIZE); @@ -2895,9 +2896,9 @@ static uint16_t ospf6_make_lsupdate_interface(struct ospf6_interface *oi, } ospf6_lsa_age_update_to_send(lsa, oi->transdelay); - stream_put((*op)->s, lsa->header, OSPF6_LSA_SIZE(lsa->header)); + stream_put((*op)->s, lsa->header, ospf6_lsa_size(lsa->header)); (*lsa_cnt)++; - length += OSPF6_LSA_SIZE(lsa->header); + length += ospf6_lsa_size(lsa->header); assert(lsa->lock == 2); ospf6_lsdb_remove(lsa, oi->lsupdate_list); diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c index 17cdcdae8ec4..36864d2a7de7 100644 --- a/ospf6d/ospf6_snmp.c +++ b/ospf6d/ospf6_snmp.c @@ -1017,7 +1017,7 @@ static uint8_t *ospfv3WwLsdbEntry(struct variable *v, oid *name, size_t *length, case OSPFv3WWLSDBCHECKSUM: return SNMP_INTEGER(ntohs(lsa->header->checksum)); case OSPFv3WWLSDBADVERTISEMENT: - *var_len = ntohs(lsa->header->length); + *var_len = ospf6_lsa_size(lsa->header); return (uint8_t *)lsa->header; case OSPFv3WWLSDBTYPEKNOWN: return SNMP_INTEGER(OSPF6_LSA_IS_KNOWN(lsa->header->type) diff --git a/ospf6d/ospf6_spf.c b/ospf6d/ospf6_spf.c index 7d6dcf8e36bb..7879dae8d7cc 100644 --- a/ospf6d/ospf6_spf.c +++ b/ospf6d/ospf6_spf.c @@ -187,7 +187,7 @@ static struct ospf6_lsa *ospf6_lsdesc_lsa(caddr_t lsdesc, inet_ntop(AF_INET, &adv_router, abuf, sizeof(abuf)); if (lsa) zlog_debug(" Link to: %s len %u, V %s", lsa->name, - ntohs(lsa->header->length), v->name); + ospf6_lsa_size(lsa->header), v->name); else zlog_debug(" Link to: [%s Id:%s Adv:%s] No LSA , V %s", ospf6_lstype_name(type), ibuf, abuf, @@ -1011,7 +1011,7 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, continue; } lsa_header = rtr_lsa->header; - total_lsa_length += (ntohs(lsa_header->length) - lsa_length); + total_lsa_length += (ospf6_lsa_size(lsa_header) - lsa_length); num_lsa++; rtr_lsa = ospf6_lsdb_next(end, rtr_lsa); } @@ -1044,11 +1044,11 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, if (!OSPF6_LSA_IS_MAXAGE(rtr_lsa)) { /* Append first Link State ID LSA */ lsa_header = rtr_lsa->header; - memcpy(new_header, lsa_header, ntohs(lsa_header->length)); + memcpy(new_header, lsa_header, ospf6_lsa_size(lsa_header)); /* Assign new lsa length as aggregated length. */ ((struct ospf6_lsa_header *)new_header)->length = htons(total_lsa_length); - new_header += ntohs(lsa_header->length); + new_header += ospf6_lsa_size(lsa_header); num_lsa--; } @@ -1066,17 +1066,16 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, lsd = ospf6_lsa_header_end(rtr_lsa->header) + 4; interface_id = ROUTER_LSDESC_GET_IFID(lsd); inet_ntop(AF_INET, &interface_id, ifbuf, sizeof(ifbuf)); - zlog_debug( - "%s: Next Router LSA %s to aggreat with len %u interface_id %s", - __func__, rtr_lsa->name, - ntohs(lsa_header->length), ifbuf); + zlog_debug("%s: Next Router LSA %s to aggreat with len %u interface_id %s", + __func__, rtr_lsa->name, + ospf6_lsa_size(lsa_header), ifbuf); } /* Append Next Link State ID LSA */ lsa_header = rtr_lsa->header; memcpy(new_header, (ospf6_lsa_header_end(rtr_lsa->header) + 4), - (ntohs(lsa_header->length) - lsa_length)); - new_header += (ntohs(lsa_header->length) - lsa_length); + (ospf6_lsa_size(lsa_header) - lsa_length)); + new_header += (ospf6_lsa_size(lsa_header) - lsa_length); num_lsa--; rtr_lsa = ospf6_lsdb_next(end, rtr_lsa); @@ -1091,8 +1090,8 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area, if (IS_OSPF6_DEBUG_SPF(PROCESS)) zlog_debug("%s: LSA %s id %u type 0%x len %u num_lsa %u", __func__, lsa->name, ntohl(lsa->header->id), - ntohs(lsa->header->type), ntohs(lsa->header->length), - num_lsa); + ntohs(lsa->header->type), + ospf6_lsa_size(lsa->header), num_lsa); return lsa; } From 39e27b840e5ddc2087c0b20cfcf379745b3baa79 Mon Sep 17 00:00:00 2001 From: zhou-run <166502045+zhou-run@users.noreply.github.com> Date: Tue, 21 May 2024 17:19:44 +0800 Subject: [PATCH 160/472] isisd: When the metric-type is configured as "wide", the IS-IS generates incorrect metric values for IPv4 directly connected routes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IPv4 directly connected route prefix exists in both the root LSP and the root's neighbor LSP: 1. When generating vertices for directly connected route prefixes with a metric of 0 based on the root LSP, the isis_spf_preload_tent_ip_reach_cb function only generates vertices of type VTYPE_IPREACH_INTERNAL without distinguishing between area->oldmetric and area->newmetric. 2. When generating vertices for the directly connected route prefix based on the neighbor LSP, the isis_spf_process_lsp function will generate vertices of type VTYPE_IPREACH_INTERNAL and VTYPE_IPREACH_TE based on area->oldmetric and area->newmetric, where the vertex metric is the sum of the metric from the root IS to the neighbor IS and from the neighbor IS to the root IS, respectively. If area->newmetric=1, the same directly connected route prefix will have both VTYPE_IPREACH_INTERNAL vertices with a metric of 0 and VTYPE_IPREACH_TE vertices with a non-zero metric. During route generation, the isis_spf_loop function will prioritize selecting VTYPE_IPREACH_TE vertices, leading to incorrect metrics for the directly connected routes. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> fix frrbot styling issues found. 1)fix frrbot styling issues found. 2)Roll back the modifications to TE. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> Maintain code factorization and avoid duplicating code. Maintain code factorization and avoid duplicating code. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: fix frrbot styling issues found fix frrbot styling issues found Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: fix frrbot styling issues found fix frrbot styling issues found Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: Resolve compilation issues. Resolve compilation issues. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: Resolve compilation issues. Resolve compilation issues. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: fix frrbot styling issues found fix frrbot styling issues found Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: fix frrbot styling issues found fix frrbot styling issues found Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> isisd: Resolve compilation issues. Resolve compilation issues. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> --- isisd/isis_spf.c | 24 ++++- tests/isisd/test_isis_spf.refout | 154 +++++++++++++++---------------- 2 files changed, 97 insertions(+), 81 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 418e0af16b82..7fdbe8d109fd 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1260,7 +1260,7 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, struct isis_vertex *parent = args->parent; struct prefix_pair ip_info; enum vertextype vtype; - bool has_valid_psid = false; + bool has_valid_psid = false, transition = false; if (external) return LSP_ITER_CONTINUE; @@ -1270,10 +1270,17 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, prefix_copy(&ip_info.dest, prefix); apply_mask(&ip_info.dest); - if (prefix->family == AF_INET) + if (prefix->family == AF_INET) { vtype = VTYPE_IPREACH_INTERNAL; - else + + if (spftree->area->newmetric) + vtype = VTYPE_IPREACH_TE; + + if (spftree->area->oldmetric && spftree->area->newmetric) + transition = true; + } else { vtype = VTYPE_IP6REACH_INTERNAL; + } /* Parse list of Prefix-SID subTLVs if SR is enabled */ if (spftree->area->srdb.enabled && subtlvs) { @@ -1288,6 +1295,11 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, has_valid_psid = true; isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, psid, parent); + if (transition) + isis_spf_add_local(spftree, + VTYPE_IPREACH_INTERNAL, + &ip_info, NULL, 0, psid, + parent); /* * Stop the Prefix-SID iteration since we only support @@ -1296,9 +1308,13 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, break; } } - if (!has_valid_psid) + if (!has_valid_psid) { isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, NULL, parent); + if (transition) + isis_spf_add_local(spftree, VTYPE_IPREACH_INTERNAL, + &ip_info, NULL, 0, NULL, parent); + } return LSP_ITER_CONTINUE; } diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout index 23d41b9e5dd0..d70677c9b3ce 100644 --- a/tests/isisd/test_isis_spf.refout +++ b/tests/isisd/test_isis_spf.refout @@ -2,7 +2,7 @@ test# test isis topology 1 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -61,7 +61,7 @@ test# test isis topology 2 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 10 rt5 - rt1(4) rt2 TE-IS 15 rt2 - rt1(4) @@ -122,7 +122,7 @@ test# test isis topology 3 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -149,7 +149,7 @@ test# test isis topology 4 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -182,7 +182,7 @@ test# test isis topology 5 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -218,7 +218,7 @@ test# test isis topology 6 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -266,7 +266,7 @@ test# test isis topology 7 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 20 rt4 - rt4(4) rt7 TE-IS 20 rt4 - rt4(4) @@ -314,7 +314,7 @@ test# test isis topology 8 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt3 TE-IS 20 rt2 - rt2(4) @@ -361,7 +361,7 @@ test# test isis topology 9 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -438,7 +438,7 @@ test# test isis topology 10 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 20 rt3 - rt1(4) rt4 TE-IS 20 rt4 - rt1(4) @@ -503,7 +503,7 @@ test# test isis topology 11 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt2 pseudo_TE-IS 20 rt3 - rt3(4) @@ -564,7 +564,7 @@ test# test isis topology 12 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -603,7 +603,7 @@ test# test isis topology 13 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -638,7 +638,7 @@ test# test isis topology 4 root rt1 reverse-spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -671,7 +671,7 @@ test# test isis topology 11 root rt1 reverse-spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt2 pseudo_TE-IS 20 rt3 - rt3(4) @@ -725,7 +725,7 @@ test# test isis topology 1 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -792,7 +792,7 @@ test# test isis topology 2 root rt4 lfa system-id rt1 pseudonode-id 1 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP internal 0 rt4(4) +10.0.255.4/32 IP TE 0 rt4(4) rt1 TE-IS 10 rt1 - rt4(4) rt5 TE-IS 10 rt5 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) @@ -865,7 +865,7 @@ test# test isis topology 2 root rt4 lfa system-id rt6 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP internal 0 rt4(4) +10.0.255.4/32 IP TE 0 rt4(4) rt1 TE-IS 10 rt1 - rt4(4) rt5 TE-IS 10 rt5 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) @@ -938,7 +938,7 @@ test# test isis topology 3 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -988,7 +988,7 @@ test# test isis topology 3 root rt1 lfa system-id rt3 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -1035,7 +1035,7 @@ test# test isis topology 7 root rt1 lfa system-id rt4 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 20 rt4 - rt4(4) rt7 TE-IS 20 rt4 - rt4(4) @@ -1113,7 +1113,7 @@ test# test isis topology 7 root rt7 lfa system-id rt8 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt7 -10.0.255.7/32 IP internal 0 rt7(4) +10.0.255.7/32 IP TE 0 rt7(4) rt4 TE-IS 10 rt4 - rt7(4) rt8 TE-IS 10 rt8 - rt7(4) rt10 TE-IS 20 rt10 - rt7(4) @@ -1195,7 +1195,7 @@ test# test isis topology 7 root rt8 lfa system-id rt11 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt8 -10.0.255.8/32 IP internal 0 rt8(4) +10.0.255.8/32 IP TE 0 rt8(4) rt5 TE-IS 10 rt5 - rt8(4) rt7 TE-IS 10 rt7 - rt8(4) rt9 TE-IS 10 rt9 - rt8(4) @@ -1272,7 +1272,7 @@ test# test isis topology 9 root rt3 lfa system-id rt1 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt3 -10.0.255.3/32 IP internal 0 rt3(4) +10.0.255.3/32 IP TE 0 rt3(4) rt1 TE-IS 10 rt1 - rt3(4) rt2 TE-IS 20 rt1 - rt1(4) 10.0.255.1/32 IP TE 20 rt1 - rt1(4) @@ -1379,7 +1379,7 @@ test# test isis topology 10 root rt8 lfa system-id rt5 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt8 -10.0.255.8/32 IP internal 0 rt8(4) +10.0.255.8/32 IP TE 0 rt8(4) rt5 TE-IS 10 rt5 - rt8(4) rt2 TE-IS 20 rt5 - rt5(4) 10.0.255.5/32 IP TE 20 rt5 - rt5(4) @@ -1478,7 +1478,7 @@ test# test isis topology 11 root rt3 lfa system-id rt5 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt3 -10.0.255.3/32 IP internal 0 rt3(4) +10.0.255.3/32 IP TE 0 rt3(4) rt1 TE-IS 10 rt1 - rt3(4) rt2 TE-IS 10 rt2 - rt3(4) rt5 TE-IS 10 rt5 - rt3(4) @@ -1557,7 +1557,7 @@ test# test isis topology 13 root rt4 lfa system-id rt3 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP internal 0 rt4(4) +10.0.255.4/32 IP TE 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt3 TE-IS 10 rt3 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) @@ -1615,7 +1615,7 @@ test# test isis topology 14 root rt1 lfa system-id rt1 pseudonode-id 1 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt2 TE-IS 10 rt2 - rt1(4) @@ -1672,7 +1672,7 @@ test# test isis topology 14 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt2 TE-IS 10 rt2 - rt1(4) @@ -1737,7 +1737,7 @@ test# test isis topology 14 root rt5 lfa system-id rt4 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt1 pseudo_TE-IS 20 rt4 - rt4(4) rt1 TE-IS 20 rt4 - rt1(2) @@ -1825,7 +1825,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -1840,7 +1840,7 @@ rt2 TE-IS 50 rt3 - rt4(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -1966,7 +1966,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -1982,7 +1982,7 @@ rt2 TE-IS 45 rt6 - rt1(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt1 TE-IS 10 rt1 - rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) @@ -2125,7 +2125,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -2142,7 +2142,7 @@ rt1 TE-IS 40 rt3 - rt3(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -2212,7 +2212,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -2227,7 +2227,7 @@ rt3 TE-IS 30 rt4 - rt2(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -2278,7 +2278,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -2297,7 +2297,7 @@ rt2 TE-IS 70 rt3 - rt4(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -2364,7 +2364,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP internal 0 rt4(4) +10.0.255.4/32 IP TE 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) @@ -2384,7 +2384,7 @@ rt7 TE-IS 30 rt6 - rt5(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP internal 0 rt4(4) +10.0.255.4/32 IP TE 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt3 TE-IS 10 rt3 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) @@ -2454,7 +2454,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt11 -10.0.255.11/32 IP internal 0 rt11(4) +10.0.255.11/32 IP TE 0 rt11(4) rt10 TE-IS 10 rt10 - rt11(4) rt12 TE-IS 10 rt12 - rt11(4) rt9 TE-IS 20 rt12 - rt12(4) @@ -2483,7 +2483,7 @@ rt3 TE-IS 60 rt12 - rt6(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt11 -10.0.255.11/32 IP internal 0 rt11(4) +10.0.255.11/32 IP TE 0 rt11(4) rt8 TE-IS 10 rt8 - rt11(4) rt10 TE-IS 10 rt10 - rt11(4) rt12 TE-IS 10 rt12 - rt11(4) @@ -2579,7 +2579,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt6 -10.0.255.6/32 IP internal 0 rt6(4) +10.0.255.6/32 IP TE 0 rt6(4) rt3 TE-IS 10 rt3 - rt6(4) rt2 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -2614,7 +2614,7 @@ rt10 TE-IS 60 rt9 - rt11(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt6 -10.0.255.6/32 IP internal 0 rt6(4) +10.0.255.6/32 IP TE 0 rt6(4) rt3 TE-IS 10 rt3 - rt6(4) rt5 TE-IS 10 rt5 - rt6(4) rt2 TE-IS 20 rt3 - rt3(4) @@ -2708,7 +2708,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP internal 0 rt2(4) +10.0.255.2/32 IP TE 0 rt2(4) rt1 TE-IS 10 rt1 - rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt4 TE-IS 20 rt1 - rt1(4) @@ -2736,7 +2736,7 @@ rt12 TE-IS 60 rt3 - rt9(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP internal 0 rt2(4) +10.0.255.2/32 IP TE 0 rt2(4) rt1 TE-IS 10 rt1 - rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt5 TE-IS 10 rt5 - rt2(4) @@ -2817,7 +2817,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP internal 0 rt2(4) +10.0.255.2/32 IP TE 0 rt2(4) rt1 TE-IS 50 rt1 - rt2(4) rt3 TE-IS 50 rt3 - rt2(4) rt2 @@ -2833,7 +2833,7 @@ rt6 TE-IS 70 rt3 - rt5(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP internal 0 rt2(4) +10.0.255.2/32 IP TE 0 rt2(4) rt4 TE-IS 10 rt4 - rt2(4) rt5 TE-IS 20 rt4 - rt4(4) rt6 TE-IS 20 rt4 - rt4(4) @@ -2968,7 +2968,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -2986,7 +2986,7 @@ rt7 TE-IS 50 rt2 - rt5(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -3046,7 +3046,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3129,7 +3129,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 10 rt5 - rt1(4) rt2 TE-IS 15 rt2 - rt1(4) @@ -3219,7 +3219,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 15 rt2 - rt1(4) 10.0.255.2/32 IP TE 25 rt2 - rt2(4) rt3 TE-IS 30 rt3 - rt1(4) @@ -3305,7 +3305,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -3398,7 +3398,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -3452,7 +3452,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP internal 0 rt5(4) +10.0.255.5/32 IP TE 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -3486,7 +3486,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3533,7 +3533,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP internal 0 rt4(4) +10.0.255.4/32 IP TE 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -3577,7 +3577,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3626,7 +3626,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP internal 0 rt4(4) +10.0.255.4/32 IP TE 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) @@ -3678,7 +3678,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt11 -10.0.255.11/32 IP internal 0 rt11(4) +10.0.255.11/32 IP TE 0 rt11(4) rt10 TE-IS 10 rt10 - rt11(4) rt12 TE-IS 10 rt12 - rt11(4) rt9 TE-IS 20 rt12 - rt12(4) @@ -3752,7 +3752,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt6 -10.0.255.6/32 IP internal 0 rt6(4) +10.0.255.6/32 IP TE 0 rt6(4) rt3 TE-IS 10 rt3 - rt6(4) rt2 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3831,7 +3831,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP internal 0 rt2(4) +10.0.255.2/32 IP TE 0 rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt5 TE-IS 10 rt5 - rt2(4) rt6 TE-IS 20 rt3 - rt3(4) @@ -3896,7 +3896,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP internal 0 rt2(4) +10.0.255.2/32 IP TE 0 rt2(4) rt1 TE-IS 10 rt1 - rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt4 TE-IS 20 rt1 - rt1(4) @@ -3956,7 +3956,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -4053,7 +4053,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) rt4 TE-IS 110 rt3 - rt3(4) @@ -4162,7 +4162,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt9 -10.0.255.9/32 IP internal 0 rt9(4) +10.0.255.9/32 IP TE 0 rt9(4) rt6 TE-IS 10 rt6 - rt9(4) rt7 TE-IS 10 rt7 - rt9(4) rt8 TE-IS 10 rt8 - rt9(4) @@ -4331,7 +4331,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt9 -10.0.255.9/32 IP internal 0 rt9(4) +10.0.255.9/32 IP TE 0 rt9(4) rt5 TE-IS 10 rt5 - rt9(4) rt6 TE-IS 10 rt6 - rt9(4) rt7 TE-IS 10 rt7 - rt9(4) @@ -4430,7 +4430,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt3 TE-IS 20 rt3 - rt1(4) rt4 TE-IS 20 rt4 - rt1(4) rt6 TE-IS 30 rt3 - rt3(4) @@ -4542,7 +4542,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 20 rt3 - rt1(4) rt5 TE-IS 20 rt2 - rt2(4) @@ -4635,7 +4635,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP internal 0 rt2(4) +10.0.255.2/32 IP TE 0 rt2(4) rt1 TE-IS 50 rt1 - rt2(4) rt3 TE-IS 50 rt3 - rt2(4) rt2 @@ -4725,7 +4725,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -4772,7 +4772,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP internal 0 rt1(4) +10.0.255.1/32 IP TE 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -4796,5 +4796,5 @@ IS-IS L1 IPv4 routing table: 10.0.255.6/32 50 - rt2 16040/16060 10.0.255.7/32 60 - rt2 16040/16070 -test# -end. +test# +end. From 6924749bfe6e830d47c0f65e82dd7b04b2764866 Mon Sep 17 00:00:00 2001 From: zhou-run <166502045+zhou-run@users.noreply.github.com> Date: Sat, 11 May 2024 15:30:38 +0800 Subject: [PATCH 161/472] isisd: fix crash when deactivating ISIS adjacency on the interface. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. When the command "no router isis WORD" is executed on the interface, it invokes list_delete_all_node to iterate and release the memory of all nodes in the cirtcuit->u.bc.adjdb[1] linked list. However, the nodes are not unlinked during this traversal process, leading to the call of *list->del to delete the data of the linked list nodes. 2. For ISIS, deleting the data of the linked list nodes is done by calling isis_delete_adj. Subsequently, isis_level2_adj_up will be called to iterate and query the cirtcuit->u.bc.adjdb[1] linked list. If there are many neighbors on this interface, accessing the memory of the released linked list nodes may occur. 3. Not limited to ISIS, if the linked list is not unlinked during the deletion of all nodes in process 1, *list->del should not be allowed to iterate through the list again. The backtrace is as follows: (gdb) bt at isisd/isis_csm.c:196 context=) at lib/northbound.c:1131 errmsg_len=errmsg_len@entry=8192) at lib/northbound.c:1356 at lib/northbound.c:1473 errmsg=errmsg@entry=0x7ffc0ced38d0 "", errmsg_len=errmsg_len@entry=8192) at lib/northbound.c:906 comment=comment@entry=0x0, transaction_id=transaction_id@entry=0x0, errmsg=errmsg@entry=0x7ffc0ced38d0 "", errmsg_len=8192) at lib/northbound.c:938 filter=FILTER_RELAXED) at lib/command.c:971 at lib/command.c:1030 vtysh=vtysh@entry=0) at lib/command.c:1198 at isisd/isis_csm.c:196 context=) at lib/northbound.c:1131 errmsg_len=errmsg_len@entry=8192) at lib/northbound.c:1356 at lib/northbound.c:1473 errmsg=errmsg@entry=0x7ffc0ced38d0 "", errmsg_len=errmsg_len@entry=8192) at lib/northbound.c:906 comment=comment@entry=0x0, transaction_id=transaction_id@entry=0x0, errmsg=errmsg@entry=0x7ffc0ced38d0 "", errmsg_len=8192) at lib/northbound.c:938 filter=FILTER_RELAXED) at lib/command.c:971 at lib/command.c:1030 vtysh=vtysh@entry=0) at lib/command.c:1198 0 0x00007f7d6e541fe1 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0 1 0x00007f7d6e63188c in core_handler (signo=11, siginfo=0x7ffc0ced2630, context=) at lib/sigevent.c:262 2 3 0x00005647f5b11568 in isis_level2_adj_up (area=area@entry=0x5647f7c89830) at isisd/isis_lsp.c:423 4 0x00005647f5b14073 in isis_reset_attach_bit (adj=0x5647f7cad690) at isisd/isis_lsp.c:474 5 lsp_handle_adj_state_change (adj=0x5647f7cad690) at isisd/isis_lsp.c:2162 6 0x00005647f5b53675 in hook_call_isis_adj_state_change_hook (adj=adj@entry=0x5647f7cad690) at isisd/isis_adjacency.c:152 7 0x00005647f5b536f3 in isis_delete_adj (arg=0x5647f7cad690) at isisd/isis_adjacency.c:167 8 0x00007f7d6e5fe003 in list_delete_all_node (list=0x5647f7c88060) at lib/linklist.c:316 9 0x00007f7d6e5fe069 in list_delete (list=list@entry=0x5647f7c84708) at lib/linklist.c:326 10 0x00005647f5b0872e in isis_circuit_down (circuit=0x5647f7c84620) at isisd/isis_circuit.c:835 11 0x00005647f5b09f81 in isis_csm_state_change (event=event@entry=IF_DOWN_FROM_Z, circuit=circuit@entry=0x5647f7c84620, arg=arg@entry=0x5647f7c7f7a0) at isisd/isis_csm.c:196 12 0x00005647f5b083b0 in isis_circuit_disable (circuit=0x5647f7c84620) at isisd/isis_circuit.c:100 13 isis_circuit_del (circuit=0x5647f7c84620) at isisd/isis_circuit.c:200 14 0x00005647f5b434f5 in lib_interface_isis_destroy (args=) at isisd/isis_nb_config.c:2612 15 0x00007f7d6e61347a in nb_callback_destroy (errmsg_len=2, errmsg=0x7ffc0ced38d0 "", dnode=0x5647f7c948f0, event=NB_EV_APPLY, nb_node=, context=) at lib/northbound.c:1131 16 nb_callback_configuration (context=, event=event@entry=NB_EV_APPLY, change=change@entry=0x5647f7cb6680, errmsg=errmsg@entry=0x7ffc0ced38d0 "", errmsg_len=errmsg_len@entry=8192) at lib/northbound.c:1356 17 0x00007f7d6e6138b7 in nb_transaction_process (errmsg_len=8192, errmsg=0x7ffc0ced38d0 "", transaction=0x5647f7c94080, event=NB_EV_APPLY) at lib/northbound.c:1473 18 nb_candidate_commit_apply (transaction=0x5647f7c94080, save_transaction=save_transaction@entry=true, transaction_id=transaction_id@entry=0x0, errmsg=errmsg@entry=0x7ffc0ced38d0 "", errmsg_len=errmsg_len@entry=8192) at lib/northbound.c:906 19 0x00007f7d6e61403d in nb_candidate_commit (context=context@entry=0x7ffc0ced38c0, candidate=, save_transaction=save_transaction@entry=true, comment=comment@entry=0x0, transaction_id=transaction_id@entry=0x0, errmsg=errmsg@entry=0x7ffc0ced38d0 "", errmsg_len=8192) at lib/northbound.c:938 20 0x00007f7d6e616ec9 in nb_cli_classic_commit (vty=0x5647f7cae160) at lib/northbound_cli.c:64 21 0x00007f7d6e6176a8 in nb_cli_apply_changes (vty=0x5647f7cae160, xpath_base_fmt=) at lib/northbound_cli.c:268 22 0x00007f7d6e5d918e in cmd_execute_command_real (vline=vline@entry=0x5647f7cae140, vty=vty@entry=0x5647f7cae160, cmd=cmd@entry=0x0, up_level=up_level@entry=0, filter=FILTER_RELAXED) at lib/command.c:971 23 0x00007f7d6e5d951d in cmd_execute_command (vline=vline@entry=0x5647f7cae140, vty=vty@entry=0x5647f7cae160, cmd=cmd@entry=0x0, vtysh=vtysh@entry=0) at lib/command.c:1030 24 0x00007f7d6e5d9770 in cmd_execute (vty=vty@entry=0x5647f7cae160, cmd=cmd@entry=0x5647f7cb48a0 "no ip router isis 10", matched=matched@entry=0x0, vtysh=vtysh@entry=0) at lib/command.c:1198 25 0x00007f7d6e6485e6 in vty_command (vty=vty@entry=0x5647f7cae160, buf=0x5647f7cb48a0 "no ip router isis 10") at lib/vty.c:483 26 0x00007f7d6e648d01 in vty_execute (vty=vty@entry=0x5647f7cae160) at lib/vty.c:1246 27 0x00007f7d6e64ba40 in vtysh_read (thread=) at lib/vty.c:2090 28 0x00007f7d6e64348d in thread_call (thread=thread@entry=0x7ffc0ced8310) at lib/thread.c:1958 29 0x00007f7d6e5fd4a8 in frr_run (master=0x5647f79a43d0) at lib/libfrr.c:1184 30 0x00005647f5b050f3 in main (argc=5, argv=, envp=) at isisd/isis_main.c:273 (gdb) f 3 423 isisd/isis_lsp.c: No such file or directory. (gdb) p node $1 = (struct listnode *) 0x110 (gdb) f 8 316 lib/linklist.c: No such file or directory. (gdb) p list->head->data $2 = (void *) 0x5647f7cabf20 (gdb) p list->head->next->data $3 = (void *) 0x5647f7c9bb60 (gdb) p list->head->next->next->data Cannot access memory at address 0x120 (gdb) p list->head->next->next $4 = (struct listnode *) 0x110 The backtrace provided above pertains to version 8.2.2, but it seems that the same issue exists in the code of the master branch as well. isis_reset_attach_bit() is useless because lsp_handle_adj_state_change() unconditionally calls lsp_regenerate_schedule. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> --- isisd/isis_lsp.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 9d671137e945..9e875ff6e4e7 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -442,47 +442,6 @@ void set_overload_on_start_timer(struct event *thread) isis_area_overload_bit_set(area, false); } -static void isis_reset_attach_bit(struct isis_adjacency *adj) -{ - struct isis_area *area = adj->circuit->area; - struct lspdb_head *head; - struct isis_lsp *lsp; - uint8_t lspid[ISIS_SYS_ID_LEN + 2]; - - /* - * If an L2 adjacency changed its state in L-1-2 area, we have to: - * - set the attached bit in L1 LSPs if it's the first L2 adjacency - * - remove the attached bit in L1 LSPs if it's the last L2 adjacency - */ - - if (area->is_type != IS_LEVEL_1_AND_2 || adj->level == ISIS_ADJ_LEVEL1) - return; - - if (!area->attached_bit_send) - return; - - head = &area->lspdb[IS_LEVEL_1 - 1]; - memset(lspid, 0, ISIS_SYS_ID_LEN + 2); - memcpy(lspid, area->isis->sysid, ISIS_SYS_ID_LEN); - - lsp = lsp_search(head, lspid); - if (!lsp) - return; - - if (adj->adj_state == ISIS_ADJ_UP - && !(lsp->hdr.lsp_bits & LSPBIT_ATT)) { - sched_debug("ISIS (%s): adj going up regenerate lsp-bits", - area->area_tag); - lsp_regenerate_schedule(area, IS_LEVEL_1, 0); - } else if (adj->adj_state == ISIS_ADJ_DOWN - && (lsp->hdr.lsp_bits & LSPBIT_ATT) - && !isis_level2_adj_up(area)) { - sched_debug("ISIS (%s): adj going down regenerate lsp-bits", - area->area_tag); - lsp_regenerate_schedule(area, IS_LEVEL_1, 0); - } -} - static uint8_t lsp_bits_generate(int level, int overload_bit, int attached_bit, struct isis_area *area) { @@ -2354,11 +2313,6 @@ static int lsp_handle_adj_state_change(struct isis_adjacency *adj) { lsp_regenerate_schedule(adj->circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0); - /* when an adjacency state changes determine if we need to - * change attach_bits in other area's LSPs - */ - isis_reset_attach_bit(adj); - return 0; } From 772688d2d3c03d8eeeb711c2fe3735c9e0885498 Mon Sep 17 00:00:00 2001 From: Acee Date: Tue, 28 May 2024 10:02:27 -0400 Subject: [PATCH 162/472] ospf6d: OSPFv3 route change comparision fixed for ASBR-only change When a router route already exists in the area border routers table as an ABR and it solely changes its ABR or ASBR status, the change was missed and border route is not updated. This fixes the comparison for the router_bits in the ospf6_path structure. This fixes issue https://github.com/FRRouting/frr/issues/16053 although the actual problem is not the computing router (r2) and not the OSPFv3 redistribution (r3). Signed-off-by: Acee --- ospf6d/ospf6_abr.c | 7 ++++--- ospf6d/ospf6_route.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index d3ff759d33ed..629b9839ec9d 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -1357,9 +1357,10 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) * does not match with the new entry then add the new route */ if (old_entry_updated == false) { - if ((old == NULL) || (old->type != route->type) - || (old->path.type != route->path.type) - || (old->path.cost != route->path.cost)) + if ((old == NULL) || (old->type != route->type) || + (old->path.type != route->path.type) || + (old->path.cost != route->path.cost) || + (old->path.router_bits != route->path.router_bits)) add_route = true; } diff --git a/ospf6d/ospf6_route.h b/ospf6d/ospf6_route.h index d3c1804658ff..88813491e48d 100644 --- a/ospf6d/ospf6_route.h +++ b/ospf6d/ospf6_route.h @@ -290,6 +290,7 @@ extern const char *const ospf6_path_type_substr[OSPF6_PATH_TYPE_MAX]; prefix_same(&(ra)->prefix, &(rb)->prefix) && \ (ra)->path.type == (rb)->path.type && \ (ra)->path.cost == (rb)->path.cost && \ + (ra)->path.router_bits == (rb)->path.router_bits && \ (ra)->path.u.cost_e2 == (rb)->path.u.cost_e2 && \ listcount(ra->paths) == listcount(rb->paths) && \ ospf6_route_cmp_nexthops(ra, rb)) From f1ea52bee98c03daaefc0fb35aaa64566759160e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sang?= Date: Tue, 28 May 2024 18:27:40 +0200 Subject: [PATCH 163/472] yang: use relative path instead of absolute one for route-map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using absolute xpath is not optimal for finding the target node. As the route map configuration grows, the yang validation will take more time to complete. Relative paths are much faster. Tested with a config file that contains ~3k route map config lines. - before: time cat conf | vtysh configure log syslog errors router bgp 65000 ! route-map RM:BGP:VPNV4:PEER:VRR9:IN10001 permit 101 match community CL:HCC:PATH_PRIO1_EAST1 set local-preference 15200 ! ... route-map RM:BGP:VPNV4:PEER:VRR9:IN10001 permit 1182 match community CL:HCC:PATH_PRIO1_EAST1082 set local-preference 16281 ! real 13m51.500s user 0m0.522s sys 0m4.854s - after: time cat conf | vtysh ... real 0m48.390s user 0m0.384s sys 0m1.245s Signed-off-by: Loïc Sang --- yang/frr-bgp-route-map.yang | 100 +++++++++++++++++----------------- yang/frr-ospf-route-map.yang | 2 +- yang/frr-ospf6-route-map.yang | 2 +- 3 files changed, 52 insertions(+), 52 deletions(-) diff --git a/yang/frr-bgp-route-map.yang b/yang/frr-bgp-route-map.yang index b0858e153cec..abfb14c23cec 100644 --- a/yang/frr-bgp-route-map.yang +++ b/yang/frr-bgp-route-map.yang @@ -542,7 +542,7 @@ identity set-extcommunity-color { augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:rmap-match-condition/frr-route-map:match-condition" { case local-preference { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-local-preference')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-local-preference')"; leaf local-preference { type uint32 { range "0..4294967295"; @@ -551,21 +551,21 @@ identity set-extcommunity-color { } case alias { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-alias')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-alias')"; leaf alias { type string; } } case script { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-script')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-script')"; leaf script { type string; } } case origin { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-origin')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-origin')"; leaf origin { type enumeration { enum "egp" { @@ -588,7 +588,7 @@ identity set-extcommunity-color { } case rpki { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:rpki')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:rpki')"; leaf rpki { type enumeration { enum "invalid" { @@ -634,7 +634,7 @@ identity set-extcommunity-color { } case probability { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:probability')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:probability')"; leaf probability { type uint8 { range "0..100"; @@ -643,14 +643,14 @@ identity set-extcommunity-color { } case source-vrf { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:source-vrf')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:source-vrf')"; leaf source-vrf { type string; } } case peer { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:peer')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:peer')"; choice peer { description "Value of the peer"; @@ -689,10 +689,10 @@ identity set-extcommunity-color { } case access-list-name { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:mac-address-list') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:as-path-list') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ip-route-source') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ip-route-source-prefix-list')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:mac-address-list') or " + + "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:as-path-list') or " + + "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:ip-route-source') or " + + "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:ip-route-source-prefix-list')"; description "Access-list name"; leaf list-name { @@ -701,7 +701,7 @@ identity set-extcommunity-color { } case evpn-default-route { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-default-route')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:evpn-default-route')"; description "Match default EVPN type-5 route"; leaf evpn-default-route { @@ -710,7 +710,7 @@ identity set-extcommunity-color { } case evpn-vni { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-vni')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:evpn-vni')"; description "Match eVPN VNI"; leaf evpn-vni { @@ -721,7 +721,7 @@ identity set-extcommunity-color { } case evpn-route-type { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-route-type')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:evpn-route-type')"; description "Match eVPN route-type"; leaf evpn-route-type { @@ -756,7 +756,7 @@ identity set-extcommunity-color { } case evpn-rd { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:evpn-rd')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:evpn-rd')"; description "Match eVPN route-distinguisher"; leaf route-distinguisher { @@ -765,9 +765,9 @@ identity set-extcommunity-color { } case comm-list-name { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-community') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-large-community') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:match-extcommunity')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-community') or " + + "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-large-community') or " + + "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:match-extcommunity')"; container comm-list { leaf comm-list-name { mandatory true; @@ -790,7 +790,7 @@ identity set-extcommunity-color { } case ipv4-address { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ipv4-nexthop')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:ipv4-nexthop')"; leaf ipv4-address { type inet:ipv4-address; description @@ -799,7 +799,7 @@ identity set-extcommunity-color { } case ipv6-address { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:match-condition/frr-route-map:condition, 'frr-bgp-route-map:ipv6-nexthop')"; + when "derived-from-or-self(../frr-route-map:condition, 'frr-bgp-route-map:ipv6-nexthop')"; leaf ipv6-address { type inet:ipv6-address; description @@ -817,7 +817,7 @@ identity set-extcommunity-color { augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:rmap-set-action/frr-route-map:set-action" { case distance { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:distance')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:distance')"; leaf distance { type uint8 { range "1..255"; @@ -826,7 +826,7 @@ identity set-extcommunity-color { } case extcommunity-none { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-none')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-none')"; description "Value of the BGP extended community attribute"; leaf extcommunity-none { @@ -836,7 +836,7 @@ identity set-extcommunity-color { } case extcommunity-rt { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-rt')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-rt')"; description "Value of the ext-community"; leaf extcommunity-rt { @@ -858,7 +858,7 @@ identity set-extcommunity-color { } case extcommunity-soo { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-soo')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-soo')"; description "Value of the ext-community"; leaf extcommunity-soo { @@ -869,7 +869,7 @@ identity set-extcommunity-color { } case extcommunity-lb { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-lb')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-lb')"; container extcommunity-lb { description "Value of the ext-community."; @@ -890,7 +890,7 @@ identity set-extcommunity-color { } case extcommunity-color { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-color')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-extcommunity-color')"; description "Value of the ext-community"; leaf extcommunity-color { @@ -903,7 +903,7 @@ identity set-extcommunity-color { } case ipv4-address { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv4-vpn-address')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:ipv4-vpn-address')"; description "Set the IPv4 address"; leaf ipv4-address { @@ -912,15 +912,15 @@ identity set-extcommunity-color { } case ipv4-nexthop { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-ipv4-nexthop')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-ipv4-nexthop')"; leaf ipv4-nexthop { type string; } } case ipv6-address { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-nexthop-global') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-vpn-address')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:ipv6-nexthop-global') or " + + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:ipv6-vpn-address')"; description "Set the IPv6 address"; leaf ipv6-address { @@ -929,15 +929,15 @@ identity set-extcommunity-color { } case preference { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-prefer-global') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:ipv6-peer-address')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:ipv6-prefer-global') or " + + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:ipv6-peer-address')"; leaf preference { type boolean; } } case label-index { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:label-index')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:label-index')"; leaf label-index { type uint32 { range "0..1048560"; @@ -946,14 +946,14 @@ identity set-extcommunity-color { } case local-pref { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-local-preference')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-local-preference')"; leaf local-pref { type string; } } case weight { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:weight')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:weight')"; leaf weight { type uint32 { range "0..4294967295"; @@ -962,7 +962,7 @@ identity set-extcommunity-color { } case origin { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-origin')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-origin')"; leaf origin { type enumeration { enum "egp" { @@ -985,14 +985,14 @@ identity set-extcommunity-color { } case originator-id { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:originator-id')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:originator-id')"; leaf originator-id { type inet:ipv4-address; } } case table { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:table')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:table')"; leaf table { type uint32 { range "1..4294967295"; @@ -1001,7 +1001,7 @@ identity set-extcommunity-color { } case atomic-aggregate { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:atomic-aggregate')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:atomic-aggregate')"; leaf atomic-aggregate { type empty; } @@ -1017,7 +1017,7 @@ identity set-extcommunity-color { } case as-path-prepend { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:as-path-prepend')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:as-path-prepend')"; choice as-path-prepend { description "Value of the BGP AS-path attribute"; @@ -1042,7 +1042,7 @@ identity set-extcommunity-color { } case as-path-exclude { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:as-path-exclude')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:as-path-exclude')"; leaf exclude-as-path { type string; description @@ -1051,7 +1051,7 @@ identity set-extcommunity-color { } case as-path-replace { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:as-path-replace')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:as-path-replace')"; leaf replace-as-path { type string; description @@ -1060,7 +1060,7 @@ identity set-extcommunity-color { } case community { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-community')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-community')"; choice community { description "Value of the BGP community attribute"; @@ -1083,7 +1083,7 @@ identity set-extcommunity-color { } case large-community { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:set-large-community')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-large-community')"; choice large-community { description "Value of the BGP large-community attribute"; @@ -1106,7 +1106,7 @@ identity set-extcommunity-color { } case aggregator { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:aggregator')"; + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:aggregator')"; container aggregator { leaf aggregator-asn { type asn-type; @@ -1125,9 +1125,9 @@ identity set-extcommunity-color { } case comm-list-name { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:comm-list-delete') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'frr-bgp-route-map:large-comm-list-delete') or " - + "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, + when "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:comm-list-delete') or " + + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:large-comm-list-delete') or " + + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:extended-comm-list-delete')"; leaf comm-list-name { type bgp-filter:bgp-list-name; @@ -1155,7 +1155,7 @@ identity set-extcommunity-color { } case l3vpn-nexthop-encapsulation { when - "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, + "derived-from-or-self(../frr-route-map:action, 'frr-bgp-route-map:set-l3vpn-nexthop-encapsulation')"; description "Accept L3VPN traffic over other than LSP encapsulation"; diff --git a/yang/frr-ospf-route-map.yang b/yang/frr-ospf-route-map.yang index ad7ba5c1ba2f..6e7c85dc962a 100644 --- a/yang/frr-ospf-route-map.yang +++ b/yang/frr-ospf-route-map.yang @@ -32,7 +32,7 @@ module frr-ospf-route-map { augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:rmap-set-action/frr-route-map:set-action" { case metric-type { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'metric-type')"; + when "derived-from-or-self(../frr-route-map:action, 'metric-type')"; leaf metric-type { type enumeration { enum "type-1" { diff --git a/yang/frr-ospf6-route-map.yang b/yang/frr-ospf6-route-map.yang index e5d4969d45d8..7e2e56de0f13 100644 --- a/yang/frr-ospf6-route-map.yang +++ b/yang/frr-ospf6-route-map.yang @@ -38,7 +38,7 @@ module frr-ospf6-route-map { augment "/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:rmap-set-action/frr-route-map:set-action" { case ipv6-address { - when "derived-from-or-self(/frr-route-map:lib/frr-route-map:route-map/frr-route-map:entry/frr-route-map:set-action/frr-route-map:action, 'forwarding-address')"; + when "derived-from-or-self(../frr-route-map:action, 'forwarding-address')"; leaf ipv6-address { type inet:ipv6-address; } From f766686bce471e95764a94eebbf5e7a5da076a7f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 29 May 2024 14:52:44 -0400 Subject: [PATCH 164/472] tests: Fix zebra_seg6_route Locally this test would occassionally fail for me because the connected route the sharp route being installed has not fully come up yet due to heavy load and start up slowness. Add a bit of code to look for the problem and make sure it doesn't happen. Signed-off-by: Donald Sharp --- .../zebra_seg6_route/r1/routes_setup.json | 28 +++++++++++++++++++ .../zebra_seg6_route/test_zebra_seg6_route.py | 10 +++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/topotests/zebra_seg6_route/r1/routes_setup.json diff --git a/tests/topotests/zebra_seg6_route/r1/routes_setup.json b/tests/topotests/zebra_seg6_route/r1/routes_setup.json new file mode 100644 index 000000000000..d131e4acd4cf --- /dev/null +++ b/tests/topotests/zebra_seg6_route/r1/routes_setup.json @@ -0,0 +1,28 @@ +{ + "2001::/64":[ + { + "prefix":"2001::/64", + "prefixLen":64, + "protocol":"connected", + "vrfName":"default", + "selected":true, + "destSelected":true, + "distance":0, + "metric":0, + "installed":true, + "internalStatus":16, + "internalFlags":8, + "internalNextHopNum":1, + "internalNextHopActiveNum":1, + "nexthops":[ + { + "flags":3, + "fib":true, + "directlyConnected":true, + "interfaceName":"dum0", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py b/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py index f872f7a2587f..4a4cf0624f6b 100755 --- a/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py +++ b/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py @@ -73,6 +73,16 @@ def check(router, dest, expected): return False return topotest.json_cmp(output, expected) + def check_connected(router, dest, expected): + logger.info("Checking for connected") + output = json.loads(router.vtysh_cmd("show ipv6 route {} json".format(dest))) + return topotest.json_cmp(output, expected) + + expected = open_json_file(os.path.join(CWD, "{}/routes_setup.json".format("r1"))) + test_func = partial(check_connected, r1, "2001::/64", expected) + success, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + assert result is None, "Failed to fully setup connected routes needed" + manifests = open_json_file(os.path.join(CWD, "{}/routes.json".format("r1"))) for manifest in manifests: dest = manifest["in"]["dest"] From 826f2510e67711045e52cf4b5e3ddef514ed556e Mon Sep 17 00:00:00 2001 From: Iggy Frankovic Date: Thu, 30 May 2024 07:59:54 -0400 Subject: [PATCH 165/472] ospf6d: Prevent heap-buffer-overflow with unknown type When parsing a osf6 grace lsa field and we receive an unknown tlv type, ospf6d was not incrementing the pointer to get beyond the tlv. Leaving a situation where ospf6d would parse the packet incorrectly. Signed-off-by: Iggy Frankovic --- ospf6d/ospf6_gr_helper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ospf6d/ospf6_gr_helper.c b/ospf6d/ospf6_gr_helper.c index 229e0a4db8ab..f0e5d3a15c24 100644 --- a/ospf6d/ospf6_gr_helper.c +++ b/ospf6d/ospf6_gr_helper.c @@ -176,6 +176,7 @@ static int ospf6_extract_grace_lsa_fields(struct ospf6_lsa *lsa, return OSPF6_FAILURE; break; default: + sum += TLV_SIZE(tlvh); if (IS_DEBUG_OSPF6_GR) zlog_debug("%s, Ignoring unknown TLV type:%d", __func__, ntohs(tlvh->type)); From a4ee9762734332697ba186ae7223da1eb0445cb2 Mon Sep 17 00:00:00 2001 From: dleroy Date: Mon, 29 Apr 2024 09:40:21 -0700 Subject: [PATCH 166/472] nhrpd: fixes core dump on shutdown When nhrpd is shutdown via nhrp_request_stop() the shutdown sequence was not handling the case where there are active shortcut routes installed. The zebra client and shortcut rib were being cleaned up before vrf_terminate() had an opportunity to delete the active routes. Signed-off-by: dleroy --- nhrpd/nhrp_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index adb8be36d303..5d492249d32c 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -83,13 +83,13 @@ static void nhrp_request_stop(void) debugf(NHRP_DEBUG_COMMON, "Exiting..."); frr_early_fini(); - nhrp_shortcut_terminate(); + vrf_terminate(); nhrp_nhs_terminate(); nhrp_zebra_terminate(); vici_terminate(); evmgr_terminate(); - vrf_terminate(); nhrp_vc_terminate(); + nhrp_shortcut_terminate(); debugf(NHRP_DEBUG_COMMON, "Done."); From a7037ab23407d5667385f9be096e347caa0c94ad Mon Sep 17 00:00:00 2001 From: dleroy Date: Mon, 29 Apr 2024 14:59:25 -0700 Subject: [PATCH 167/472] tests: add a topotest to verify nhrp shortcuts in a redundant nhs topology Contains 2 testcases. The first does a basic configuration/connectivity. The second testcase initiates a shortcut through the primary NHS, verifies shortcut routes are installed. Primary NHS interface brought down and verify that the shortcut is not impacted. Finally verify that after the shortcut expires, it is able to be re-established via a backup NHS. Signed-off-by: dleroy --- .../nhrp_redundancy/r1/nhrp_cache.json | 40 ++ .../nhrp_redundancy/r1/nhrp_route.json | 48 ++ tests/topotests/nhrp_redundancy/r1/nhrpd.conf | 9 + tests/topotests/nhrp_redundancy/r1/zebra.conf | 12 + .../nhrp_redundancy/r2/nhrp_cache.json | 40 ++ .../nhrp_redundancy/r2/nhrp_route.json | 48 ++ tests/topotests/nhrp_redundancy/r2/nhrpd.conf | 9 + tests/topotests/nhrp_redundancy/r2/zebra.conf | 12 + .../nhrp_redundancy/r3/nhrp_cache.json | 40 ++ .../nhrp_redundancy/r3/nhrp_route.json | 48 ++ tests/topotests/nhrp_redundancy/r3/nhrpd.conf | 9 + tests/topotests/nhrp_redundancy/r3/zebra.conf | 12 + .../nhrp_redundancy/r4/nhrp_cache.json | 51 +++ .../nhrp_redundancy/r4/nhrp_route.json | 71 +++ .../r4/nhrp_route_shortcut.json | 118 +++++ tests/topotests/nhrp_redundancy/r4/nhrpd.conf | 11 + tests/topotests/nhrp_redundancy/r4/zebra.conf | 16 + .../nhrp_redundancy/r5/nhrp_cache.json | 51 +++ .../nhrp_redundancy/r5/nhrp_route.json | 71 +++ tests/topotests/nhrp_redundancy/r5/nhrpd.conf | 11 + tests/topotests/nhrp_redundancy/r5/zebra.conf | 16 + tests/topotests/nhrp_redundancy/r6/zebra.conf | 7 + tests/topotests/nhrp_redundancy/r7/zebra.conf | 4 + .../nhrp_redundancy/test_nhrp_redundancy.dot | 103 +++++ .../nhrp_redundancy/test_nhrp_redundancy.py | 423 ++++++++++++++++++ 25 files changed, 1280 insertions(+) create mode 100644 tests/topotests/nhrp_redundancy/r1/nhrp_cache.json create mode 100644 tests/topotests/nhrp_redundancy/r1/nhrp_route.json create mode 100644 tests/topotests/nhrp_redundancy/r1/nhrpd.conf create mode 100644 tests/topotests/nhrp_redundancy/r1/zebra.conf create mode 100644 tests/topotests/nhrp_redundancy/r2/nhrp_cache.json create mode 100644 tests/topotests/nhrp_redundancy/r2/nhrp_route.json create mode 100644 tests/topotests/nhrp_redundancy/r2/nhrpd.conf create mode 100644 tests/topotests/nhrp_redundancy/r2/zebra.conf create mode 100644 tests/topotests/nhrp_redundancy/r3/nhrp_cache.json create mode 100644 tests/topotests/nhrp_redundancy/r3/nhrp_route.json create mode 100644 tests/topotests/nhrp_redundancy/r3/nhrpd.conf create mode 100644 tests/topotests/nhrp_redundancy/r3/zebra.conf create mode 100644 tests/topotests/nhrp_redundancy/r4/nhrp_cache.json create mode 100644 tests/topotests/nhrp_redundancy/r4/nhrp_route.json create mode 100644 tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json create mode 100644 tests/topotests/nhrp_redundancy/r4/nhrpd.conf create mode 100644 tests/topotests/nhrp_redundancy/r4/zebra.conf create mode 100644 tests/topotests/nhrp_redundancy/r5/nhrp_cache.json create mode 100644 tests/topotests/nhrp_redundancy/r5/nhrp_route.json create mode 100644 tests/topotests/nhrp_redundancy/r5/nhrpd.conf create mode 100644 tests/topotests/nhrp_redundancy/r5/zebra.conf create mode 100644 tests/topotests/nhrp_redundancy/r6/zebra.conf create mode 100644 tests/topotests/nhrp_redundancy/r7/zebra.conf create mode 100644 tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot create mode 100644 tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py diff --git a/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json new file mode 100644 index 000000000000..a94dd9fecfb1 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json @@ -0,0 +1,40 @@ +{ + "attr": { + "entriesCount": 3 + }, + "table": [ + { + "interface": "r1-gre0", + "type": "dynamic", + "protocol": "176.16.1.4", + "nbma": "192.168.2.4", + "claimed_nbma": "192.168.2.4", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r1-gre0", + "type": "local", + "protocol": "176.16.1.1", + "nbma": "192.168.1.1", + "claimed_nbma": "192.168.1.1", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + }, + { + "interface": "r1-gre0", + "type": "dynamic", + "protocol": "176.16.1.5", + "nbma": "192.168.2.5", + "claimed_nbma": "192.168.2.5", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r1/nhrp_route.json b/tests/topotests/nhrp_redundancy/r1/nhrp_route.json new file mode 100644 index 000000000000..b5f3e29e7418 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/nhrp_route.json @@ -0,0 +1,48 @@ +{ + "176.16.1.4\/32": [ + { + "prefix": "176.16.1.4\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-gre0", + "active": true + } + ] + } + ], + "176.16.1.5\/32": [ + { + "prefix": "176.16.1.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r1-gre0", + "active": true + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r1/nhrpd.conf b/tests/topotests/nhrp_redundancy/r1/nhrpd.conf new file mode 100644 index 000000000000..ad48ce3769a7 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/nhrpd.conf @@ -0,0 +1,9 @@ +!debug nhrp all +nhrp nflog-group 1 +interface r1-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source r1-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r1/zebra.conf b/tests/topotests/nhrp_redundancy/r1/zebra.conf new file mode 100644 index 000000000000..0f11563f575d --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/zebra.conf @@ -0,0 +1,12 @@ +ip forwarding +interface r1-eth0 + ip address 192.168.1.1/24 +! +ip route 192.168.2.0/24 192.168.1.6 +interface r1-gre0 + ip address 176.16.1.1/32 + no link-detect + ipv6 nd suppress-ra +! +ip route 4.4.4.0/24 176.16.1.4 +ip route 5.5.5.0/24 176.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json new file mode 100644 index 000000000000..91557a191826 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json @@ -0,0 +1,40 @@ +{ + "attr": { + "entriesCount": 3 + }, + "table": [ + { + "interface": "r2-gre0", + "type": "local", + "protocol": "176.16.1.2", + "nbma": "192.168.1.2", + "claimed_nbma": "192.168.1.2", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + }, + { + "interface": "r2-gre0", + "type": "dynamic", + "protocol": "176.16.1.4", + "nbma": "192.168.2.4", + "claimed_nbma": "192.168.2.4", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r2-gre0", + "type": "dynamic", + "protocol": "176.16.1.5", + "nbma": "192.168.2.5", + "claimed_nbma": "192.168.2.5", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r2/nhrp_route.json b/tests/topotests/nhrp_redundancy/r2/nhrp_route.json new file mode 100644 index 000000000000..f1fa6e54c1bc --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/nhrp_route.json @@ -0,0 +1,48 @@ +{ + "176.16.1.4\/32": [ + { + "prefix": "176.16.1.4\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r2-gre0", + "active": true + } + ] + } + ], + "176.16.1.5\/32": [ + { + "prefix": "176.16.1.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r2-gre0", + "active": true + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r2/nhrpd.conf b/tests/topotests/nhrp_redundancy/r2/nhrpd.conf new file mode 100644 index 000000000000..4d63f07d1f71 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/nhrpd.conf @@ -0,0 +1,9 @@ +!debug nhrp all +nhrp nflog-group 1 +interface r2-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source r2-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r2/zebra.conf b/tests/topotests/nhrp_redundancy/r2/zebra.conf new file mode 100644 index 000000000000..1a9c4ff91544 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/zebra.conf @@ -0,0 +1,12 @@ +ip forwarding +interface r2-eth0 + ip address 192.168.1.2/24 +! +ip route 192.168.2.0/24 192.168.1.6 +interface r2-gre0 + ip address 176.16.1.2/32 + no link-detect + ipv6 nd suppress-ra +! +ip route 4.4.4.0/24 176.16.1.4 +ip route 5.5.5.0/24 176.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json new file mode 100644 index 000000000000..ef3ab690bc5b --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json @@ -0,0 +1,40 @@ +{ + "attr": { + "entriesCount": 3 + }, + "table": [ + { + "interface": "r3-gre0", + "type": "dynamic", + "protocol": "176.16.1.4", + "nbma": "192.168.2.4", + "claimed_nbma": "192.168.2.4", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r3-gre0", + "type": "local", + "protocol": "176.16.1.3", + "nbma": "192.168.1.3", + "claimed_nbma": "192.168.1.3", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + }, + { + "interface": "r3-gre0", + "type": "dynamic", + "protocol": "176.16.1.5", + "nbma": "192.168.2.5", + "claimed_nbma": "192.168.2.5", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r3/nhrp_route.json b/tests/topotests/nhrp_redundancy/r3/nhrp_route.json new file mode 100644 index 000000000000..3d548c08fdce --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/nhrp_route.json @@ -0,0 +1,48 @@ +{ + "176.16.1.4\/32": [ + { + "prefix": "176.16.1.4\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r3-gre0", + "active": true + } + ] + } + ], + "176.16.1.5\/32": [ + { + "prefix": "176.16.1.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r3-gre0", + "active": true + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r3/nhrpd.conf b/tests/topotests/nhrp_redundancy/r3/nhrpd.conf new file mode 100644 index 000000000000..87cc2161f8bf --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/nhrpd.conf @@ -0,0 +1,9 @@ +!debug nhrp all +nhrp nflog-group 1 +interface r3-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source r3-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r3/zebra.conf b/tests/topotests/nhrp_redundancy/r3/zebra.conf new file mode 100644 index 000000000000..980cfbcaab7d --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/zebra.conf @@ -0,0 +1,12 @@ +ip forwarding +interface r3-eth0 + ip address 192.168.1.3/24 +! +ip route 192.168.2.0/24 192.168.1.6 +interface r3-gre0 + ip address 176.16.1.3/32 + no link-detect + ipv6 nd suppress-ra +! +ip route 4.4.4.0/24 176.16.1.4 +ip route 5.5.5.0/24 176.16.1.5 \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json new file mode 100644 index 000000000000..f87ebcf5fc7e --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json @@ -0,0 +1,51 @@ +{ + "attr": { + "entriesCount": 4 + }, + "table": [ + { + "interface": "r4-gre0", + "type": "nhs", + "protocol": "176.16.1.2", + "nbma": "192.168.1.2", + "claimed_nbma": "192.168.1.2", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r4-gre0", + "type": "local", + "protocol": "176.16.1.4", + "nbma": "192.168.2.4", + "claimed_nbma": "192.168.2.4", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + }, + { + "interface": "r4-gre0", + "type": "nhs", + "protocol": "176.16.1.3", + "nbma": "192.168.1.3", + "claimed_nbma": "192.168.1.3", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r4-gre0", + "type": "nhs", + "protocol": "176.16.1.1", + "nbma": "192.168.1.1", + "claimed_nbma": "192.168.1.1", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_route.json b/tests/topotests/nhrp_redundancy/r4/nhrp_route.json new file mode 100644 index 000000000000..4f1faee7a744 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrp_route.json @@ -0,0 +1,71 @@ +{ + "176.16.1.1\/32": [ + { + "prefix": "176.16.1.1\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ], + "176.16.1.2\/32": [ + { + "prefix": "176.16.1.2\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ], + "176.16.1.3\/32": [ + { + "prefix": "176.16.1.3\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json b/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json new file mode 100644 index 000000000000..f8efff2059e4 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json @@ -0,0 +1,118 @@ +{ + "5.5.5.5\/32": [ + { + "prefix": "5.5.5.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "ip": "176.16.1.5", + "afi": "ipv4", + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ], + "176.16.1.1\/32": [ + { + "prefix": "176.16.1.1\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ], + "176.16.1.2\/32": [ + { + "prefix": "176.16.1.2\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ], + "176.16.1.3\/32": [ + { + "prefix": "176.16.1.3\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ], + "176.16.1.5\/32": [ + { + "prefix": "176.16.1.5\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r4-gre0", + "active": true + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrpd.conf b/tests/topotests/nhrp_redundancy/r4/nhrpd.conf new file mode 100644 index 000000000000..8a52f3386e89 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrpd.conf @@ -0,0 +1,11 @@ +!debug nhrp all +interface r4-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp nhs dynamic nbma 192.168.1.1 + ip nhrp nhs dynamic nbma 192.168.1.2 + ip nhrp nhs dynamic nbma 192.168.1.3 + ip nhrp shortcut + tunnel source r4-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r4/zebra.conf b/tests/topotests/nhrp_redundancy/r4/zebra.conf new file mode 100644 index 000000000000..e4a9a6f80f74 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/zebra.conf @@ -0,0 +1,16 @@ +ip forwarding +interface r4-eth0 + ip address 192.168.2.4/24 +! +ip route 192.168.1.0/24 192.168.2.6 +interface r4-gre0 + ip address 176.16.1.4/32 + no link-detect + ipv6 nd suppress-ra +! +interface r4-eth1 + ip address 4.4.4.4/24 +! +ip route 0.0.0.0/0 176.16.1.1 50 +ip route 0.0.0.0/0 176.16.1.2 60 +ip route 0.0.0.0/0 176.16.1.3 70 \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json new file mode 100644 index 000000000000..bc041c601475 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json @@ -0,0 +1,51 @@ +{ + "attr": { + "entriesCount": 4 + }, + "table": [ + { + "interface": "r5-gre0", + "type": "nhs", + "protocol": "176.16.1.2", + "nbma": "192.168.1.2", + "claimed_nbma": "192.168.1.2", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r5-gre0", + "type": "nhs", + "protocol": "176.16.1.3", + "nbma": "192.168.1.3", + "claimed_nbma": "192.168.1.3", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r5-gre0", + "type": "nhs", + "protocol": "176.16.1.1", + "nbma": "192.168.1.1", + "claimed_nbma": "192.168.1.1", + "used": false, + "timeout": true, + "auth": false, + "identity": "" + }, + { + "interface": "r5-gre0", + "type": "local", + "protocol": "176.16.1.5", + "nbma": "192.168.2.5", + "claimed_nbma": "192.168.2.5", + "used": false, + "timeout": false, + "auth": false, + "identity": "-" + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrp_route.json b/tests/topotests/nhrp_redundancy/r5/nhrp_route.json new file mode 100644 index 000000000000..1d1c16ffb86b --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/nhrp_route.json @@ -0,0 +1,71 @@ +{ + "176.16.1.1\/32": [ + { + "prefix": "176.16.1.1\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r5-gre0", + "active": true + } + ] + } + ], + "176.16.1.2\/32": [ + { + "prefix": "176.16.1.2\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r5-gre0", + "active": true + } + ] + } + ], + "176.16.1.3\/32": [ + { + "prefix": "176.16.1.3\/32", + "protocol": "nhrp", + "vrfId": 0, + "vrfName": "default", + "selected": true, + "destSelected": true, + "distance": 10, + "metric": 0, + "installed": true, + "internalNextHopNum": 1, + "internalNextHopActiveNum": 1, + "nexthops": [ + { + "fib": true, + "directlyConnected": true, + "interfaceName": "r5-gre0", + "active": true + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrpd.conf b/tests/topotests/nhrp_redundancy/r5/nhrpd.conf new file mode 100644 index 000000000000..7241ed592da8 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/nhrpd.conf @@ -0,0 +1,11 @@ +!debug nhrp all +interface r5-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp nhs dynamic nbma 192.168.1.1 + ip nhrp nhs dynamic nbma 192.168.1.2 + ip nhrp nhs dynamic nbma 192.168.1.3 + ip nhrp registration no-unique + ip nhrp shortcut + tunnel source r5-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r5/zebra.conf b/tests/topotests/nhrp_redundancy/r5/zebra.conf new file mode 100644 index 000000000000..9b1e1c0646e3 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/zebra.conf @@ -0,0 +1,16 @@ +ip forwarding +interface r5-eth0 + ip address 192.168.2.5/24 +! +ip route 192.168.1.0/24 192.168.2.6 +interface r5-gre0 + ip address 176.16.1.5/32 + no link-detect + ipv6 nd suppress-ra +! +interface r5-eth1 + ip address 5.5.5.5/24 +! +ip route 0.0.0.0/0 176.16.1.1 50 +ip route 0.0.0.0/0 176.16.1.2 60 +ip route 0.0.0.0/0 176.16.1.3 70 diff --git a/tests/topotests/nhrp_redundancy/r6/zebra.conf b/tests/topotests/nhrp_redundancy/r6/zebra.conf new file mode 100644 index 000000000000..63a37cd5bf38 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r6/zebra.conf @@ -0,0 +1,7 @@ +ip forwarding +interface r6-eth0 + ip address 192.168.1.6/24 +! +interface r6-eth1 + ip address 192.168.2.6/24 +exit diff --git a/tests/topotests/nhrp_redundancy/r7/zebra.conf b/tests/topotests/nhrp_redundancy/r7/zebra.conf new file mode 100644 index 000000000000..5747b409561e --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r7/zebra.conf @@ -0,0 +1,4 @@ +interface r7-eth0 + ip address 4.4.4.7/24 +! +ip route 0.0.0.0/0 4.4.4.4 diff --git a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot new file mode 100644 index 000000000000..c169436db04f --- /dev/null +++ b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot @@ -0,0 +1,103 @@ +## Color coding: +######################### +## Main FRR: #f08080 red +## Switches: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #fcb314 dark yellow +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +##### Colors (see http://www.color-hex.com/) + +graph template { + label="nhrp-topo-redundant-nhs"; + + # Routers + r1 [ + shape=doubleoctagon, + label="NHS 1", + fillcolor="#f08080", + style=filled, + ]; + r2 [ + shape=doubleoctagon + label="NHS 2", + fillcolor="#f08080", + style=filled, + ]; + r3 [ + shape=doubleoctagon + label="NHS 3", + fillcolor="#f08080", + style=filled, + ]; + r4 [ + shape=doubleoctagon + label="NHC 1", + fillcolor="#f08080", + style=filled, + ]; + r5 [ + shape=doubleoctagon + label="NHC 2", + fillcolor="#f08080", + style=filled, + ]; + r6 [ + shape=doubleoctagon + label="router", + fillcolor="#f08080", + style=filled, + ]; + r7 [ + shape=doubleoctagon + label="host", + fillcolor="#f08080", + style=filled, + ]; + + # Switches + sw1 [ + shape=oval, + label="sw1\n192.168.1.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + sw2 [ + shape=oval, + label="sw2\n192.168.2.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + sw3 [ + shape=oval, + label="sw3\n4.4.4.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + sw4 [ + shape=oval, + label="sw4\n5.5.5.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + + # Connections + r1 -- sw1 [label="eth0"]; + r2 -- sw1 [label="eth0"]; + r3 -- sw1 [label="eth0"]; + r6 -- sw1 [label="eth0"]; + + r4 -- sw2 [label="eth0"]; + r5 -- sw2 [label="eth0"]; + r6 -- sw2 [label="eth1"]; + + r4 -- sw3 [label="eth1"]; + r7 -- sw3 [label="eth0"]; + + r5 -- sw4 [label="eth1"]; + +} diff --git a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py new file mode 100644 index 000000000000..81a22ebfaf5d --- /dev/null +++ b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py @@ -0,0 +1,423 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0-or-later +# +# test_nhrp_redundancy.py +# +# Copyright 2024, LabN Consulting, L.L.C. +# Dave LeRoy +# + +import os +import sys +import json +from time import sleep +from functools import partial +import pytest + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from lib.common_config import ( + required_linux_kernel_version, + shutdown_bringup_interface, + retry, +) + +""" +test_nhrp_redundancy.py: Test NHS redundancy for NHRP +""" + +TOPOLOGY = """ ++------------+ +------------+ +------------+ +| | | | | | +| | | | | | +| NHS 1 | | NHS 2 | | NHS 3 | +| | | | | | ++-----+------+ +-----+------+ +-----+------+ + |.1 |.2 |.3 + | | | + | | 192.168.1.0/24 | +------+-------------------------------+------------------+-------------+------ + | + |.6 + GRE P2MP between all NHS and NHC +-----+------+ + 172.16.1.x/32 | | + | | + | Router | + | | + +-----+------+ + | + | + ---------+----------------+-------------+------ + | 192.168.2.0/24 | + | | + | |.4 |.5 ++------------+ | +-------+----+ +------+-----+ | +| | | | | | | | +| | +--------+ | | | | +| Host |.7 | | NHC 1 | | NHC 2 +-----+5.5.5.0/24 +| +---------+ | | | | | ++------------+ | +------------+ +------------+ | + | | + 4.4.4.0/24 +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# Required to instantiate the topology builder class. + +pytestmark = [pytest.mark.nhrpd] + + +def build_topo(tgen): + "Build function" + + # Create 7 routers + for routern in range(1, 8): + tgen.add_router("r{}".format(routern)) + + # Interconnect routers 1, 2, 3, 6 + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r6"]) + + # Interconnect routers 4, 5, 6 + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["r5"]) + switch.add_link(tgen.gears["r6"]) + + # Connect router 4, 7 + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["r7"]) + + # Connect router 5 + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r5"]) + + +def _populate_iface(): + tgen = get_topogen() + cmds_tot_hub = [ + "ip tunnel add {0}-gre0 mode gre ttl 64 key 42 dev {0}-eth0 local 192.168.1.{1} remote 0.0.0.0", + "ip link set dev {0}-gre0 up", + "echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu", + "echo 1 > /proc/sys/net/ipv6/conf/{0}-eth0/disable_ipv6", + "echo 1 > /proc/sys/net/ipv6/conf/{0}-gre0/disable_ipv6", + "iptables -A FORWARD -i {0}-gre0 -o {0}-gre0 -m hashlimit --hashlimit-upto 4/minute --hashlimit-burst 1 --hashlimit-mode srcip,dstip --hashlimit-srcmask 24 --hashlimit-dstmask 24 --hashlimit-name loglimit-0 -j NFLOG --nflog-group 1 --nflog-range 128", + ] + + cmds_tot = [ + "ip tunnel add {0}-gre0 mode gre ttl 64 key 42 dev {0}-eth0 local 192.168.2.{1} remote 0.0.0.0", + "ip link set dev {0}-gre0 up", + "echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu", + "echo 1 > /proc/sys/net/ipv6/conf/{0}-eth0/disable_ipv6", + "echo 1 > /proc/sys/net/ipv6/conf/{0}-gre0/disable_ipv6", + ] + + for cmd in cmds_tot_hub: + # Router 1 + input = cmd.format("r1", "1") + logger.info("input: " + input) + output = tgen.net["r1"].cmd(input) + logger.info("output: " + output) + + # Router 2 + input = cmd.format("r2", "2") + logger.info("input: " + input) + output = tgen.net["r2"].cmd(input) + logger.info("output: " + output) + + # Router 3 + input = cmd.format("r3", "3") + logger.info("input: " + input) + output = tgen.net["r3"].cmd(input) + logger.info("output: " + output) + + for cmd in cmds_tot: + input = cmd.format("r4", "4") + logger.info("input: " + input) + output = tgen.net["r4"].cmd(input) + logger.info("output: " + output) + + input = cmd.format("r5", "5") + logger.info("input: " + input) + output = tgen.net["r5"].cmd(input) + logger.info("output: " + output) + + +def _verify_iptables(): + tgen = get_topogen() + # Verify iptables is installed. Required for shortcuts + rc, _, _ = tgen.net["r1"].cmd_status("iptables") + return False if rc == 127 else True + + +def setup_module(mod): + logger.info("NHRP Redundant NHS:\n {}".format(TOPOLOGY)) + + result = required_linux_kernel_version("5.0") + if result is not True: + pytest.skip("Kernel requirements are not met") + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + # Starting Routers + router_list = tgen.routers() + _populate_iface() + + for rname, router in router_list.items(): + router.load_config( + TopoRouter.RD_ZEBRA, + os.path.join(CWD, "{}/zebra.conf".format(rname)), + ) + if rname in ("r1", "r2", "r3", "r4", "r5"): + router.load_config( + TopoRouter.RD_NHRP, os.path.join(CWD, "{}/nhrpd.conf".format(rname)) + ) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(_mod): + "Teardown the pytest environment" + tgen = get_topogen() + tgen.stop_topology() + + +def test_protocols_convergence(): + """ + Assert that all protocols have converged before checking for the NHRP + statuses as they depend on it. + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Checking NHRP cache and IPv4 routes for convergence") + router_list = tgen.routers() + + # Check NHRP cache on servers and clients + for rname, router in router_list.items(): + + json_file = "{}/{}/nhrp_cache.json".format(CWD, router.name) + if not os.path.isfile(json_file): + logger.info("skipping file {}".format(json_file)) + continue + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip nhrp cache json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = router.vtysh_cmd("show ip nhrp cache") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + # Check NHRP IPV4 routes on servers and clients + for rname, router in router_list.items(): + + json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) + if not os.path.isfile(json_file): + logger.info("skipping file {}".format(json_file)) + continue + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = router.vtysh_cmd("show ip route nhrp") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + # Test connectivity from 1 NHRP server to all clients + pingrouter = tgen.gears["r1"] + logger.info("Check Ping IPv4 from R1 to R4 = 176.16.1.4)") + output = pingrouter.run("ping 176.16.1.4 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R1 to R4 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1 to R4 OK") + + logger.info("Check Ping IPv4 from R1 to R5 = 176.16.1.5)") + output = pingrouter.run("ping 176.16.1.5 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R1 to R5 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1 to R5 OK") + + # Test connectivity from 1 NHRP client to all servers + pingrouter = tgen.gears["r4"] + logger.info("Check Ping IPv4 from R4 to R1 = 176.16.1.1)") + output = pingrouter.run("ping 176.16.1.1 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R4 to R1 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R4 to R1 OK") + + logger.info("Check Ping IPv4 from R4 to R2 = 176.16.1.2)") + output = pingrouter.run("ping 176.16.1.2 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R4 to R2 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R4 to R2 OK") + + logger.info("Check Ping IPv4 from R4 to R3 = 176.16.1.3)") + output = pingrouter.run("ping 176.16.1.3 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R4 to R3 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R4 to R3 OK") + + +@retry(retry_timeout=30, initial_wait=5) +def verify_shortcut_path(): + """ + Verifying that traffic flows through shortcut path + """ + tgen = get_topogen() + pingrouter = tgen.gears["r7"] + logger.info("Check Ping IPv4 from R7 to R5 = 5.5.5.5") + + output = pingrouter.run("ping 5.5.5.5 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R7 to R5 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R7 to R5 OK") + + +def test_redundancy_shortcut(): + """ + Assert that if shortcut created and then NHS goes down, there is no traffic disruption + Stop traffic and verify next time traffic started, shortcut is initiated by backup NHS + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + if not _verify_iptables(): + pytest.skip("iptables not installed") + + logger.info("Testing NHRP shortcuts with redundant servers") + + # Verify R4 nhrp routes before shortcut creation + router = tgen.gears["r4"] + json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) + assertmsg = "No nhrp_route file found" + assert os.path.isfile(json_file), assertmsg + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = router.vtysh_cmd("show ip route nhrp") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + # Initiate shortcut by pinging between clients + pingrouter = tgen.gears["r7"] + logger.info("Check Ping IPv4 from R7 to R5 via shortcut = 5.5.5.5") + + output = pingrouter.run("ping 5.5.5.5 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R7 to R5 via shortcut should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R7 to R5 via shortcut OK") + + # Now check that NHRP shortcut route installed + json_file = "{}/{}/nhrp_route_shortcut.json".format(CWD, router.name) + assertmsg = "No nhrp_route file found" + assert os.path.isfile(json_file), assertmsg + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = router.vtysh_cmd("show ip route nhrp") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + # Bring down primary GRE interface and verify shortcut is not disturbed + logger.info("Bringing down R1, primary NHRP server.") + shutdown_bringup_interface(tgen, "r1", "r1-gre0", False) + + # Verify shortcut is still active + pingrouter = tgen.gears["r7"] + logger.info("Check Ping IPv4 from R7 to R5 via shortcut = 5.5.5.5") + + output = pingrouter.run("ping 5.5.5.5 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = "expected ping IPv4 from R7 to R5 via shortcut should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R7 to R5 via shortcut OK") + + # Now verify shortcut is purged with lack of traffic + json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) + assertmsg = "No nhrp_route file found" + assert os.path.isfile(json_file), assertmsg + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, router, "show ip route nhrp json", expected + ) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + + output = router.vtysh_cmd("show ip route nhrp") + logger.info(output) + + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From a951960a15e8b6b5ed248abb0ecc9eb4e9a3427f Mon Sep 17 00:00:00 2001 From: Jafar Al-Gharaibeh Date: Thu, 30 May 2024 12:46:47 -0500 Subject: [PATCH 168/472] pimd: fix crash when mixing ssm/any-source joins There is no reason to call `igmp_anysource_forward_stop()` inside a call to `igmp_get_source_by_addr()`; not only it is not expected for a "get" function to perform such an action, but also the decision to start/stop forwarding is already handled correctly by pim outside `igmp_get_source_by_addr()`. That call was left there from the days pim was initially imported into the sources. The problem/crash was happening because `igmp_find_source_by_addr()` would fail to find the group/source combo when mixing `(*, G)` and `(S, G)`. When having an existing flow `(*, G)`, and a new `(S, G)` igmp is received, a new entry is correctly created. `igmp_anysource_forward_stop(group)` always stops and eventually frees `(*, G)`, even when the new igmp is `(S, G)`, leaving a bad state. I.e, the new entry for `(S, G)` causes `(*, G)` to be deleted. Tested the fix with multiple receivers on the same interface with several ssm and any source senders and receivers with various combination of start/stop orders and they all worked correctly. Fixes: #15630 Signed-off-by: Jafar Al-Gharaibeh --- pimd/pim_igmpv3.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/pimd/pim_igmpv3.c b/pimd/pim_igmpv3.c index 18a9fb7c6c76..2c5ad4d44b1b 100644 --- a/pimd/pim_igmpv3.c +++ b/pimd/pim_igmpv3.c @@ -457,8 +457,6 @@ struct gm_source *igmp_get_source_by_addr(struct gm_group *group, listnode_add(group->group_source_list, src); - /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */ - igmp_anysource_forward_stop(group); return src; } From cd5791c12e97f2ca3c8820ae6e0c51b30eec118c Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Wed, 29 May 2024 02:38:01 -0400 Subject: [PATCH 169/472] tests: fix multiple grpc-client.py running in parallel Signed-off-by: Christian Hopps --- tests/topotests/lib/grpc-query.py | 58 ++++++++++++++++++------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/tests/topotests/lib/grpc-query.py b/tests/topotests/lib/grpc-query.py index c9b79b0bdc99..13b63614c77a 100755 --- a/tests/topotests/lib/grpc-query.py +++ b/tests/topotests/lib/grpc-query.py @@ -10,36 +10,46 @@ import logging import os import sys +import tempfile import pytest CWD = os.path.dirname(os.path.realpath(__file__)) -# This is painful but works if you have installed grpc and grpc_tools would be *way* -# better if we actually built and installed these but ... python packaging. try: - import grpc_tools - - import grpc - - sys.path.append(os.path.dirname(CWD)) - from munet.base import commander - - commander.cmd_raises(f"cp {CWD}/../../../grpc/frr-northbound.proto .") - commander.cmd_raises( - "python3 -m grpc_tools.protoc --python_out=. --grpc_python_out=. -I . frr-northbound.proto" - ) -except Exception as error: - logging.error("can't create proto definition modules %s", error) - raise - -try: - sys.path[0:0] = "." - import frr_northbound_pb2 - import frr_northbound_pb2_grpc -except Exception as error: - logging.error("can't import proto definition modules %s", error) - raise + # Make sure we don't run-into ourselves in parallel operating environment + tmpdir = tempfile.mkdtemp(prefix="grpc-client-") + + # This is painful but works if you have installed grpc and grpc_tools would be *way* + # better if we actually built and installed these but ... python packaging. + try: + import grpc_tools + from munet.base import commander + + import grpc + + commander.cmd_raises(f"cp {CWD}/../../../grpc/frr-northbound.proto .") + commander.cmd_raises( + "python3 -m grpc_tools.protoc" + f" --python_out={tmpdir} --grpc_python_out={tmpdir}" + f" -I {CWD}/../../../grpc frr-northbound.proto" + ) + except Exception as error: + logging.error("can't create proto definition modules %s", error) + raise + + try: + sys.path[0:0] = [tmpdir] + print(sys.path) + import frr_northbound_pb2 + import frr_northbound_pb2_grpc + + sys.path = sys.path[1:] + except Exception as error: + logging.error("can't import proto definition modules %s", error) + raise +finally: + commander.cmd_nostatus(f"rm -rf {tmpdir}") class GRPCClient: From 5032be4f1c1e262af6d463d91e9d5bddd7f91651 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Wed, 29 May 2024 03:32:46 -0400 Subject: [PATCH 170/472] tests: fix pim test to wait for actual OSPF route convergence Signed-off-by: Christian Hopps --- .../pim_igmp_vrf/r1/ospf_blue_route.json | 54 +++++++++++++ .../pim_igmp_vrf/r1/ospf_red_route.json | 54 +++++++++++++ tests/topotests/pim_igmp_vrf/r1/ospfd.conf | 2 + tests/topotests/pim_igmp_vrf/r1/pimd.conf | 1 + tests/topotests/pim_igmp_vrf/r11/ospfd.conf | 2 + tests/topotests/pim_igmp_vrf/r12/ospfd.conf | 2 + tests/topotests/pim_igmp_vrf/test_pim_vrf.py | 76 ++++++++++++++++--- 7 files changed, 179 insertions(+), 12 deletions(-) create mode 100644 tests/topotests/pim_igmp_vrf/r1/ospf_blue_route.json create mode 100644 tests/topotests/pim_igmp_vrf/r1/ospf_red_route.json diff --git a/tests/topotests/pim_igmp_vrf/r1/ospf_blue_route.json b/tests/topotests/pim_igmp_vrf/r1/ospf_blue_route.json new file mode 100644 index 000000000000..c5e89d18e87b --- /dev/null +++ b/tests/topotests/pim_igmp_vrf/r1/ospf_blue_route.json @@ -0,0 +1,54 @@ +{ + "blue": { + "vrfName": "blue", + "192.168.0.1/32": { + "routeType": "N", + "transit": false, + "cost": 0, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": " ", + "directlyAttachedTo": "blue" + } + ] + }, + "192.168.0.11/32": { + "routeType": "N", + "transit": false, + "cost": 10, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": "192.168.101.11", + "via": "r1-eth1", + "advertisedRouter": "192.168.0.11" + } + ] + }, + "192.168.100.0/24": { + "routeType": "N", + "transit": false, + "cost": 10, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": " ", + "directlyAttachedTo": "r1-eth0" + } + ] + }, + "192.168.101.0/24": { + "routeType": "N", + "transit": true, + "cost": 10, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": " ", + "directlyAttachedTo": "r1-eth1" + } + ] + } + } +} diff --git a/tests/topotests/pim_igmp_vrf/r1/ospf_red_route.json b/tests/topotests/pim_igmp_vrf/r1/ospf_red_route.json new file mode 100644 index 000000000000..2fc340d4c899 --- /dev/null +++ b/tests/topotests/pim_igmp_vrf/r1/ospf_red_route.json @@ -0,0 +1,54 @@ +{ + "red": { + "vrfName": "red", + "192.168.0.1/32": { + "routeType": "N", + "transit": false, + "cost": 0, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": " ", + "directlyAttachedTo": "red" + } + ] + }, + "192.168.0.12/32": { + "routeType": "N", + "transit": false, + "cost": 10, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": "192.168.101.12", + "via": "r1-eth3", + "advertisedRouter": "192.168.0.12" + } + ] + }, + "192.168.100.0/24": { + "routeType": "N", + "transit": false, + "cost": 10, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": " ", + "directlyAttachedTo": "r1-eth2" + } + ] + }, + "192.168.101.0/24": { + "routeType": "N", + "transit": true, + "cost": 10, + "area": "0.0.0.0", + "nexthops": [ + { + "ip": " ", + "directlyAttachedTo": "r1-eth3" + } + ] + } + } +} diff --git a/tests/topotests/pim_igmp_vrf/r1/ospfd.conf b/tests/topotests/pim_igmp_vrf/r1/ospfd.conf index 88eb5a8a054c..9b9a261b1d31 100644 --- a/tests/topotests/pim_igmp_vrf/r1/ospfd.conf +++ b/tests/topotests/pim_igmp_vrf/r1/ospfd.conf @@ -1,6 +1,8 @@ hostname r1 ! ! debug ospf event +! debug ospf nsm +! debug ospf packet hello ! ! interface r1-eth1 diff --git a/tests/topotests/pim_igmp_vrf/r1/pimd.conf b/tests/topotests/pim_igmp_vrf/r1/pimd.conf index 040c3d01b1d0..c4ddced0227a 100644 --- a/tests/topotests/pim_igmp_vrf/r1/pimd.conf +++ b/tests/topotests/pim_igmp_vrf/r1/pimd.conf @@ -2,6 +2,7 @@ hostname r1 ! ! debug igmp events ! debug igmp packets +! debug mroute detail ! debug pim events ! debug pim packets ! debug pim trace diff --git a/tests/topotests/pim_igmp_vrf/r11/ospfd.conf b/tests/topotests/pim_igmp_vrf/r11/ospfd.conf index 86fb66db6175..e52737cb1841 100644 --- a/tests/topotests/pim_igmp_vrf/r11/ospfd.conf +++ b/tests/topotests/pim_igmp_vrf/r11/ospfd.conf @@ -1,6 +1,8 @@ hostname r11 ! ! debug ospf event +! debug ospf nsm +! debug ospf packet hello ! interface r11-eth0 ip ospf hello-interval 2 diff --git a/tests/topotests/pim_igmp_vrf/r12/ospfd.conf b/tests/topotests/pim_igmp_vrf/r12/ospfd.conf index f0dcabece2c3..cd944061f776 100644 --- a/tests/topotests/pim_igmp_vrf/r12/ospfd.conf +++ b/tests/topotests/pim_igmp_vrf/r12/ospfd.conf @@ -1,6 +1,8 @@ hostname r12 ! ! debug ospf event +! debug ospf nsm +! debug ospf packet hello ! interface r12-eth0 ip ospf hello-interval 2 diff --git a/tests/topotests/pim_igmp_vrf/test_pim_vrf.py b/tests/topotests/pim_igmp_vrf/test_pim_vrf.py index ddc430330d3d..01c496d70388 100755 --- a/tests/topotests/pim_igmp_vrf/test_pim_vrf.py +++ b/tests/topotests/pim_igmp_vrf/test_pim_vrf.py @@ -60,7 +60,7 @@ +---------+ +------------+ | +---------+ | Host H1 | 192.168.100.0/24 | | .1 | .11 | Host H2 | | receive |------------------| VRF Blue |---------+--------| PIM RP | -|IGMP JOIN| .10 .1 | | 192.168.101.0/24 | | +|IGMP JOIN| .10 .1 | | 192.168.101.0/24 | | +---------+ | | +---------+ =| = = R1 = = |= +---------+ | | +---------+ @@ -68,7 +68,7 @@ | receive |------------------| VRF Red |---------+--------| PIM RP | |IGMP JOIN| .20 .1 | | .1 | .12 | | +---------+ +------------+ | +---------+ - .4 | + .4 | +----------+ | Host H4 | | Source | @@ -80,6 +80,7 @@ import os import sys import pytest +import logging # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -91,7 +92,7 @@ from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from lib.topotest import iproute2_is_vrf_capable -from lib.common_config import required_linux_kernel_version +from lib.common_config import required_linux_kernel_version, retry from lib.pim import McastTesterHelper @@ -192,6 +193,17 @@ def setup_module(module): tgen.start_router() + # iproute2 needs to support VRFs for this suite to run. + if not iproute2_is_vrf_capable(): + pytest.skip( + "Installed iproute2 version does not support VRFs", allow_module_level=True + ) + + if os.getenv("MROUTE_VRF_MISSING"): + pytest.skip( + "Kernel does not support vrf mroute tables.", allow_module_level=True + ) + def teardown_module(module): tgen = get_topogen() @@ -202,16 +214,13 @@ def test_ospf_convergence(): "Test for OSPFv2 convergence" tgen = get_topogen() - # iproute2 needs to support VRFs for this suite to run. - if not iproute2_is_vrf_capable(): - pytest.skip("Installed iproute2 version does not support VRFs") - # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) logger.info("Checking OSPFv2 convergence on router r1 for VRF blue") + # Check for blue neighbor router = tgen.gears["r1"] reffile = os.path.join(CWD, "r1/ospf_blue_neighbor.json") expected = json.loads(open(reffile).read()) @@ -223,7 +232,22 @@ def test_ospf_convergence(): expected, ) _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) - assertmsg = "OSPF router R1 did not converge on VRF blue" + assertmsg = "OSPF router R1 did not converge on VRF blue (nbr)" + assert res is None, assertmsg + + # Check for blue loopback route + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/ospf_blue_route.json") + expected = json.loads(open(reffile).read()) + + test_func = functools.partial( + topotest.router_json_cmp, + router, + "show ip ospf vrf blue route json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=2) + assertmsg = "OSPF router R1 did not converge on VRF blue (route)" assert res is None, assertmsg logger.info("Checking OSPFv2 convergence on router r1 for VRF red") @@ -236,7 +260,22 @@ def test_ospf_convergence(): topotest.router_json_cmp, router, "show ip ospf vrf red neighbor json", expected ) _, res = topotest.run_and_expect(test_func, None, count=60, wait=2) - assertmsg = "OSPF router R1 did not converge on VRF red" + assertmsg = "OSPF router R1 did not converge on VRF red (nbr)" + assert res is None, assertmsg + + # Check for red loopback route + router = tgen.gears["r1"] + reffile = os.path.join(CWD, "r1/ospf_red_route.json") + expected = json.loads(open(reffile).read()) + + test_func = functools.partial( + topotest.router_json_cmp, + router, + "show ip ospf vrf red route json", + expected, + ) + _, res = topotest.run_and_expect(test_func, None, count=30, wait=2) + assertmsg = "OSPF router R1 did not converge on VRF red (route)" assert res is None, assertmsg @@ -275,10 +314,13 @@ def test_pim_convergence(): assert res is None, assertmsg -def test_vrf_pimreg_interfaces(): +def _test_vrf_pimreg_interfaces(): "Adding PIM RP in VRF information and verify pimreg interfaces" tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + r1 = tgen.gears["r1"] r1.vtysh_cmd("conf\ninterface blue\nip pim") r1.vtysh_cmd("conf\nvrf blue\nip pim rp 192.168.0.11 239.100.0.1/32\nexit-vrf") @@ -292,7 +334,7 @@ def test_vrf_pimreg_interfaces(): "show ip pim vrf blue inter pimreg11 json", expected, ) - _, res = topotest.run_and_expect(test_func, None, count=5, wait=2) + _, res = topotest.run_and_expect(test_func, None, count=15, wait=2) assertmsg = "PIM router R1, VRF blue (table 11) pimreg11 interface missing or incorrect status" assert res is None, assertmsg @@ -308,10 +350,20 @@ def test_vrf_pimreg_interfaces(): "show ip pim vrf red inter pimreg12 json", expected, ) - _, res = topotest.run_and_expect(test_func, None, count=5, wait=2) + _, res = topotest.run_and_expect(test_func, None, count=15, wait=2) assertmsg = "PIM router R1, VRF red (table 12) pimreg12 interface missing or incorrect status" assert res is None, assertmsg +def test_vrf_pimreg_interfaces(): + tgen = get_topogen() + r1 = tgen.gears["r1"] + try: + _test_vrf_pimreg_interfaces() + except Exception: + # get some debug info. + output = r1.net.cmd_nostatus("ip -o link") + logging.error("ip link info after failure: %s", output) + raise ################################## ### Test PIM / IGMP with VRF From e855436cc6ce125dad989f4d8cd7b27510710ee0 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Wed, 29 May 2024 08:07:47 -0400 Subject: [PATCH 171/472] tests: all errors go to log (and thus stderr) Only output requested information to stdout so it can be filtered and captured in shell variables etc... Signed-off-by: Christian Hopps --- tests/topotests/analyze.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/topotests/analyze.py b/tests/topotests/analyze.py index 690786a07c53..a1ac9a2212bb 100755 --- a/tests/topotests/analyze.py +++ b/tests/topotests/analyze.py @@ -262,7 +262,7 @@ def main(): capture_output=True, ) except subprocess.CalledProcessError: - print(f"{docker_bin} container '{contid}' does not exist") + logging.critical(f"{docker_bin} container '{contid}' does not exist") sys.exit(1) # If you need container info someday... # cont_info = json.loads(p.stdout) @@ -278,7 +278,7 @@ def main(): if scount and args.results and not os.path.exists(args.results): if not contid: if not os.path.exists(cppath): - print(f"'{cppath}' doesn't exist to save") + logging.critical(f"'{cppath}' doesn't exist to save") sys.exit(1) if args.save_xml: subprocess.run(["cp", cppath, args.results]) @@ -294,7 +294,7 @@ def main(): capture_output=True, ) except subprocess.CalledProcessError as error: - print(f"Can't {docker_bin} cp '{cppath}': %s", str(error)) + logging.critical(f"Can't {docker_bin} cp '{cppath}': %s", str(error)) sys.exit(1) if "SUDO_USER" in os.environ: @@ -303,7 +303,7 @@ def main(): # User doesn't want to save results just use them inplace if not contid: if not os.path.exists(cppath): - print(f"'{cppath}' doesn't exist") + logging.critical(f"'{cppath}' doesn't exist") sys.exit(1) args.results = cppath else: @@ -321,7 +321,7 @@ def main(): capture_output=True, ) except subprocess.CalledProcessError as error: - print(f"Can't {docker_bin} cp '{cppath}': %s", str(error)) + logging.critical(f"Can't {docker_bin} cp '{cppath}': %s", str(error)) sys.exit(1) args.results = tresname From 30d3b4d47e3c4dfd5229781bb5e45eac2004a38a Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Wed, 29 May 2024 09:54:35 -0400 Subject: [PATCH 172/472] tests: use raw string for doc to avoid deprecated python warning Signed-off-by: Christian Hopps --- tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py index 0058f213da81..911a6d757f8a 100644 --- a/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py @@ -32,7 +32,7 @@ def build_topo(tgen): - """ + r""" +---+ | h1| +---+ From 5daf64f63bffcda54b36eb99288515189f8e4f0b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 31 May 2024 11:30:52 +0200 Subject: [PATCH 173/472] lib: make python/ts_expand.py actually work lib/typesafe.h was supposed to be outside the _TYPESAFE_EXPAND_MACROS guard, so that including lib/atomlist.h grabs all the typesafe container macros. (No effect on normal build, as _TYPESAFE_EXPAND_MACROS is never defined there.) Signed-off-by: David Lamparter --- lib/atomlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/atomlist.h b/lib/atomlist.h index faf1d7324e58..3eb498a23a17 100644 --- a/lib/atomlist.h +++ b/lib/atomlist.h @@ -6,8 +6,8 @@ #ifndef _FRR_ATOMLIST_H #define _FRR_ATOMLIST_H -#ifndef _TYPESAFE_EXPAND_MACROS #include "typesafe.h" +#ifndef _TYPESAFE_EXPAND_MACROS #include "frratomic.h" #endif /* _TYPESAFE_EXPAND_MACROS */ From 637ab53f75a9288888dfb48b8b939833fa3501ed Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 31 May 2024 15:03:55 +0300 Subject: [PATCH 174/472] bgpd: Send End-of-RIB not only if Graceful Restart capability is received Before we checked for received Graceful Restart capability, but that was also incorrect, because we SHOULD HAVE checked it per AFI/SAFI instead. https://datatracker.ietf.org/doc/html/rfc4724 says: Although the End-of-RIB marker is specified for the purpose of BGP graceful restart, it is noted that the generation of such a marker upon completion of the initial update would be useful for routing convergence in general, and thus the practice is recommended. Thus, it might be reasonable to send EoR regardless of whether the Graceful Restart capability is received or not from the peer. Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 65 ++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 86f85dd86662..3f38790cbda3 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -560,40 +560,37 @@ void bgp_generate_updgrp_packets(struct event *thread) } } - if (CHECK_FLAG(peer->cap, - PEER_CAP_RESTART_RCV)) { - if (!(PAF_SUBGRP(paf))->t_coalesce - && peer->afc_nego[afi][safi] - && peer->synctime - && !CHECK_FLAG( - peer->af_sflags[afi][safi], - PEER_STATUS_EOR_SEND)) { - /* If EOR is disabled, - * the message is not sent - */ - if (BGP_SEND_EOR(peer->bgp, afi, - safi)) { - SET_FLAG( - peer->af_sflags - [afi] - [safi], - PEER_STATUS_EOR_SEND); - - /* Update EOR - * send time - */ - peer->eor_stime[afi] - [safi] = - monotime(NULL); - - BGP_UPDATE_EOR_PKT( - peer, afi, safi, - s); - bgp_process_pending_refresh( - peer, afi, - safi); - } - } + /* rfc4724 says: + * Although the End-of-RIB marker is + * specified for the purpose of BGP + * graceful restart, it is noted that + * the generation of such a marker upon + * completion of the initial update would + * be useful for routing convergence in + * general, and thus the practice is + * recommended. + */ + if (!(PAF_SUBGRP(paf))->t_coalesce && + peer->afc_nego[afi][safi] && + peer->synctime && + !CHECK_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_EOR_SEND)) { + /* If EOR is disabled, the message is + * not sent. + */ + if (!BGP_SEND_EOR(peer->bgp, afi, safi)) + continue; + + SET_FLAG(peer->af_sflags[afi][safi], + PEER_STATUS_EOR_SEND); + + /* Update EOR send time */ + peer->eor_stime[afi][safi] = + monotime(NULL); + + BGP_UPDATE_EOR_PKT(peer, afi, safi, s); + bgp_process_pending_refresh(peer, afi, + safi); } continue; } From 75e87501425e85360b48882569d100175f19ca4a Mon Sep 17 00:00:00 2001 From: Mike RE Mallin Date: Fri, 31 May 2024 09:41:07 -0400 Subject: [PATCH 175/472] lib: Add SET_IPADDR_NONE macro Signed-off-by: Mike RE Mallin --- lib/ipaddr.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/ipaddr.h b/lib/ipaddr.h index c86e38c867c0..e8f87374773c 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -40,8 +40,9 @@ struct ipaddr { #define IS_IPADDR_V4(p) ((p)->ipa_type == IPADDR_V4) #define IS_IPADDR_V6(p) ((p)->ipa_type == IPADDR_V6) -#define SET_IPADDR_V4(p) (p)->ipa_type = IPADDR_V4 -#define SET_IPADDR_V6(p) (p)->ipa_type = IPADDR_V6 +#define SET_IPADDR_NONE(p) ((p)->ipa_type = IPADDR_NONE) +#define SET_IPADDR_V4(p) ((p)->ipa_type = IPADDR_V4) +#define SET_IPADDR_V6(p) ((p)->ipa_type = IPADDR_V6) #define IPADDRSZ(p) \ (IS_IPADDR_V4((p)) ? sizeof(struct in_addr) : sizeof(struct in6_addr)) From f381bc21482d0177cb81a8fe4ff687470dde2c3a Mon Sep 17 00:00:00 2001 From: Mike RE Mallin Date: Fri, 31 May 2024 09:42:12 -0400 Subject: [PATCH 176/472] lib: Add ipaddr_is_same to compare IPv6 addresses Signed-off-by: Mike RE Mallin --- lib/ipaddr.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/ipaddr.h b/lib/ipaddr.h index e8f87374773c..76c7c15ffd48 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -166,6 +166,12 @@ static inline bool ipaddr_is_zero(const struct ipaddr *ip) return true; } +static inline bool ipaddr_is_same(const struct ipaddr *ip1, + const struct ipaddr *ip2) +{ + return ipaddr_cmp(ip1, ip2) == 0; +} + #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pIA" (struct ipaddr *) #endif From b30523d3c9cdec301653d0c5d3dc689eda5f3fba Mon Sep 17 00:00:00 2001 From: Mike RE Mallin Date: Tue, 21 May 2024 10:07:43 -0400 Subject: [PATCH 177/472] lib: Add clang-format wrapper around printfrr_ext Signed-off-by: Mike RE Mallin --- lib/ipaddr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ipaddr.h b/lib/ipaddr.h index 76c7c15ffd48..888955fba0ab 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -172,9 +172,11 @@ static inline bool ipaddr_is_same(const struct ipaddr *ip1, return ipaddr_cmp(ip1, ip2) == 0; } +/* clang-format off */ #ifdef _FRR_ATTRIBUTE_PRINTFRR #pragma FRR printfrr_ext "%pIA" (struct ipaddr *) #endif +/* clang-format on */ #ifdef __cplusplus } From b69ec60dc6e1f7942a5818b9d7154c1caa0f4441 Mon Sep 17 00:00:00 2001 From: Mike RE Mallin Date: Tue, 21 May 2024 10:09:02 -0400 Subject: [PATCH 178/472] lib: Make the ip arg const in stream_put_ipaddr Signed-off-by: Mike RE Mallin --- lib/stream.c | 2 +- lib/stream.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/stream.c b/lib/stream.c index fa20ebdbe715..bb90f3b944e9 100644 --- a/lib/stream.c +++ b/lib/stream.c @@ -921,7 +921,7 @@ int stream_put_in_addr(struct stream *s, const struct in_addr *addr) return sizeof(uint32_t); } -bool stream_put_ipaddr(struct stream *s, struct ipaddr *ip) +bool stream_put_ipaddr(struct stream *s, const struct ipaddr *ip) { stream_putw(s, ip->ipa_type); diff --git a/lib/stream.h b/lib/stream.h index 61eaa46c95d0..e48cedc61345 100644 --- a/lib/stream.h +++ b/lib/stream.h @@ -175,7 +175,7 @@ extern int stream_putq(struct stream *, uint64_t); extern int stream_putq_at(struct stream *, size_t, uint64_t); extern int stream_put_ipv4(struct stream *, uint32_t); extern int stream_put_in_addr(struct stream *s, const struct in_addr *addr); -extern bool stream_put_ipaddr(struct stream *s, struct ipaddr *ip); +extern bool stream_put_ipaddr(struct stream *s, const struct ipaddr *ip); extern int stream_put_in_addr_at(struct stream *s, size_t putp, const struct in_addr *addr); extern int stream_put_in6_addr_at(struct stream *s, size_t putp, From f4f19cc20f73c692a7eead14d4c82740576ea059 Mon Sep 17 00:00:00 2001 From: Mike RE Mallin Date: Fri, 31 May 2024 10:08:59 -0400 Subject: [PATCH 179/472] lib, zebra: Update prefix_sg structure for IPv6 group support Signed-off-by: Mike RE Mallin --- lib/prefix.c | 15 +++++++-- lib/prefix.h | 4 ++- zebra/zebra_vxlan.c | 81 ++++++++++++++++++++++++++++----------------- 3 files changed, 65 insertions(+), 35 deletions(-) diff --git a/lib/prefix.c b/lib/prefix.c index f342c4c1dbea..2485c3e61bdd 100644 --- a/lib/prefix.c +++ b/lib/prefix.c @@ -1124,6 +1124,15 @@ const char *prefix2str(union prefixconstptr pu, char *str, int size) return str; } +void prefix_mcast_ip_dump(const char *onfail, const struct ipaddr *addr, + char *buf, int buf_size) +{ + if (ipaddr_is_zero(addr)) + strlcpy(buf, "*", buf_size); + else + (void)snprintfrr(buf, buf_size, "%pIA", addr); +} + static ssize_t prefixhost2str(struct fbuf *fbuf, union prefixconstptr pu) { const struct prefix *p = pu.p; @@ -1166,7 +1175,7 @@ const char *prefix_sg2str(const struct prefix_sg *sg, char *sg_str) char src_str[INET_ADDRSTRLEN]; char grp_str[INET_ADDRSTRLEN]; - prefix_mcast_inet4_dump("", sg->src, src_str, sizeof(src_str)); + prefix_mcast_ip_dump("", &sg->src, src_str, sizeof(src_str)); prefix_mcast_inet4_dump("", sg->grp, grp_str, sizeof(grp_str)); snprintf(sg_str, PREFIX_SG_STR_LEN, "(%s,%s)", src_str, grp_str); @@ -1637,10 +1646,10 @@ static ssize_t printfrr_psg(struct fbuf *buf, struct printfrr_eargs *ea, if (!sg) return bputs(buf, "(null)"); - if (sg->src.s_addr == INADDR_ANY) + if (ipaddr_is_zero(&sg->src)) ret += bputs(buf, "(*,"); else - ret += bprintfrr(buf, "(%pI4,", &sg->src); + ret += bprintfrr(buf, "(%pIA,", &sg->src); if (sg->grp.s_addr == INADDR_ANY) ret += bputs(buf, "*)"); diff --git a/lib/prefix.h b/lib/prefix.h index 14f269593341..48388cd019eb 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -282,7 +282,7 @@ struct prefix_fs { struct prefix_sg { uint8_t family; uint16_t prefixlen; - struct in_addr src __attribute__((aligned(8))); + struct ipaddr src __attribute__((aligned(8))); struct in_addr grp; }; @@ -415,6 +415,8 @@ extern int str2prefix(const char *string, struct prefix *prefix); #define PREFIX2STR_BUFFER PREFIX_STRLEN +extern void prefix_mcast_ip_dump(const char *onfail, const struct ipaddr *addr, + char *buf, int buf_size); extern void prefix_mcast_inet4_dump(const char *onfail, struct in_addr addr, char *buf, int buf_size); extern const char *prefix_sg2str(const struct prefix_sg *sg, char *str); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 65dc6638bc32..b8c11e186a7b 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -108,10 +108,11 @@ static void zevpn_build_hash_table(void); static unsigned int zebra_vxlan_sg_hash_key_make(const void *p); static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2); static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf, - struct in_addr sip, struct in_addr mcast_grp); -static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf, - struct in_addr sip, - struct in_addr mcast_grp); + const struct ipaddr *sip, + const struct in_addr mcast_grp); +static struct zebra_vxlan_sg * +zebra_vxlan_sg_do_ref(struct zebra_vrf *vrf, const struct ipaddr *sip, + const struct in_addr mcast_grp); static void zebra_vxlan_cleanup_sg_table(struct zebra_vrf *zvrf); bool zebra_evpn_do_dup_addr_detect(struct zebra_vrf *zvrf) @@ -5891,7 +5892,10 @@ static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf, zclient_create_header(s, cmd, VRF_DEFAULT); stream_putl(s, IPV4_MAX_BYTELEN); - stream_put(s, &sg->src.s_addr, IPV4_MAX_BYTELEN); + /* + * There is currently no support for IPv6 VTEPs with PIM. + */ + stream_put(s, &sg->src.ipaddr_v4, IPV4_MAX_BYTELEN); stream_put(s, &sg->grp.s_addr, IPV4_MAX_BYTELEN); /* Write packet size. */ @@ -5914,9 +5918,17 @@ static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf, static unsigned int zebra_vxlan_sg_hash_key_make(const void *p) { const struct zebra_vxlan_sg *vxlan_sg = p; + uint32_t hash1; - return (jhash_2words(vxlan_sg->sg.src.s_addr, - vxlan_sg->sg.grp.s_addr, 0)); + if (IS_IPADDR_V4(&vxlan_sg->sg.src)) { + return (jhash_2words(vxlan_sg->sg.src.ipaddr_v4.s_addr, + vxlan_sg->sg.grp.s_addr, 0)); + } else { + hash1 = jhash_1word(vxlan_sg->sg.grp.s_addr, 0); + return jhash2(vxlan_sg->sg.src.ipaddr_v6.s6_addr32, + array_size(vxlan_sg->sg.src.ipaddr_v6.s6_addr32), + hash1); + } } static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2) @@ -5924,8 +5936,8 @@ static bool zebra_vxlan_sg_hash_eq(const void *p1, const void *p2) const struct zebra_vxlan_sg *sg1 = p1; const struct zebra_vxlan_sg *sg2 = p2; - return ((sg1->sg.src.s_addr == sg2->sg.src.s_addr) - && (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr)); + return (ipaddr_is_same(&sg1->sg.src, &sg2->sg.src) && + (sg1->sg.grp.s_addr == sg2->sg.grp.s_addr)); } static struct zebra_vxlan_sg *zebra_vxlan_sg_new(struct zebra_vrf *zvrf, @@ -5961,7 +5973,7 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf, { struct zebra_vxlan_sg *vxlan_sg; struct zebra_vxlan_sg *parent = NULL; - struct in_addr sip; + struct ipaddr sip; vxlan_sg = zebra_vxlan_sg_find(zvrf, sg); if (vxlan_sg) @@ -5972,9 +5984,9 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf, * 2. the XG entry is used by pimd to setup the * vxlan-termination-mroute */ - if (sg->src.s_addr != INADDR_ANY) { + if (!ipaddr_is_zero(&sg->src)) { memset(&sip, 0, sizeof(sip)); - parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp); + parent = zebra_vxlan_sg_do_ref(zvrf, &sip, sg->grp); if (!parent) return NULL; } @@ -5989,7 +6001,7 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_add(struct zebra_vrf *zvrf, static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg) { - struct in_addr sip; + struct ipaddr sip; struct zebra_vrf *zvrf; zvrf = vrf_info_lookup(VRF_DEFAULT); @@ -5997,13 +6009,13 @@ static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg) /* On SG entry deletion remove the reference to its parent XG * entry */ - if (vxlan_sg->sg.src.s_addr != INADDR_ANY) { + if (!ipaddr_is_zero(&vxlan_sg->sg.src)) { memset(&sip, 0, sizeof(sip)); - zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp); + zebra_vxlan_sg_do_deref(zvrf, &sip, vxlan_sg->sg.grp); } - zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg, - vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL); + zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg, vxlan_sg->sg_str, + ZEBRA_VXLAN_SG_DEL); hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg); @@ -6014,14 +6026,15 @@ static void zebra_vxlan_sg_del(struct zebra_vxlan_sg *vxlan_sg) } static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf, - struct in_addr sip, struct in_addr mcast_grp) + const struct ipaddr *sip, + const struct in_addr mcast_grp) { struct zebra_vxlan_sg *vxlan_sg; struct prefix_sg sg; sg.family = AF_INET; sg.prefixlen = IPV4_MAX_BYTELEN; - sg.src = sip; + sg.src = *sip; sg.grp = mcast_grp; vxlan_sg = zebra_vxlan_sg_find(zvrf, &sg); if (!vxlan_sg) @@ -6034,16 +6047,16 @@ static void zebra_vxlan_sg_do_deref(struct zebra_vrf *zvrf, zebra_vxlan_sg_del(vxlan_sg); } -static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf, - struct in_addr sip, - struct in_addr mcast_grp) +static struct zebra_vxlan_sg * +zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf, const struct ipaddr *sip, + const struct in_addr mcast_grp) { struct zebra_vxlan_sg *vxlan_sg; struct prefix_sg sg; sg.family = AF_INET; sg.prefixlen = IPV4_MAX_BYTELEN; - sg.src = sip; + sg.src = *sip; sg.grp = mcast_grp; vxlan_sg = zebra_vxlan_sg_add(zvrf, &sg); if (vxlan_sg) @@ -6052,10 +6065,10 @@ static struct zebra_vxlan_sg *zebra_vxlan_sg_do_ref(struct zebra_vrf *zvrf, return vxlan_sg; } -void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip, - struct in_addr mcast_grp) +void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip, struct in_addr mcast_grp) { struct zebra_vrf *zvrf; + struct ipaddr local_vtep_ipaddr; if (local_vtep_ip.s_addr == INADDR_ANY || mcast_grp.s_addr == INADDR_ANY) @@ -6063,20 +6076,26 @@ void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip, zvrf = vrf_info_lookup(VRF_DEFAULT); - zebra_vxlan_sg_do_deref(zvrf, local_vtep_ip, mcast_grp); + SET_IPADDR_V4(&local_vtep_ipaddr); + local_vtep_ipaddr.ipaddr_v4 = local_vtep_ip; + + zebra_vxlan_sg_do_deref(zvrf, &local_vtep_ipaddr, mcast_grp); } void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip, struct in_addr mcast_grp) { struct zebra_vrf *zvrf; + struct ipaddr local_vtep_ipaddr; - if (local_vtep_ip.s_addr == INADDR_ANY - || mcast_grp.s_addr == INADDR_ANY) + if (local_vtep_ip.s_addr == INADDR_ANY || mcast_grp.s_addr == INADDR_ANY) return; zvrf = vrf_info_lookup(VRF_DEFAULT); - zebra_vxlan_sg_do_ref(zvrf, local_vtep_ip, mcast_grp); + SET_IPADDR_V4(&local_vtep_ipaddr); + local_vtep_ipaddr.ipaddr_v4 = local_vtep_ip; + + zebra_vxlan_sg_do_ref(zvrf, &local_vtep_ipaddr, mcast_grp); } static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg) @@ -6086,7 +6105,7 @@ static void zebra_vxlan_xg_pre_cleanup(struct hash_bucket *bucket, void *arg) /* increment the ref count against (*,G) to prevent them from being * deleted */ - if (vxlan_sg->sg.src.s_addr == INADDR_ANY) + if (ipaddr_is_zero(&vxlan_sg->sg.src)) ++vxlan_sg->ref_cnt; } @@ -6095,7 +6114,7 @@ static void zebra_vxlan_xg_post_cleanup(struct hash_bucket *bucket, void *arg) struct zebra_vxlan_sg *vxlan_sg = (struct zebra_vxlan_sg *)bucket->data; /* decrement the dummy ref count against (*,G) to delete them */ - if (vxlan_sg->sg.src.s_addr == INADDR_ANY) { + if (ipaddr_is_zero(&vxlan_sg->sg.src)) { if (vxlan_sg->ref_cnt) --vxlan_sg->ref_cnt; if (!vxlan_sg->ref_cnt) From f450332476e6358ccdab9810ab45b0e6f85da4be Mon Sep 17 00:00:00 2001 From: Mike RE Mallin Date: Tue, 21 May 2024 10:16:09 -0400 Subject: [PATCH 180/472] tests: Extend prefix_sg print UT for IPv6 Signed-off-by: Mike RE Mallin --- tests/lib/test_printfrr.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c index cefa07ec7323..a81ebcdbcd78 100644 --- a/tests/lib/test_printfrr.c +++ b/tests/lib/test_printfrr.c @@ -230,19 +230,25 @@ int main(int argc, char **argv) printchk("02:ca:fe:f0:0d:1e", "%pFXh", &pfx); struct prefix_sg sg; - sg.src.s_addr = INADDR_ANY; + SET_IPADDR_V4(&sg.src); + sg.src.ipaddr_v4.s_addr = INADDR_ANY; sg.grp.s_addr = INADDR_ANY; printchk("(*,*)", "%pPSG4", &sg); - inet_aton("192.168.1.2", &sg.src); + inet_aton("192.168.1.2", &sg.src.ipaddr_v4); printchk("(192.168.1.2,*)", "%pPSG4", &sg); inet_aton("224.1.2.3", &sg.grp); printchk("(192.168.1.2,224.1.2.3)", "%pPSG4", &sg); - sg.src.s_addr = INADDR_ANY; + SET_IPADDR_NONE(&sg.src); + sg.src.ipaddr_v4.s_addr = INADDR_ANY; printchk("(*,224.1.2.3)", "%pPSG4", &sg); + SET_IPADDR_V6(&sg.src); + inet_pton(AF_INET6, "1:2:3:4::5", &sg.src.ipaddr_v6); + printchk("(1:2:3:4::5,224.1.2.3)", "%pPSG4", &sg); + uint8_t randhex[] = { 0x12, 0x34, 0x00, 0xca, 0xfe, 0x00, 0xaa, 0x55 }; FMT_NSTD(printchk("12 34 00 ca fe 00 aa 55", "%.8pHX", randhex)); From a514e34e30c64d52d6bf23f27319880348c6c7f2 Mon Sep 17 00:00:00 2001 From: Mike RE Mallin Date: Tue, 21 May 2024 10:27:17 -0400 Subject: [PATCH 181/472] bgpd, lib, zebra: Extend ES_VTEP_LIST_STR_SZ to support IPv6 addresses Signed-off-by: Mike RE Mallin --- bgpd/bgp_evpn_mh.c | 4 ++-- lib/prefix.h | 6 +++--- zebra/zebra_evpn_mh.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index d63e011560a5..7bad0bc3413a 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -2455,7 +2455,7 @@ static void bgp_evpn_es_frag_show_detail(struct vty *vty, } static char *bgp_evpn_es_vteps_str(char *vtep_str, struct bgp_evpn_es *es, - uint8_t vtep_str_size) + size_t vtep_str_size) { char vtep_flag_str[BGP_EVPN_FLAG_STR_SZ]; struct listnode *node; @@ -3956,7 +3956,7 @@ void bgp_evpn_vni_es_cleanup(struct bgpevpn *vpn) static char *bgp_evpn_es_evi_vteps_str(char *vtep_str, struct bgp_evpn_es_evi *es_evi, - uint8_t vtep_str_size) + size_t vtep_str_size) { char vtep_flag_str[BGP_EVPN_FLAG_STR_SZ]; struct listnode *node; diff --git a/lib/prefix.h b/lib/prefix.h index 48388cd019eb..2d679d06224f 100644 --- a/lib/prefix.h +++ b/lib/prefix.h @@ -52,10 +52,10 @@ typedef enum { /* Maximum number of VTEPs per-ES - * XXX - temporary limit for allocating strings etc. */ -#define ES_VTEP_MAX_CNT 10 -#define ES_VTEP_LIST_STR_SZ (ES_VTEP_MAX_CNT * 16) +#define ES_VTEP_MAX_CNT 10 +#define ES_VTEP_LIST_STR_SZ (ES_VTEP_MAX_CNT * IPADDR_STRING_SIZE) -#define ETHER_ADDR_STRLEN (3*ETH_ALEN) +#define ETHER_ADDR_STRLEN (3 * ETH_ALEN) /* * there isn't a portable ethernet address type. We define our * own to simplify internal handling diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 5c19d226b16a..75e7e20176a9 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -3026,7 +3026,7 @@ void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up) } static char *zebra_evpn_es_vtep_str(char *vtep_str, struct zebra_evpn_es *es, - uint8_t vtep_str_size) + size_t vtep_str_size) { struct zebra_evpn_es_vtep *zvtep; struct listnode *node; From 854caad3eaa3927e9e163862e87d7162c24ae476 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Mon, 19 Feb 2024 10:30:13 -0500 Subject: [PATCH 182/472] docker: update docker reference to follow latest docs Signed-off-by: Christian Hopps --- docker/ubuntu-ci/Dockerfile | 26 +++++++++++++++----------- docker/ubuntu-ci/docker-start | 5 +---- docker/ubuntu22-ci/README.md | 21 +++++++++++++++------ 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/docker/ubuntu-ci/Dockerfile b/docker/ubuntu-ci/Dockerfile index 5a49806581e3..5c4649dc325c 100644 --- a/docker/ubuntu-ci/Dockerfile +++ b/docker/ubuntu-ci/Dockerfile @@ -23,13 +23,17 @@ RUN apt update && apt upgrade -y && \ libreadline-dev \ libsnmp-dev \ libsqlite3-dev \ + lsb-release \ libtool \ + lcov \ make \ perl \ pkg-config \ python3-dev \ python3-sphinx \ + screen \ texinfo \ + tmux \ && \ # Protobuf build requirements apt-get install -y \ @@ -89,18 +93,14 @@ RUN groupadd -r -g 92 frr && \ echo 'frr ALL = NOPASSWD: ALL' | tee /etc/sudoers.d/frr && \ mkdir -p /home/frr && chown frr.frr /home/frr -USER frr:frr +# Install FRR built packages +RUN mkdir -p /etc/apt/keyrings && \ + curl -s -o /etc/apt/keyrings/frrouting.gpg https://deb.frrouting.org/frr/keys.gpg && \ + echo deb '[signed-by=/etc/apt/keyrings/frrouting.gpg]' https://deb.frrouting.org/frr \ + $(lsb_release -s -c) "frr-stable" > /etc/apt/sources.list.d/frr.list && \ + apt-get update && apt-get install -y librtr-dev libyang2-dev libyang2-tools -# build and install libyang2 -RUN cd && pwd && ls -al && \ - git clone https://github.com/CESNET/libyang.git && \ - cd libyang && \ - git checkout v2.1.128 && \ - mkdir build; cd build && \ - cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \ - -DCMAKE_BUILD_TYPE:String="Release" .. && \ - make -j $(nproc) && \ - sudo make install +USER frr:frr COPY --chown=frr:frr . /home/frr/frr/ @@ -111,6 +111,10 @@ RUN cd ~/frr && \ --sysconfdir=/etc \ --localstatedir=/var \ --sbindir=/usr/lib/frr \ + --enable-gcov \ + --enable-dev-build \ + --enable-mgmtd-test-be-client \ + --enable-rpki \ --enable-sharpd \ --enable-multipath=64 \ --enable-user=frr \ diff --git a/docker/ubuntu-ci/docker-start b/docker/ubuntu-ci/docker-start index 9a45c722f1b8..c383ea8ee929 100755 --- a/docker/ubuntu-ci/docker-start +++ b/docker/ubuntu-ci/docker-start @@ -1,8 +1,5 @@ #!/bin/bash - if [ $(uname -a | grep -ci Ubuntu) -ge 1 ]; then - #for topotests under ubuntu host - sudo modprobe mpls-router mpls-iptunnel - sudo /etc/init.d/openvswitch-switch start + sudo modprobe mpls-router mpls-iptunnel vrf fi while true ; do sleep 365d ; done diff --git a/docker/ubuntu22-ci/README.md b/docker/ubuntu22-ci/README.md index 73f4a1011b40..617192eb71b2 100644 --- a/docker/ubuntu22-ci/README.md +++ b/docker/ubuntu22-ci/README.md @@ -8,10 +8,18 @@ This builds an ubuntu 22.04 container for dev / test docker build -t frr-ubuntu22:latest -f docker/ubuntu-ci/Dockerfile . ``` -# Running Full Topotest +# Run ``` -docker run --init -it --privileged --name frr-ubuntu22 -v /lib/modules:/lib/modules frr-ubuntu22:latest bash -c 'cd ~/frr/tests/topotests ; sudo pytest -nauto --dist=loadfile' +docker run -d --init --privileged --name frr-ubuntu22 --mount type=bind,source=/lib/modules,target=/lib/modules frr-ubuntu22:latest +``` + +# Running full topotest (container stops at end) + +``` +docker run --init -it --privileged --name frr-ubuntu22 \ + -v /lib/modules:/lib/modules frr-ubuntu22:latest \ + bash -c 'cd /home/frr/frr/tests/topotests; sudo pytest -nauto --dist=loadfile' ``` # Extract results from the above run into `run-results` dir and analyze @@ -20,10 +28,11 @@ docker run --init -it --privileged --name frr-ubuntu22 -v /lib/modules:/lib/modu tests/topotests/analyze.py -C frr-ubuntu22 -Ar run-results ``` -# Running +# Extract coverage from a stopped container into host FRR source tree ``` -docker run -d --init --privileged --name frr-ubuntu22 --mount type=bind,source=/lib/modules,target=/lib/modules frr-ubuntu22:latest +docker export frr-ubuntu22 | tar --strip=3 --wildcards -vx '*.gc??' +lcov -b $(pwd) --capture --directory . --output-file=coverage.info ``` # make check @@ -38,10 +47,10 @@ docker exec frr-ubuntu22 bash -c 'cd ~/frr ; make check' docker exec -it frr-ubuntu22 bash ``` -# topotest -- when Host O/S is Ubuntu only +# Run a specific topotest ``` -docker exec frr-ubuntu22 bash -c 'cd ~/frr/tests/topotests/ospf_topo1 ; sudo pytest test_ospf_topo1.py' +docker exec frr-ubuntu22 bash -c 'cd ~/frr/tests/topotests ; sudo pytest ospf_topo1/test_ospf_topo1.py' ``` # stop & remove container From 5ef144ce6d03d2dc2d36cf7d0e6ef6ce8ba6d2dc Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 30 May 2024 15:48:33 -0400 Subject: [PATCH 183/472] pimd: Give a clearer warning when the kernel is not compiled right When the kernel is not compiled with mroute vrf's enabled it will fail the call to initialize the vrf. As such let's recognize this specific error code and output a specific warning to the operator to help them figure this problem out. Signed-off-by: Donald Sharp --- pimd/pim_mroute.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index c63e0f35d469..adc47e719d24 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -56,10 +56,14 @@ int pim_mroute_set(struct pim_instance *pim, int enable) err = setsockopt(pim->mroute_socket, PIM_IPPROTO, MRT_TABLE, &data, data_len); if (err) { - zlog_warn( - "%s %s: failure: setsockopt(fd=%d,PIM_IPPROTO, MRT_TABLE=%d): errno=%d: %s", - __FILE__, __func__, pim->mroute_socket, - data, errno, safe_strerror(errno)); + if (err == ENOPROTOOPT) + zlog_err("%s Kernel is not compiled with CONFIG_IP_MROUTE_MULTIPLE_TABLES and vrf's will not work", + __func__); + else + zlog_warn("%s %s: failure: setsockopt(fd=%d,PIM_IPPROTO, MRT_TABLE=%d): errno=%d: %s", + __FILE__, __func__, + pim->mroute_socket, data, + errno, safe_strerror(errno)); return -1; } } From 15a33df79cc9643630de2515cc6a37dd8ae5e882 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Thu, 30 May 2024 20:48:06 -0400 Subject: [PATCH 184/472] github: add docker build and test github action Signed-off-by: Christian Hopps --- .github/workflows/build-test-docker.yml | 161 ++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 .github/workflows/build-test-docker.yml diff --git a/.github/workflows/build-test-docker.yml b/.github/workflows/build-test-docker.yml new file mode 100644 index 000000000000..de9f620c9d5f --- /dev/null +++ b/.github/workflows/build-test-docker.yml @@ -0,0 +1,161 @@ +name: build-test + +on: + pull_request: + push: + branches: + - 'master' + - 'stable/**' + +defaults: + run: + shell: bash + +jobs: + build-docker: + name: Build the ubuntu 22.04 docker image + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Build docker image + run: | + docker build -t frr-ubuntu22 -f docker/ubuntu-ci/Dockerfile . + docker save --output /tmp/frr-ubuntu22.tar frr-ubuntu22 + - name: Upload docker image artifact + uses: actions/upload-artifact@v4 + with: + name: ubuntu-image + path: /tmp/frr-ubuntu22.tar + - name: Clear any previous results + # So if all jobs are re-run then all tests will be re-run + run: | + rm -rf test-results* + mkdir -p test-results + touch test-results/cleared-results.txt + - name: Save cleared previous results + uses: actions/upload-artifact@v4 + with: + name: test-results + path: test-results + overwrite: true + - name: Cleanup + if: ${{ always() }} + run: rm -rf test-results* /tmp/frr-ubuntu22.tar + + test-docker: + name: Test ubuntu docker image + needs: build-docker + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: Fetch docker image artifact + uses: actions/download-artifact@v4 + with: + name: ubuntu-image + path: /tmp + - name: Fetch previous results + if: ${{ github.run_attempt > 1 }} + uses: actions/download-artifact@v4 + with: + name: test-results + path: test-results + - name: Run topotests + run: | + uname -a + sudo apt-get install -y linux-modules-extra-azure || true + sudo apt-get install -y python3-xmltodict || true + sudo modprobe vrf || true + sudo modprobe mpls-iptunnel || true + sudo modprobe mpls-router || true + docker load --input /tmp/frr-ubuntu22.tar + + if ! grep CONFIG_IP_MROUTE_MULTIPLE_TABLES=y /boot/config*; then + ADD_DOCKER_ENV+="-e MROUTE_VRF_MISSING=1" + fi + echo "ADD_DOCKER_ENV: ${ADD_DOCKER_ENV}" + + if [ -f test-results/topotests.xml ]; then + ./tests/topotests/analyze.py -r test-results + ls -l test-results/topotests.xml + run_tests=$(./tests/topotests/analyze.py -r test-results | cut -f1 -d: | sort -u) + else + echo "No test results dir" + run_tests="" + fi + rm -rf test-results* /tmp/topotests + + echo RUN_TESTS: $run_tests + if docker run --init -i --privileged --name frr-ubuntu-cont ${ADD_DOCKER_ENV} -v /lib/modules:/lib/modules frr-ubuntu22 \ + bash -c 'cd ~/frr/tests/topotests ; sudo -E pytest -n$(($(nproc) * 5 / 2)) --dist=loadfile '$run_tests; then + echo "All tests passed." + exit 0 + fi + + # Grab the results from the container + if ! ./tests/topotests/analyze.py -Ar test-results -C frr-ubuntu-cont; then + if [ ! -d test-results ]; then + echo "ERROR: Basic failure in docker run, no test results directory available." >&2 + exit 1; + fi + if [ ! -f test-results/topotests.xml ]; then + # In this case we may be missing topotests.xml + echo "ERROR: No topotests.xml available perhaps docker run aborted?" >&2 + exit 1; + fi + echo "WARNING: analyyze.py returned error but grabbed results anyway." >&2 + fi + + # Save some information useful for debugging + cp /boot/config* test-results/ + sysctl -a > test-results/sysctl.out 2> /dev/null + + # Now get the failed tests (if any) from the archived results directory. + rerun_tests=$(./tests/topotests/analyze.py -r test-results | cut -f1 -d: | sort -u) + if [ -z "$rerun_tests" ]; then + echo "All tests passed during parallel run." + exit 0 + fi + + echo "ERROR: Some tests failed during parallel run, rerunning serially." >&2 + echo RERUN_TESTS: $rerun_tests >&2 + docker stop frr-ubuntu-cont + docker rm frr-ubuntu-cont + + mv test-results test-results-initial + if docker run --init -i --privileged --name frr-ubuntu-cont ${ADD_DOCKER_ENV} -v /lib/modules:/lib/modules frr-ubuntu22 \ + bash -c 'cd ~/frr/tests/topotests ; sudo -E pytest '$rerun_tests; then + echo "All rerun tests passed." + exit 0 + fi + echo "Some rerun tests still failed." + exit 1 + - name: Gather results + if: ${{ always() }} + run: | + if [ ! -d test-results ]; then + if ! ./tests/topotests/analyze.py -Ar test-results -C frr-ubuntu-cont; then + echo "ERROR: gathering results produced an error, perhaps due earlier run cancellation." >&2 + fi + fi + - name: Upload test results + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: test-results + path: | + test-results + test-results-initial + overwrite: true + - name: Cleanup + if: ${{ always() }} + run: | + rm -rf test-results* /tmp/frr-ubuntu22.tar + docker stop frr-ubuntu-cont || true + docker rm frr-ubuntu-cont || true + From 172dd682d907c1e694db7e6d9d7d2023b3b566c5 Mon Sep 17 00:00:00 2001 From: David Ward Date: Sun, 2 Jun 2024 06:42:23 -0400 Subject: [PATCH 185/472] bgpd: Adjust terminology related to DSCP The default DSCP used for BGP connections is CS6. The DSCP value is not part of the TCP header. When setting the IP_TOS or IPV6_TCLASS socket options, the argument is not the 6-bit DSCP value, but an 8-bit value for the former IPv4 Type of Service field or IPv6 Traffic Class field, respectively. Fixes: 425bd64be847 ("bgpd: Allow bgp to control the DSCP session TOS value") Signed-off-by: David Ward --- bgpd/bgp_network.c | 8 ++++---- bgpd/bgp_vty.c | 18 +++++++++--------- bgpd/bgpd.c | 2 +- bgpd/bgpd.h | 4 ++-- doc/user/bgp.rst | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index b409cbe706ec..e09dbc22af2d 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -817,9 +817,9 @@ int bgp_connect(struct peer_connection *connection) #ifdef IPTOS_PREC_INTERNETCONTROL frr_with_privs(&bgpd_privs) { if (sockunion_family(&connection->su) == AF_INET) - setsockopt_ipv4_tos(connection->fd, bm->tcp_dscp); + setsockopt_ipv4_tos(connection->fd, bm->ip_tos); else if (sockunion_family(&connection->su) == AF_INET6) - setsockopt_ipv6_tclass(connection->fd, bm->tcp_dscp); + setsockopt_ipv6_tclass(connection->fd, bm->ip_tos); } #endif @@ -905,9 +905,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, #ifdef IPTOS_PREC_INTERNETCONTROL if (sa->sa_family == AF_INET) - setsockopt_ipv4_tos(sock, bm->tcp_dscp); + setsockopt_ipv4_tos(sock, bm->ip_tos); else if (sa->sa_family == AF_INET6) - setsockopt_ipv6_tclass(sock, bm->tcp_dscp); + setsockopt_ipv6_tclass(sock, bm->ip_tos); #endif sockopt_v6only(sa->sa_family, sock); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index be9942afb6ea..fbe1db9d2a00 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1760,10 +1760,10 @@ DEFPY (bgp_session_dscp, bgp_session_dscp_cmd, "bgp session-dscp (0-63)$dscp", BGP_STR - "Override default (C6) bgp TCP session DSCP value\n" - "Manually configured dscp parameter\n") + "Override default (CS6) DSCP for BGP connections\n" + "Manually configured DSCP value\n") { - bm->tcp_dscp = dscp << 2; + bm->ip_tos = dscp << 2; return CMD_SUCCESS; } @@ -1773,10 +1773,10 @@ DEFPY (no_bgp_session_dscp, "no bgp session-dscp [(0-63)]", NO_STR BGP_STR - "Override default (C6) bgp TCP session DSCP value\n" - "Manually configured dscp parameter\n") + "Override default (CS6) DSCP for BGP connections\n" + "Manually configured DSCP value\n") { - bm->tcp_dscp = IPTOS_PREC_INTERNETCONTROL; + bm->ip_tos = IPTOS_PREC_INTERNETCONTROL; return CMD_SUCCESS; } @@ -19191,9 +19191,9 @@ int bgp_config_write(struct vty *vty) if (CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) vty_out(vty, "bgp send-extra-data zebra\n"); - /* BGP session DSCP value */ - if (bm->tcp_dscp != IPTOS_PREC_INTERNETCONTROL) - vty_out(vty, "bgp session-dscp %u\n", bm->tcp_dscp >> 2); + /* DSCP value for outgoing packets in BGP connections */ + if (bm->ip_tos != IPTOS_PREC_INTERNETCONTROL) + vty_out(vty, "bgp session-dscp %u\n", bm->ip_tos >> 2); /* BGP InQ limit */ if (bm->inq_limit != BM_DEFAULT_Q_LIMIT) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 09e64cf9ec31..d8eba0ab2234 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -8375,7 +8375,7 @@ void bgp_master_init(struct event_loop *master, const int buffer_size, bm->terminating = false; bm->socket_buffer = buffer_size; bm->wait_for_fib = false; - bm->tcp_dscp = IPTOS_PREC_INTERNETCONTROL; + bm->ip_tos = IPTOS_PREC_INTERNETCONTROL; bm->inq_limit = BM_DEFAULT_Q_LIMIT; bm->outq_limit = BM_DEFAULT_Q_LIMIT; bm->t_bgp_sync_label_manager = NULL; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index ad749ba67675..1f8cc5334986 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -166,8 +166,8 @@ struct bgp_master { bool terminating; /* global flag that sigint terminate seen */ - /* DSCP value for TCP sessions */ - uint8_t tcp_dscp; + /* TOS value for outgoing packets in BGP connections */ + uint8_t ip_tos; #define BM_DEFAULT_Q_LIMIT 10000 uint32_t inq_limit; diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index ae342e4c1359..58fdbf969bd7 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -4933,8 +4933,8 @@ setting. .. clicmd:: bgp session-dscp (0-63) -This command allows bgp to control, at a global level, the TCP dscp values -in the TCP header. +This command allows the BGP daemon to control, at a global level, the DSCP value +used in outgoing packets for each BGP connection. .. _bgp-suppress-fib: From 7b76c8f67b51fdfb0a652e9d1bba7d2a428be73b Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Fri, 31 May 2024 13:08:16 -0400 Subject: [PATCH 186/472] ci: only run conflict check on pull-requests This change will stop this action from running on forked repos. Previously whenever one pushed a change to one's development branch the action would "run but skip" which still generated an email notifications and thus was very annoying. :) Signed-off-by: Christian Hopps --- .github/workflows/conflicts.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/conflicts.yml b/.github/workflows/conflicts.yml index 100f557e02e0..4b4e99facf9f 100644 --- a/.github/workflows/conflicts.yml +++ b/.github/workflows/conflicts.yml @@ -1,9 +1,8 @@ name: Add a conflict label if PR needs to rebase on: - push: pull_request_target: - types: [synchronize] + types: [opened, reopened, synchronize] jobs: conflicts: From 41c236120ff98ce9173c63a3402f80590d608290 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 4 Jun 2024 00:51:33 -0400 Subject: [PATCH 187/472] lib: comments about public vs private message apis Signed-off-by: Christian Hopps --- lib/mgmt_msg_native.h | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index cf528a635638..21f702cc6134 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -4,6 +4,15 @@ * * Copyright (c) 2023, LabN Consulting, L.L.C. * + * Public APIs: + * + * The message type codes and corresponding message data definitions for + * front-end client messages represent a public API, as such any changes should + * only be made according to backward compatible principles (basically never, + * just use a new message type). Back-end clients being always compiled with FRR + * can be updated (although one should take care in modifying BE messages as it + * could impact private back-end client implementations which will then need to + * be updated by their owners). */ #ifndef _FRR_MGMT_MSG_NATIVE_H_ @@ -158,15 +167,15 @@ DECLARE_MTYPE(MSG_NATIVE_RPC_REPLY); /* * Native message codes */ -#define MGMT_MSG_CODE_ERROR 0 -#define MGMT_MSG_CODE_GET_TREE 1 -#define MGMT_MSG_CODE_TREE_DATA 2 -#define MGMT_MSG_CODE_GET_DATA 3 -#define MGMT_MSG_CODE_NOTIFY 4 -#define MGMT_MSG_CODE_EDIT 5 -#define MGMT_MSG_CODE_EDIT_REPLY 6 -#define MGMT_MSG_CODE_RPC 7 -#define MGMT_MSG_CODE_RPC_REPLY 8 +#define MGMT_MSG_CODE_ERROR 0 /* Public API */ +#define MGMT_MSG_CODE_GET_TREE 1 /* BE only, non-public API */ +#define MGMT_MSG_CODE_TREE_DATA 2 /* Public API */ +#define MGMT_MSG_CODE_GET_DATA 3 /* Public API */ +#define MGMT_MSG_CODE_NOTIFY 4 /* Public API */ +#define MGMT_MSG_CODE_EDIT 5 /* Public API */ +#define MGMT_MSG_CODE_EDIT_REPLY 6 /* Public API */ +#define MGMT_MSG_CODE_RPC 7 /* Public API */ +#define MGMT_MSG_CODE_RPC_REPLY 8 /* Public API */ /* * Datastores From 890b67d7a9eb6ee9cbb6b5623934ad4d0b781232 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 3 Jun 2024 09:53:34 +0200 Subject: [PATCH 188/472] zebra: display srv6 encapsulation source-address when configured The 'show running-config' does not display the ipv6 source address when a locator is not configured. Fix this by systematically displaying the ipv6 source address. Fixes: 6a0956169b31 ("zebra: Add encap source address to SRv6 config write function") Signed-off-by: Philippe Guibert --- zebra/zebra_srv6_vty.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index c5b8505992d6..d5cd30e64bfc 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -475,16 +475,24 @@ static int zebra_sr_config(struct vty *vty) struct listnode *node; struct srv6_locator *locator; char str[256]; + bool display_source_srv6 = false; + + if (srv6 && !IPV6_ADDR_SAME(&srv6->encap_src_addr, &in6addr_any)) + display_source_srv6 = true; vty_out(vty, "!\n"); - if (zebra_srv6_is_enable()) { + if (display_source_srv6 || zebra_srv6_is_enable()) { vty_out(vty, "segment-routing\n"); vty_out(vty, " srv6\n"); + } + if (display_source_srv6) { if (!IPV6_ADDR_SAME(&srv6->encap_src_addr, &in6addr_any)) { vty_out(vty, " encapsulation\n"); vty_out(vty, " source-address %pI6\n", &srv6->encap_src_addr); } + } + if (zebra_srv6_is_enable()) { vty_out(vty, " locators\n"); for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) { inet_ntop(AF_INET6, &locator->prefix.prefix, @@ -514,6 +522,8 @@ static int zebra_sr_config(struct vty *vty) vty_out(vty, " !\n"); vty_out(vty, " exit\n"); vty_out(vty, " !\n"); + } + if (display_source_srv6 || zebra_srv6_is_enable()) { vty_out(vty, "exit\n"); vty_out(vty, "!\n"); } From a5f82baa9b90d090dc93691bb23015d1eebd6df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87a=C4=9Fatay=20Erem?= Date: Sat, 1 Jun 2024 00:17:14 +0300 Subject: [PATCH 189/472] docker: fix chmod issues when running debian container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I had problem by running container after build. It gave the error below in container, [FATAL tini (7)] exec /usr/lib/frr/docker-start failed: Permission denied So I have fixed the permission issues after building images. Signed-off-by: Çağatay Erem --- docker/debian/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/debian/Dockerfile b/docker/debian/Dockerfile index d136538c7d08..b317b0598d9f 100644 --- a/docker/debian/Dockerfile +++ b/docker/debian/Dockerfile @@ -24,5 +24,5 @@ RUN chown -R frr:frr /etc/frr /var/run/frr ENTRYPOINT ["/usr/bin/tini", "--"] # Default CMD starts watchfrr -COPY docker-start /usr/lib/frr/docker-start +COPY --chmod=0755 docker-start /usr/lib/frr/docker-start CMD ["/usr/lib/frr/docker-start"] From f7242fbf73b9142456bedad9dc59c80d46f3d004 Mon Sep 17 00:00:00 2001 From: Georgi Valkov Date: Tue, 4 Jun 2024 13:35:54 +0300 Subject: [PATCH 190/472] zebra: fix compilation with GCC14 Fixes: zebra/zebra_netns_notify.c: In function 'zebra_ns_ready_read': zebra/zebra_netns_notify.c:266:40: error: implicit declaration of function 'basename' [-Wimplicit-function-declaration] 266 | if (strmatch(VRF_DEFAULT_NAME, basename(netnspath))) { | ^~~~~~~~ Fixed by including libgen.h, then since basename may modify its parameter, allocate a copy on the stack, using strdupa, and pass the temporary string to basename. According to the man page for basename: With glibc, one gets the POSIX version of basename() when is included, and the GNU version otherwise. The POSIX version of basename may modify the contents of path, so we should to pass a copy when calling this function. [1] https://man7.org/linux/man-pages/man3/basename.3.html Signed-off-by: Georgi Valkov --- zebra/zebra_netns_notify.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index 617a2225f895..fb326b0ddf67 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -15,6 +15,7 @@ #include #endif #include +#include #include #include @@ -234,6 +235,7 @@ static void zebra_ns_ready_read(struct event *t) { struct zebra_netns_info *zns_info = EVENT_ARG(t); const char *netnspath; + const char *netnspath_basename; int err, stop_retry = 0; if (!zns_info) @@ -261,23 +263,24 @@ static void zebra_ns_ready_read(struct event *t) zebra_ns_continue_read(zns_info, stop_retry); return; } + netnspath_basename = basename(strdupa(netnspath)); /* check default name is not already set */ - if (strmatch(VRF_DEFAULT_NAME, basename(netnspath))) { - zlog_warn("NS notify : NS %s is already default VRF.Cancel VRF Creation", basename(netnspath)); + if (strmatch(VRF_DEFAULT_NAME, netnspath_basename)) { + zlog_warn("NS notify : NS %s is already default VRF.Cancel VRF Creation", netnspath_basename); zebra_ns_continue_read(zns_info, 1); return; } - if (zebra_ns_notify_is_default_netns(basename(netnspath))) { + if (zebra_ns_notify_is_default_netns(netnspath_basename)) { zlog_warn( "NS notify : NS %s is default VRF. Ignore VRF creation", - basename(netnspath)); + netnspath_basename); zebra_ns_continue_read(zns_info, 1); return; } /* success : close fd and create zns context */ - zebra_ns_notify_create_context_from_entry_name(basename(netnspath)); + zebra_ns_notify_create_context_from_entry_name(netnspath_basename); zebra_ns_continue_read(zns_info, 1); } @@ -396,7 +399,7 @@ void zebra_ns_notify_parse(void) continue; } /* check default name is not already set */ - if (strmatch(VRF_DEFAULT_NAME, basename(dent->d_name))) { + if (strmatch(VRF_DEFAULT_NAME, basename(strdupa(dent->d_name)))) { zlog_warn("NS notify : NS %s is already default VRF.Cancel VRF Creation", dent->d_name); continue; } From 07573cf98be059bf185fc82daf9f4c047484cdef Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 4 Jun 2024 17:31:40 +0300 Subject: [PATCH 191/472] Revert "isisd: When the metric-type is configured as "wide", the IS-IS generates incorrect metric values for IPv4 directly connected routes." This broke these topotests: test_isis_lsp_bits_topo1 test_isis_sr_topo1 test_isis_srv6_topo1 test_isis_tilfa_topo1 test_isis_topo1 test_isis_topo1_vrf test_ldp_snmp_topo1 test_ldp_sync_isis_topo1 This reverts commit 39e27b840e5ddc2087c0b20cfcf379745b3baa79. --- isisd/isis_spf.c | 24 +---- tests/isisd/test_isis_spf.refout | 154 +++++++++++++++---------------- 2 files changed, 81 insertions(+), 97 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 5366491ceead..e349373372d6 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1262,7 +1262,7 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, struct isis_vertex *parent = args->parent; struct prefix_pair ip_info; enum vertextype vtype; - bool has_valid_psid = false, transition = false; + bool has_valid_psid = false; if (external) return LSP_ITER_CONTINUE; @@ -1272,17 +1272,10 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, prefix_copy(&ip_info.dest, prefix); apply_mask(&ip_info.dest); - if (prefix->family == AF_INET) { + if (prefix->family == AF_INET) vtype = VTYPE_IPREACH_INTERNAL; - - if (spftree->area->newmetric) - vtype = VTYPE_IPREACH_TE; - - if (spftree->area->oldmetric && spftree->area->newmetric) - transition = true; - } else { + else vtype = VTYPE_IP6REACH_INTERNAL; - } /* Parse list of Prefix-SID subTLVs if SR is enabled */ if (spftree->area->srdb.enabled && subtlvs) { @@ -1297,11 +1290,6 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, has_valid_psid = true; isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, psid, parent); - if (transition) - isis_spf_add_local(spftree, - VTYPE_IPREACH_INTERNAL, - &ip_info, NULL, 0, psid, - parent); /* * Stop the Prefix-SID iteration since we only support @@ -1310,13 +1298,9 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix, break; } } - if (!has_valid_psid) { + if (!has_valid_psid) isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, NULL, parent); - if (transition) - isis_spf_add_local(spftree, VTYPE_IPREACH_INTERNAL, - &ip_info, NULL, 0, NULL, parent); - } return LSP_ITER_CONTINUE; } diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout index d70677c9b3ce..23d41b9e5dd0 100644 --- a/tests/isisd/test_isis_spf.refout +++ b/tests/isisd/test_isis_spf.refout @@ -2,7 +2,7 @@ test# test isis topology 1 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -61,7 +61,7 @@ test# test isis topology 2 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 10 rt5 - rt1(4) rt2 TE-IS 15 rt2 - rt1(4) @@ -122,7 +122,7 @@ test# test isis topology 3 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -149,7 +149,7 @@ test# test isis topology 4 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -182,7 +182,7 @@ test# test isis topology 5 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -218,7 +218,7 @@ test# test isis topology 6 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -266,7 +266,7 @@ test# test isis topology 7 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 20 rt4 - rt4(4) rt7 TE-IS 20 rt4 - rt4(4) @@ -314,7 +314,7 @@ test# test isis topology 8 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt3 TE-IS 20 rt2 - rt2(4) @@ -361,7 +361,7 @@ test# test isis topology 9 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -438,7 +438,7 @@ test# test isis topology 10 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 20 rt3 - rt1(4) rt4 TE-IS 20 rt4 - rt1(4) @@ -503,7 +503,7 @@ test# test isis topology 11 root rt1 spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt2 pseudo_TE-IS 20 rt3 - rt3(4) @@ -564,7 +564,7 @@ test# test isis topology 12 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -603,7 +603,7 @@ test# test isis topology 13 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -638,7 +638,7 @@ test# test isis topology 4 root rt1 reverse-spf ipv4-only IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -671,7 +671,7 @@ test# test isis topology 11 root rt1 reverse-spf IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt2 pseudo_TE-IS 20 rt3 - rt3(4) @@ -725,7 +725,7 @@ test# test isis topology 1 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -792,7 +792,7 @@ test# test isis topology 2 root rt4 lfa system-id rt1 pseudonode-id 1 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP TE 0 rt4(4) +10.0.255.4/32 IP internal 0 rt4(4) rt1 TE-IS 10 rt1 - rt4(4) rt5 TE-IS 10 rt5 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) @@ -865,7 +865,7 @@ test# test isis topology 2 root rt4 lfa system-id rt6 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP TE 0 rt4(4) +10.0.255.4/32 IP internal 0 rt4(4) rt1 TE-IS 10 rt1 - rt4(4) rt5 TE-IS 10 rt5 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) @@ -938,7 +938,7 @@ test# test isis topology 3 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -988,7 +988,7 @@ test# test isis topology 3 root rt1 lfa system-id rt3 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -1035,7 +1035,7 @@ test# test isis topology 7 root rt1 lfa system-id rt4 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 20 rt4 - rt4(4) rt7 TE-IS 20 rt4 - rt4(4) @@ -1113,7 +1113,7 @@ test# test isis topology 7 root rt7 lfa system-id rt8 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt7 -10.0.255.7/32 IP TE 0 rt7(4) +10.0.255.7/32 IP internal 0 rt7(4) rt4 TE-IS 10 rt4 - rt7(4) rt8 TE-IS 10 rt8 - rt7(4) rt10 TE-IS 20 rt10 - rt7(4) @@ -1195,7 +1195,7 @@ test# test isis topology 7 root rt8 lfa system-id rt11 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt8 -10.0.255.8/32 IP TE 0 rt8(4) +10.0.255.8/32 IP internal 0 rt8(4) rt5 TE-IS 10 rt5 - rt8(4) rt7 TE-IS 10 rt7 - rt8(4) rt9 TE-IS 10 rt9 - rt8(4) @@ -1272,7 +1272,7 @@ test# test isis topology 9 root rt3 lfa system-id rt1 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt3 -10.0.255.3/32 IP TE 0 rt3(4) +10.0.255.3/32 IP internal 0 rt3(4) rt1 TE-IS 10 rt1 - rt3(4) rt2 TE-IS 20 rt1 - rt1(4) 10.0.255.1/32 IP TE 20 rt1 - rt1(4) @@ -1379,7 +1379,7 @@ test# test isis topology 10 root rt8 lfa system-id rt5 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt8 -10.0.255.8/32 IP TE 0 rt8(4) +10.0.255.8/32 IP internal 0 rt8(4) rt5 TE-IS 10 rt5 - rt8(4) rt2 TE-IS 20 rt5 - rt5(4) 10.0.255.5/32 IP TE 20 rt5 - rt5(4) @@ -1478,7 +1478,7 @@ test# test isis topology 11 root rt3 lfa system-id rt5 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt3 -10.0.255.3/32 IP TE 0 rt3(4) +10.0.255.3/32 IP internal 0 rt3(4) rt1 TE-IS 10 rt1 - rt3(4) rt2 TE-IS 10 rt2 - rt3(4) rt5 TE-IS 10 rt5 - rt3(4) @@ -1557,7 +1557,7 @@ test# test isis topology 13 root rt4 lfa system-id rt3 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP TE 0 rt4(4) +10.0.255.4/32 IP internal 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt3 TE-IS 10 rt3 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) @@ -1615,7 +1615,7 @@ test# test isis topology 14 root rt1 lfa system-id rt1 pseudonode-id 1 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt2 TE-IS 10 rt2 - rt1(4) @@ -1672,7 +1672,7 @@ test# test isis topology 14 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt2 TE-IS 10 rt2 - rt1(4) @@ -1737,7 +1737,7 @@ test# test isis topology 14 root rt5 lfa system-id rt4 IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt1 pseudo_TE-IS 20 rt4 - rt4(4) rt1 TE-IS 20 rt4 - rt1(2) @@ -1825,7 +1825,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -1840,7 +1840,7 @@ rt2 TE-IS 50 rt3 - rt4(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -1966,7 +1966,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -1982,7 +1982,7 @@ rt2 TE-IS 45 rt6 - rt1(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt1 TE-IS 10 rt1 - rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) @@ -2125,7 +2125,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -2142,7 +2142,7 @@ rt1 TE-IS 40 rt3 - rt3(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -2212,7 +2212,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -2227,7 +2227,7 @@ rt3 TE-IS 30 rt4 - rt2(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -2278,7 +2278,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -2297,7 +2297,7 @@ rt2 TE-IS 70 rt3 - rt4(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -2364,7 +2364,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP TE 0 rt4(4) +10.0.255.4/32 IP internal 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) @@ -2384,7 +2384,7 @@ rt7 TE-IS 30 rt6 - rt5(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP TE 0 rt4(4) +10.0.255.4/32 IP internal 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt3 TE-IS 10 rt3 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) @@ -2454,7 +2454,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt11 -10.0.255.11/32 IP TE 0 rt11(4) +10.0.255.11/32 IP internal 0 rt11(4) rt10 TE-IS 10 rt10 - rt11(4) rt12 TE-IS 10 rt12 - rt11(4) rt9 TE-IS 20 rt12 - rt12(4) @@ -2483,7 +2483,7 @@ rt3 TE-IS 60 rt12 - rt6(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt11 -10.0.255.11/32 IP TE 0 rt11(4) +10.0.255.11/32 IP internal 0 rt11(4) rt8 TE-IS 10 rt8 - rt11(4) rt10 TE-IS 10 rt10 - rt11(4) rt12 TE-IS 10 rt12 - rt11(4) @@ -2579,7 +2579,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt6 -10.0.255.6/32 IP TE 0 rt6(4) +10.0.255.6/32 IP internal 0 rt6(4) rt3 TE-IS 10 rt3 - rt6(4) rt2 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -2614,7 +2614,7 @@ rt10 TE-IS 60 rt9 - rt11(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt6 -10.0.255.6/32 IP TE 0 rt6(4) +10.0.255.6/32 IP internal 0 rt6(4) rt3 TE-IS 10 rt3 - rt6(4) rt5 TE-IS 10 rt5 - rt6(4) rt2 TE-IS 20 rt3 - rt3(4) @@ -2708,7 +2708,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP TE 0 rt2(4) +10.0.255.2/32 IP internal 0 rt2(4) rt1 TE-IS 10 rt1 - rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt4 TE-IS 20 rt1 - rt1(4) @@ -2736,7 +2736,7 @@ rt12 TE-IS 60 rt3 - rt9(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP TE 0 rt2(4) +10.0.255.2/32 IP internal 0 rt2(4) rt1 TE-IS 10 rt1 - rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt5 TE-IS 10 rt5 - rt2(4) @@ -2817,7 +2817,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP TE 0 rt2(4) +10.0.255.2/32 IP internal 0 rt2(4) rt1 TE-IS 50 rt1 - rt2(4) rt3 TE-IS 50 rt3 - rt2(4) rt2 @@ -2833,7 +2833,7 @@ rt6 TE-IS 70 rt3 - rt5(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP TE 0 rt2(4) +10.0.255.2/32 IP internal 0 rt2(4) rt4 TE-IS 10 rt4 - rt2(4) rt5 TE-IS 20 rt4 - rt4(4) rt6 TE-IS 20 rt4 - rt4(4) @@ -2968,7 +2968,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -2986,7 +2986,7 @@ rt7 TE-IS 50 rt2 - rt5(4) IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) @@ -3046,7 +3046,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3129,7 +3129,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt4 TE-IS 10 rt4 - rt1(4) rt5 TE-IS 10 rt5 - rt1(4) rt2 TE-IS 15 rt2 - rt1(4) @@ -3219,7 +3219,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 15 rt2 - rt1(4) 10.0.255.2/32 IP TE 25 rt2 - rt2(4) rt3 TE-IS 30 rt3 - rt1(4) @@ -3305,7 +3305,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -3398,7 +3398,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt4 TE-IS 20 rt6 - rt6(4) 10.0.255.6/32 IP TE 20 rt6 - rt6(4) @@ -3452,7 +3452,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt5 -10.0.255.5/32 IP TE 0 rt5(4) +10.0.255.5/32 IP internal 0 rt5(4) rt4 TE-IS 10 rt4 - rt5(4) rt6 TE-IS 10 rt6 - rt5(4) rt2 TE-IS 20 rt4 - rt4(4) @@ -3486,7 +3486,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3533,7 +3533,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP TE 0 rt4(4) +10.0.255.4/32 IP internal 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -3577,7 +3577,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) rt5 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3626,7 +3626,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt4 -10.0.255.4/32 IP TE 0 rt4(4) +10.0.255.4/32 IP internal 0 rt4(4) rt2 TE-IS 10 rt2 - rt4(4) rt6 TE-IS 10 rt6 - rt4(4) rt1 TE-IS 20 rt2 - rt2(4) @@ -3678,7 +3678,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt11 -10.0.255.11/32 IP TE 0 rt11(4) +10.0.255.11/32 IP internal 0 rt11(4) rt10 TE-IS 10 rt10 - rt11(4) rt12 TE-IS 10 rt12 - rt11(4) rt9 TE-IS 20 rt12 - rt12(4) @@ -3752,7 +3752,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt6 -10.0.255.6/32 IP TE 0 rt6(4) +10.0.255.6/32 IP internal 0 rt6(4) rt3 TE-IS 10 rt3 - rt6(4) rt2 TE-IS 20 rt3 - rt3(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) @@ -3831,7 +3831,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP TE 0 rt2(4) +10.0.255.2/32 IP internal 0 rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt5 TE-IS 10 rt5 - rt2(4) rt6 TE-IS 20 rt3 - rt3(4) @@ -3896,7 +3896,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP TE 0 rt2(4) +10.0.255.2/32 IP internal 0 rt2(4) rt1 TE-IS 10 rt1 - rt2(4) rt3 TE-IS 10 rt3 - rt2(4) rt4 TE-IS 20 rt1 - rt1(4) @@ -3956,7 +3956,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -4053,7 +4053,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 10 rt3 - rt1(4) 10.0.255.3/32 IP TE 20 rt3 - rt3(4) rt4 TE-IS 110 rt3 - rt3(4) @@ -4162,7 +4162,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt9 -10.0.255.9/32 IP TE 0 rt9(4) +10.0.255.9/32 IP internal 0 rt9(4) rt6 TE-IS 10 rt6 - rt9(4) rt7 TE-IS 10 rt7 - rt9(4) rt8 TE-IS 10 rt8 - rt9(4) @@ -4331,7 +4331,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt9 -10.0.255.9/32 IP TE 0 rt9(4) +10.0.255.9/32 IP internal 0 rt9(4) rt5 TE-IS 10 rt5 - rt9(4) rt6 TE-IS 10 rt6 - rt9(4) rt7 TE-IS 10 rt7 - rt9(4) @@ -4430,7 +4430,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt3 TE-IS 20 rt3 - rt1(4) rt4 TE-IS 20 rt4 - rt1(4) rt6 TE-IS 30 rt3 - rt3(4) @@ -4542,7 +4542,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt3 TE-IS 20 rt3 - rt1(4) rt5 TE-IS 20 rt2 - rt2(4) @@ -4635,7 +4635,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt2 -10.0.255.2/32 IP TE 0 rt2(4) +10.0.255.2/32 IP internal 0 rt2(4) rt1 TE-IS 50 rt1 - rt2(4) rt3 TE-IS 50 rt3 - rt2(4) rt2 @@ -4725,7 +4725,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -4772,7 +4772,7 @@ Q-space: IS-IS paths to level-1 routers that speak IP Vertex Type Metric Next-Hop Interface Parent rt1 -10.0.255.1/32 IP TE 0 rt1(4) +10.0.255.1/32 IP internal 0 rt1(4) rt2 TE-IS 10 rt2 - rt1(4) rt4 TE-IS 20 rt2 - rt2(4) 10.0.255.2/32 IP TE 20 rt2 - rt2(4) @@ -4796,5 +4796,5 @@ IS-IS L1 IPv4 routing table: 10.0.255.6/32 50 - rt2 16040/16060 10.0.255.7/32 60 - rt2 16040/16070 -test# -end. +test# +end. From f153b9a9b636e7ca16ef066e934d355ba922df2b Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 4 Jun 2024 15:30:27 +0300 Subject: [PATCH 192/472] bgpd: Ignore auto created VRF BGP instances Configuration: ``` vtysh < --- bgpd/bgpd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index d8eba0ab2234..5c795350893d 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3620,10 +3620,13 @@ struct bgp *bgp_lookup_by_name(const char *name) struct bgp *bgp; struct listnode *node, *nnode; - for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + continue; if ((bgp->name == NULL && name == NULL) || (bgp->name && name && strcmp(bgp->name, name) == 0)) return bgp; + } return NULL; } From 3f359d732c0be97e580d752cbf8099932afe7dcb Mon Sep 17 00:00:00 2001 From: Acee Lindem Date: Tue, 4 Jun 2024 21:24:46 +0000 Subject: [PATCH 193/472] ospf6d: OSPFv3 manual key authentication neglects checking the SA ID. Also, add topotest variation to verify checking. This corrects https://github.com/FRRouting/frr/issues/16100. Signed-off-by: Acee Lindem --- ospf6d/ospf6_auth_trailer.c | 9 ++ .../test_ospfv3_authentication.py | 131 +++++++++++++----- 2 files changed, 104 insertions(+), 36 deletions(-) diff --git a/ospf6d/ospf6_auth_trailer.c b/ospf6d/ospf6_auth_trailer.c index 8d9eff409e63..860d273796c5 100644 --- a/ospf6d/ospf6_auth_trailer.c +++ b/ospf6d/ospf6_auth_trailer.c @@ -517,6 +517,15 @@ int ospf6_auth_check_digest(struct ospf6_header *oh, struct ospf6_interface *oi, } } else if (CHECK_FLAG(oi->at_data.flags, OSPF6_AUTH_TRAILER_MANUAL_KEY)) { + if (oi->at_data.key_id != ntohs(ospf6_auth->id)) { + if (IS_OSPF6_DEBUG_AUTH_RX) + zlog_err("RECV[%s]: Auth SA ID mismatch for %s, received %u vs configured %u", + oi->interface->name, + ospf6_message_type(oh->type), + ntohs(ospf6_auth->id), + oi->at_data.key_id); + return OSPF6_AUTH_VALIDATE_FAILURE; + } auth_str = oi->at_data.auth_key; hash_algo = oi->at_data.hash_algo; } diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py index 58608e249b2e..00c98ac97c26 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py @@ -175,7 +175,7 @@ def test_ospf6_auth_trailer_tc1_md5(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -208,7 +208,7 @@ def test_ospf6_auth_trailer_tc1_md5(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -266,7 +266,7 @@ def test_ospf6_auth_trailer_tc1_md5(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 using" + "Verify that the neighbor is FULL between R1 and R2 using" " show ip ospf6 neighbor cmd." ) @@ -283,7 +283,7 @@ def test_ospf6_auth_trailer_tc1_md5(request): dut = "r2" step( - "Verify that the neighbour is not FULL between R1 and R2 using " + "Verify that the neighbor is not FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) @@ -295,7 +295,7 @@ def test_ospf6_auth_trailer_tc1_md5(request): shutdown_bringup_interface(tgen, dut, intf, True) step( - "Verify that the neighbour is FULL between R1 and R2 using " + "Verify that the neighbor is FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) @@ -341,7 +341,7 @@ def test_ospf6_auth_trailer_tc2_sha256(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -374,7 +374,7 @@ def test_ospf6_auth_trailer_tc2_sha256(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -432,7 +432,7 @@ def test_ospf6_auth_trailer_tc2_sha256(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 using" + "Verify that the neighbor is FULL between R1 and R2 using" " show ip ospf6 neighbor cmd." ) @@ -449,7 +449,7 @@ def test_ospf6_auth_trailer_tc2_sha256(request): dut = "r2" step( - "Verify that the neighbour is not FULL between R1 and R2 using " + "Verify that the neighbor is not FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) @@ -461,7 +461,66 @@ def test_ospf6_auth_trailer_tc2_sha256(request): shutdown_bringup_interface(tgen, dut, intf, True) step( - "Verify that the neighbour is FULL between R1 and R2 using " + "Verify that the neighbor is FULL between R1 and R2 using " + "show ip ospf6 neighbor cmd." + ) + + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) + assert ospf6_covergence is True, "Testcase {} :Failed \n Error: {}".format( + tc_name, ospf6_covergence + ) + + step("Change the key ID on R2 to not match R1") + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "30", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify on R1 that R2 nbr is deleted due to key-id mismatch " + "after dead interval expiry" + ) + # wait till the dead timer expiry + sleep(6) + dut = "r2" + ospf6_covergence = verify_ospf6_neighbor( + tgen, topo, dut=dut, expected=False, retry_timeout=5 + ) + assert ospf6_covergence is not True, "Testcase {} :Failed \n Error: {}".format( + tc_name, ospf6_covergence + ) + + step("Correct the key ID on R2 so that it matches R1") + r2_ospf6_auth = { + "r2": { + "links": { + "r1": { + "ospf6": { + "hash-algo": "hmac-sha-256", + "key": "ospf6", + "key-id": "10", + } + } + } + } + } + result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) + assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) + + step( + "Verify that the neighbor is FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) @@ -524,7 +583,7 @@ def test_ospf6_auth_trailer_tc3_keychain_md5(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -555,7 +614,7 @@ def test_ospf6_auth_trailer_tc3_keychain_md5(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -600,7 +659,7 @@ def test_ospf6_auth_trailer_tc3_keychain_md5(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 using" + "Verify that the neighbor is FULL between R1 and R2 using" " show ip ospf6 neighbor cmd." ) @@ -617,7 +676,7 @@ def test_ospf6_auth_trailer_tc3_keychain_md5(request): dut = "r2" step( - "Verify that the neighbour is not FULL between R1 and R2 using " + "Verify that the neighbor is not FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) @@ -629,7 +688,7 @@ def test_ospf6_auth_trailer_tc3_keychain_md5(request): shutdown_bringup_interface(tgen, dut, intf, True) step( - "Verify that the neighbour is FULL between R1 and R2 using " + "Verify that the neighbor is FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) @@ -692,7 +751,7 @@ def test_ospf6_auth_trailer_tc4_keychain_sha256(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -723,7 +782,7 @@ def test_ospf6_auth_trailer_tc4_keychain_sha256(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -768,7 +827,7 @@ def test_ospf6_auth_trailer_tc4_keychain_sha256(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 using" + "Verify that the neighbor is FULL between R1 and R2 using" " show ip ospf6 neighbor cmd." ) @@ -785,7 +844,7 @@ def test_ospf6_auth_trailer_tc4_keychain_sha256(request): dut = "r2" step( - "Verify that the neighbour is not FULL between R1 and R2 using " + "Verify that the neighbor is not FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) ospf6_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut, expected=False) @@ -797,7 +856,7 @@ def test_ospf6_auth_trailer_tc4_keychain_sha256(request): shutdown_bringup_interface(tgen, dut, intf, True) step( - "Verify that the neighbour is FULL between R1 and R2 using " + "Verify that the neighbor is FULL between R1 and R2 using " "show ip ospf6 neighbor cmd." ) @@ -843,7 +902,7 @@ def test_ospf6_auth_trailer_tc5_md5_keymissmatch(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -876,11 +935,11 @@ def test_ospf6_auth_trailer_tc5_md5_keymissmatch(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is not FULL between R1 and R2 " + "Verify that the neighbor is not FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) - step("Verify that the neighbour is FULL between R1 and R2.") + step("Verify that the neighbor is FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r2" @@ -913,7 +972,7 @@ def test_ospf6_auth_trailer_tc5_md5_keymissmatch(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -959,7 +1018,7 @@ def test_ospf6_auth_trailer_tc6_sha256_mismatch(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -991,7 +1050,7 @@ def test_ospf6_auth_trailer_tc6_sha256_mismatch(request): result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r2" @@ -1024,7 +1083,7 @@ def test_ospf6_auth_trailer_tc6_sha256_mismatch(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -1095,7 +1154,7 @@ def test_ospf6_auth_trailer_tc7_keychain_md5_missmatch(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -1125,7 +1184,7 @@ def test_ospf6_auth_trailer_tc7_keychain_md5_missmatch(request): result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r2" @@ -1156,7 +1215,7 @@ def test_ospf6_auth_trailer_tc7_keychain_md5_missmatch(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -1227,7 +1286,7 @@ def test_ospf6_auth_trailer_tc8_keychain_sha256_missmatch(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -1257,7 +1316,7 @@ def test_ospf6_auth_trailer_tc8_keychain_sha256_missmatch(request): result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r2" @@ -1288,7 +1347,7 @@ def test_ospf6_auth_trailer_tc8_keychain_sha256_missmatch(request): assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) @@ -1335,7 +1394,7 @@ def test_ospf6_auth_trailer_tc9_keychain_not_configured(request): result = config_ospf6_interface(tgen, topo, r1_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r1" @@ -1365,7 +1424,7 @@ def test_ospf6_auth_trailer_tc9_keychain_not_configured(request): result = config_ospf6_interface(tgen, topo, r2_ospf6_auth) assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result) - step("Verify that the neighbour is not FULL between R1 and R2.") + step("Verify that the neighbor is not FULL between R1 and R2.") # wait for dead time expiry. sleep(6) dut = "r2" @@ -1396,7 +1455,7 @@ def test_ospf6_auth_trailer_tc10_no_auth_trailer(request): router2 = tgen.gears["r2"] step( - "Verify that the neighbour is FULL between R1 and R2 " + "Verify that the neighbor is FULL between R1 and R2 " "using show ipv6 ospf6 neighbor cmd." ) From b9c97686acd34936b8e85a84ad990a4c58908e98 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 5 Jun 2024 08:35:34 +0300 Subject: [PATCH 194/472] doc: Add missing `clear bgp ASNUM` command Signed-off-by: Donatas Abraitis --- doc/user/bgp.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 58fdbf969bd7..150a915e3a88 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -4102,6 +4102,10 @@ The following are available in the top level *enable* mode: Clear all peers. +.. clicmd:: clear bgp ipv4|ipv6 ASNUM + + Clear peers with the AS number in plain or dotted format. + .. clicmd:: clear bgp ipv4|ipv6 \* Clear all peers with this address-family activated. From 747da057e814258533ea149da804adfdb4219f27 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 5 Feb 2024 17:05:20 +0100 Subject: [PATCH 195/472] bgpd: check and set extra num_labels The handling of MPLS labels in BGP faces an issue due to the way labels are stored in memory. They are stored in bgp_path_info but not in bgp_adj_in and bgp_adj_out structures. As a consequence, some configuration changes result in losing labels or even a bgpd crash. For example, when retrieving routes from the Adj-RIB-in table ("soft-reconfiguration inbound" enabled), labels are missing. bgp_path_info stores the MPLS labels, as shown below: > struct bgp_path_info { > struct bgp_path_info_extra *extra; > [...] > struct bgp_path_info_extra { > mpls_label_t label[BGP_MAX_LABELS]; > uint32_t num_labels; > [...] To solve those issues, a solution would be to set label data to the bgp_adj_in and bgp_adj_out structures in addition to the bgp_path_info_extra structure. The idea is to reference a common label pointer in all these three structures. And to store the data in a hash list in order to save memory. However, an issue in the code prevents us from setting clean data without a rework. The extra->num_labels field, which is intended to indicate the number of labels in extra->label[], is not reliably checked or set. The code often incorrectly assumes that if the extra pointer is present, then a label must also be present, leading to direct access to extra->label[] without verifying extra->num_labels. This assumption usually works because extra->label[0] is set to MPLS_INVALID_LABEL when a new bgp_path_info_extra is created, but it is technically incorrect. Cleanup the label code by setting num_labels each time values are set in extra->label[] and checking extra->num_labels before accessing the labels. Signed-off-by: Louis Scalbert --- bgpd/bgp_label.c | 4 ++- bgpd/bgp_mplsvpn.c | 15 +++++---- bgpd/bgp_route.c | 30 ++++++++--------- bgpd/bgp_zebra.c | 6 ++-- bgpd/rfapi/rfapi.c | 5 ++- bgpd/rfapi/rfapi_import.c | 14 +++++--- bgpd/rfapi/rfapi_rib.c | 5 ++- bgpd/rfapi/rfapi_vty.c | 7 ++-- bgpd/rfapi/vnc_import_bgp.c | 66 ++++++++++++++++++++++--------------- 9 files changed, 89 insertions(+), 63 deletions(-) diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 68104967b2fd..d5732b567721 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -89,7 +89,9 @@ mpls_label_t bgp_adv_label(struct bgp_dest *dest, struct bgp_path_info *pi, if (!dest || !pi || !to) return MPLS_INVALID_LABEL; - remote_label = pi->extra ? pi->extra->label[0] : MPLS_INVALID_LABEL; + remote_label = (pi->extra && pi->extra->num_labels) + ? pi->extra->label[0] + : MPLS_INVALID_LABEL; from = pi->peer; reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP)); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 39f8f84a02eb..7fe4d6ece5a7 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -4130,7 +4130,8 @@ bool bgp_mplsvpn_path_uses_valid_mpls_label(struct bgp_path_info *pi) /* prefix_sid attribute */ return false; - if (!pi->extra || !bgp_is_valid_label(&pi->extra->label[0])) + if (!pi->extra || !pi->extra->num_labels || + !bgp_is_valid_label(&pi->extra->label[0])) /* invalid MPLS label */ return false; return true; @@ -4237,14 +4238,16 @@ void bgp_mplsvpn_nh_label_bind_register_local_label(struct bgp *bgp, { struct bgp_mplsvpn_nh_label_bind_cache *bmnc; struct bgp_mplsvpn_nh_label_bind_cache_head *tree; + mpls_label_t label; + + label = pi->extra->num_labels ? decode_label(&pi->extra->label[0]) + : MPLS_INVALID_LABEL; tree = &bgp->mplsvpn_nh_label_bind; - bmnc = bgp_mplsvpn_nh_label_bind_find( - tree, &pi->nexthop->prefix, decode_label(&pi->extra->label[0])); + bmnc = bgp_mplsvpn_nh_label_bind_find(tree, &pi->nexthop->prefix, label); if (!bmnc) { - bmnc = bgp_mplsvpn_nh_label_bind_new( - tree, &pi->nexthop->prefix, - decode_label(&pi->extra->label[0])); + bmnc = bgp_mplsvpn_nh_label_bind_new(tree, &pi->nexthop->prefix, + label); bmnc->bgp_vpn = bgp; bmnc->allocation_in_progress = true; bgp_lp_get(LP_TYPE_BGP_L3VPN_BIND, bmnc, diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 2309b710ed2c..af440fce474b 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1359,25 +1359,20 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, /* If one path has a label but the other does not, do not treat * them as equals for multipath */ - int newl, existl; - - newl = existl = 0; - - if (new->extra) - newl = new->extra->num_labels; - if (exist->extra) - existl = exist->extra->num_labels; - if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) != - (exist->extra && - bgp_is_valid_label(&exist->extra->label[0]))) || - (newl != existl)) { + bool new_label_valid, exist_label_valid; + + new_label_valid = new->extra && new->extra->num_labels && + bgp_is_valid_label(&new->extra->label[0]); + exist_label_valid = exist->extra && exist->extra->num_labels && + bgp_is_valid_label(&exist->extra->label[0]); + + if (new_label_valid != exist_label_valid) { if (debug) zlog_debug( "%s: %s and %s cannot be multipath, one has a label while the other does not", pfx_buf, new_buf, exist_buf); } else if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) { - /* * For the two paths, all comparison steps till IGP * metric @@ -3455,7 +3450,7 @@ static bool bgp_lu_need_null_label(struct bgp *bgp, || new_select->sub_type == BGP_ROUTE_AGGREGATE || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE) goto need_null_label; - else if (new_select->extra && + else if (new_select->extra && new_select->extra->num_labels && bgp_is_valid_label(&new_select->extra->label[0])) return false; need_null_label: @@ -6678,7 +6673,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, route_map_result_t ret; #ifdef ENABLE_BGP_VNC int vnc_implicit_withdraw = 0; - mpls_label_t label = 0; + mpls_label_t label = MPLS_INVALID_LABEL; #endif uint32_t num_labels = 0; struct bgp *bgp_nexthop = bgp; @@ -6831,7 +6826,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, bgp, p, pi); } } else { - if (pi->extra) + if (pi->extra && pi->extra->num_labels) label = decode_label( &pi->extra->label[0]); } @@ -10069,7 +10064,8 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, } } - if (bgp_is_valid_label(&path->extra->label[0])) { + if (path->extra->num_labels && + bgp_is_valid_label(&path->extra->label[0])) { label = decode_label(&path->extra->label[0]); if (json) { json_object_int_add(json_out, "notag", label); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 1c2f08465d70..49b3ef371270 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1341,15 +1341,13 @@ static void bgp_zebra_announce_parse_nexthop( api_nh->srte_color = bgp_attr_get_color(info->attr); if (bgp_debug_zebra(&api->prefix)) { - if (mpinfo->extra) { + if (mpinfo->extra && mpinfo->extra->num_labels) { zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d", __func__, p, bgp_is_valid_label( &mpinfo->extra->label[0])); } else { - zlog_debug( - "%s: p=%pFX, extra is NULL, no label", - __func__, p); + zlog_debug("%s: p=%pFX, no label", __func__, p); } } diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index ae899daf82d3..bea9bfb618fb 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -592,7 +592,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ } } - if (label) + if (label && *label != MPLS_INVALID_LABEL) label_val = *label; else label_val = MPLS_LABEL_IMPLICIT_NULL; @@ -1020,7 +1020,9 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ new->extra->vnc = XCALLOC(MTYPE_BGP_ROUTE_EXTRA_VNC, sizeof(struct bgp_path_info_extra_vnc)); new->extra->vnc->vnc.export.rfapi_handle = (void *)rfd; + encode_label(label_val, &new->extra->label[0]); + new->extra->num_labels = 1; /* debug */ @@ -1043,6 +1045,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ bgp, prd, table, p, new); bgp_dest_unlock_node(pdest); encode_label(label_val, &bn->local_label); + new->extra->num_labels = 1; } bgp_dest_unlock_node(bn); diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 168b8e4c1e2e..7fb7d5d7aac5 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -454,8 +454,11 @@ static struct bgp_path_info *rfapiBgpInfoCreate(struct attr *attr, new->extra->vnc->vnc.import.rd = *prd; new->extra->vnc->vnc.import.create_time = monotime(NULL); } - if (label) + if (label && *label != MPLS_INVALID_LABEL) { encode_label(*label, &new->extra->label[0]); + new->extra->num_labels = 1; + } else + new->extra->num_labels = 0; peer_lock(peer); @@ -1267,7 +1270,10 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, bpi->extra->vnc->vnc.import.rd.val[1]; /* label comes from MP_REACH_NLRI label */ - vo->v.l2addr.label = decode_label(&bpi->extra->label[0]); + vo->v.l2addr.label = + bpi->extra->num_labels + ? decode_label(&bpi->extra->label[0]) + : MPLS_INVALID_LABEL; new->vn_options = vo; @@ -4154,13 +4160,13 @@ static void rfapiBgpTableFilteredImport(struct bgp *bgp, for (bpi = bgp_dest_get_bgp_path_info(dest2); bpi; bpi = bpi->next) { - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) continue; - if (bpi->extra) + if (bpi->extra && bpi->extra->num_labels) label = decode_label( &bpi->extra->label[0]); (*rfapiBgpInfoFilteredImportFunction( diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 316904e45b8a..11dccbf1b5f5 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -691,7 +691,10 @@ static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri, bpi->extra->vnc->vnc.import.rd.val[1]; /* label comes from MP_REACH_NLRI label */ - vo->v.l2addr.label = decode_label(&bpi->extra->label[0]); + vo->v.l2addr.label = + bpi->extra->num_labels + ? decode_label(&bpi->extra->label[0]) + : MPLS_INVALID_LABEL; rfapi_vn_options_free( ri->vn_options); /* maybe free old version */ diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 5da99dbc4e09..2576a283f522 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -413,7 +413,7 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p, XFREE(MTYPE_ECOMMUNITY_STR, s); } - if (bpi->extra != NULL) { + if (bpi->extra != NULL && bpi->extra->num_labels) { if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) vty_out(vty, " label=VRF2VRF"); else @@ -1052,7 +1052,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, snprintf(buf_un, sizeof(buf_un), "%s", inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, sizeof(buf_ntop))); - if (bpi->extra) { + if (bpi->extra && bpi->extra->num_labels) { uint32_t l = decode_label(&bpi->extra->label[0]); snprintf(buf_vn, sizeof(buf_vn), "Label: %d", l); } else /* should never happen */ @@ -1161,7 +1161,8 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, } } } - if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra) { + if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra && + bpi->extra->num_labels) { uint32_t l = decode_label(&bpi->extra->label[0]); if (!MPLS_LABEL_IS_NULL(l)) { diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index c067b7a610c1..09260dbca18a 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -414,7 +414,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( uint32_t lifetime; uint32_t *plifetime; struct bgp_attr_encap_subtlv *encaptlvs; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; struct rfapi_un_option optary[3]; struct rfapi_un_option *opt = NULL; @@ -470,16 +470,17 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( if (bgp_attr_get_ecommunity(bpi->attr)) ecommunity_merge(new_ecom, bgp_attr_get_ecommunity(bpi->attr)); - if (bpi->extra) + if (bpi->extra && bpi->extra->num_labels) label = decode_label(&bpi->extra->label[0]); add_vnc_route(&vncHDResolveNve, bgp, SAFI_MPLS_VPN, - prefix, /* unicast route prefix */ + prefix, /* unicast route prefix */ prd, &nexthop_h, /* new nexthop */ local_pref, plifetime, (struct bgp_tea_options *)encaptlvs, /* RFP options */ opt, NULL, new_ecom, med, /* NULL => don't set med */ - (label ? &label : NULL), /* NULL= default */ + ((label != MPLS_INVALID_LABEL) ? &label + : NULL), /* NULL= default */ ZEBRA_ROUTE_BGP_DIRECT, BGP_ROUTE_REDISTRIBUTE, RFAPI_AHR_RFPOPT_IS_VNCTLV); /* flags */ @@ -1678,7 +1679,7 @@ static void vnc_import_bgp_exterior_add_route_it( bpi_interior = bpi_interior->next) { struct prefix_rd *prd; struct attr new_attr; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; if (!is_usable_interior_route(bpi_interior)) continue; @@ -1698,8 +1699,10 @@ static void vnc_import_bgp_exterior_add_route_it( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc .import.rd; - label = decode_label( - &bpi_interior->extra->label[0]); + if (bpi_interior->extra->num_labels) + label = decode_label( + &bpi_interior->extra + ->label[0]); } else prd = NULL; @@ -1851,7 +1854,7 @@ void vnc_import_bgp_exterior_del_route( for (bpi_interior = rn->info; bpi_interior; bpi_interior = bpi_interior->next) { struct prefix_rd *prd; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; if (!is_usable_interior_route(bpi_interior)) continue; @@ -1867,8 +1870,10 @@ void vnc_import_bgp_exterior_del_route( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc .import.rd; - label = decode_label( - &bpi_interior->extra->label[0]); + if (bpi_interior->extra->num_labels) + label = decode_label( + &bpi_interior->extra + ->label[0]); } else prd = NULL; @@ -2007,15 +2012,16 @@ void vnc_import_bgp_exterior_add_route_interior( struct prefix_rd *prd; struct attr new_attr; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; assert(bpi_exterior); assert(pfx_exterior); if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc.import.rd; - label = decode_label( - &bpi_interior->extra->label[0]); + if (bpi_interior->extra->num_labels) + label = decode_label( + &bpi_interior->extra->label[0]); } else prd = NULL; @@ -2097,7 +2103,7 @@ void vnc_import_bgp_exterior_add_route_interior( struct bgp_path_info *bpi; struct prefix_rd *prd; struct attr new_attr; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; /* do pull-down */ @@ -2128,8 +2134,10 @@ void vnc_import_bgp_exterior_add_route_interior( if (bpi->extra) { prd = &bpi->extra->vnc->vnc .import.rd; - label = decode_label( - &bpi->extra->label[0]); + if (bpi->extra->num_labels) + label = decode_label( + &bpi->extra->label + [0]); } else prd = NULL; @@ -2150,8 +2158,10 @@ void vnc_import_bgp_exterior_add_route_interior( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc .import.rd; - label = decode_label( - &bpi_interior->extra->label[0]); + if (bpi_interior->extra->num_labels) + label = decode_label( + &bpi_interior->extra + ->label[0]); } else prd = NULL; @@ -2237,7 +2247,7 @@ void vnc_import_bgp_exterior_add_route_interior( struct prefix_rd *prd; struct attr new_attr; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; /* do pull-down */ @@ -2268,8 +2278,9 @@ void vnc_import_bgp_exterior_add_route_interior( */ if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc.import.rd; - label = decode_label( - &bpi_interior->extra->label[0]); + if (bpi_interior->extra->num_labels) + label = decode_label( + &bpi_interior->extra->label[0]); } else prd = NULL; @@ -2372,11 +2383,13 @@ void vnc_import_bgp_exterior_del_route_interior( &cursor)) { struct prefix_rd *prd; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc.import.rd; - label = decode_label(&bpi_interior->extra->label[0]); + if (bpi_interior->extra->num_labels) + label = decode_label( + &bpi_interior->extra->label[0]); } else prd = NULL; @@ -2446,15 +2459,16 @@ void vnc_import_bgp_exterior_del_route_interior( struct prefix_rd *prd; struct attr new_attr; - uint32_t label = 0; + uint32_t label = MPLS_INVALID_LABEL; if (bpi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) continue; if (bpi->extra) { prd = &bpi->extra->vnc->vnc.import.rd; - label = decode_label( - &bpi->extra->label[0]); + if (bpi->extra->num_labels) + label = decode_label( + &bpi->extra->label[0]); } else prd = NULL; From 7a513e3361eb879a6a0ea64939c68cd949e8fd76 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 14 Feb 2024 17:32:06 +0100 Subject: [PATCH 196/472] bgpd: add bgp_path_info_has_valid_label() Add bgp_path_has_valid_label to check that a path_info has a valid label. Signed-off-by: Louis Scalbert --- bgpd/bgp_mplsvpn.c | 3 +-- bgpd/bgp_route.c | 26 ++++++++++++++++---------- bgpd/bgp_route.h | 1 + 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 7fe4d6ece5a7..c58c67e6ac28 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -4130,8 +4130,7 @@ bool bgp_mplsvpn_path_uses_valid_mpls_label(struct bgp_path_info *pi) /* prefix_sid attribute */ return false; - if (!pi->extra || !pi->extra->num_labels || - !bgp_is_valid_label(&pi->extra->label[0])) + if (!bgp_path_info_has_valid_label(pi)) /* invalid MPLS label */ return false; return true; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index af440fce474b..3db883fc08d2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -324,6 +324,16 @@ struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi) return pi->extra; } +bool bgp_path_info_has_valid_label(const struct bgp_path_info *path) +{ + if (!path->extra) + return false; + if (!path->extra->num_labels) + return false; + + return bgp_is_valid_label(&path->extra->label[0]); +} + /* Free bgp route information. */ void bgp_path_info_free_with_caller(const char *name, struct bgp_path_info *path) @@ -1361,10 +1371,8 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, */ bool new_label_valid, exist_label_valid; - new_label_valid = new->extra && new->extra->num_labels && - bgp_is_valid_label(&new->extra->label[0]); - exist_label_valid = exist->extra && exist->extra->num_labels && - bgp_is_valid_label(&exist->extra->label[0]); + new_label_valid = bgp_path_info_has_valid_label(new); + exist_label_valid = bgp_path_info_has_valid_label(exist); if (new_label_valid != exist_label_valid) { if (debug) @@ -3450,8 +3458,7 @@ static bool bgp_lu_need_null_label(struct bgp *bgp, || new_select->sub_type == BGP_ROUTE_AGGREGATE || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE) goto need_null_label; - else if (new_select->extra && new_select->extra->num_labels && - bgp_is_valid_label(&new_select->extra->label[0])) + else if (bgp_path_info_has_valid_label(new_select)) return false; need_null_label: if (label == NULL) @@ -10064,8 +10071,7 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, } } - if (path->extra->num_labels && - bgp_is_valid_label(&path->extra->label[0])) { + if (bgp_path_info_has_valid_label(path)) { label = decode_label(&path->extra->label[0]); if (json) { json_object_int_add(json_out, "notag", label); @@ -11270,8 +11276,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path); /* Remote Label */ - if (path->extra && bgp_is_valid_label(&path->extra->label[0]) - && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) { + if (bgp_path_info_has_valid_label(path) && + (safi != SAFI_EVPN && !is_route_parent_evpn(path))) { mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp, &bos); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 25fc327a17cd..7afd77cf6b97 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -753,6 +753,7 @@ extern void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi); extern struct bgp_path_info_extra * bgp_path_info_extra_get(struct bgp_path_info *path); +extern bool bgp_path_info_has_valid_label(const struct bgp_path_info *path); extern void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *path, uint32_t flag); extern void bgp_path_info_unset_flag(struct bgp_dest *dest, From e93fa4daf07c393c733cd2c26b1edaa84a98be95 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 5 Feb 2024 17:11:47 +0100 Subject: [PATCH 197/472] bgpd: do not init labels in extra No need to init labels at extra allocation. num_labels is the number of set labels in label[] and is initialized to 0 by default. Signed-off-by: Louis Scalbert --- bgpd/bgp_route.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3db883fc08d2..b8fdb8999638 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -235,8 +235,6 @@ static struct bgp_path_info_extra *bgp_path_info_extra_new(void) struct bgp_path_info_extra *new; new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA, sizeof(struct bgp_path_info_extra)); - new->label[0] = MPLS_INVALID_LABEL; - new->num_labels = 0; new->flowspec = NULL; return new; } From 9771f1a03ea1a169a1ab2b5656ecf0719409f28c Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 12:16:16 +0100 Subject: [PATCH 198/472] bgpd: optimize label copy for new path_info In bgp_update(), path_info *new has just been created and has void labels. bgp_labels_same() is always false. Do not compare previous labels before setting them. Signed-off-by: Louis Scalbert --- bgpd/bgp_route.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index b8fdb8999638..8da30e789563 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -5239,12 +5239,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { extra = bgp_path_info_extra_get(new); - if (!bgp_labels_same((const mpls_label_t *)extra->label, - extra->num_labels, label, num_labels)) { - memcpy(&extra->label, label, - num_labels * sizeof(mpls_label_t)); - extra->num_labels = num_labels; - } + memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t)); + extra->num_labels = num_labels; if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) bgp_set_valid_label(&extra->label[0]); } From 04748e36a5d5e6dd22979bac0c81b96158a7e8f1 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 12:10:16 +0100 Subject: [PATCH 199/472] bgpd: add bgp_path_info_labels_same() Add bgp_path_info_labels_same() to compare labels with labels from path_info. Remove labels_same() that was used for mplsvpn only. Signed-off-by: Louis Scalbert --- bgpd/bgp_mplsvpn.c | 18 ++---------------- bgpd/bgp_route.c | 22 +++++++++++++++------- bgpd/bgp_route.h | 2 ++ 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index c58c67e6ac28..6e4f93f1ea73 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -964,21 +964,6 @@ void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, } } -static bool labels_same(struct bgp_path_info *bpi, mpls_label_t *label, - uint32_t n) -{ - if (!bpi->extra) { - if (!n) - return true; - else - return false; - } - - return bgp_labels_same((const mpls_label_t *)bpi->extra->label, - bpi->extra->num_labels, - (const mpls_label_t *)label, n); -} - /* * make encoded route labels match specified encoded label set */ @@ -1129,7 +1114,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, } if (bpi) { - bool labelssame = labels_same(bpi, label, num_labels); + bool labelssame = bgp_path_info_labels_same(bpi, label, + num_labels); if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED) && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) { diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8da30e789563..bf3ffaedfead 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -332,6 +332,19 @@ bool bgp_path_info_has_valid_label(const struct bgp_path_info *path) return bgp_is_valid_label(&path->extra->label[0]); } +bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, + const mpls_label_t *label, uint32_t n) +{ + uint32_t bpi_num_labels; + const mpls_label_t *bpi_label; + + bpi_num_labels = bpi->extra ? bpi->extra->num_labels : 0; + bpi_label = bpi_num_labels ? bpi->extra->label : NULL; + + return bgp_labels_same(bpi_label, bpi_num_labels, + (const mpls_label_t *)label, n); +} + /* Free bgp route information. */ void bgp_path_info_free_with_caller(const char *name, struct bgp_path_info *path) @@ -4851,10 +4864,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Same attribute comes in. */ if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) && same_attr && (!has_valid_label || - (bgp_path_info_extra_get(pi) && - bgp_labels_same((const mpls_label_t *)pi->extra->label, - pi->extra->num_labels, label, - num_labels)))) { + bgp_path_info_labels_same(pi, label, num_labels))) { if (get_active_bdc_from_pi(pi, afi, safi) && peer->sort == BGP_PEER_EBGP && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { @@ -5038,9 +5048,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { extra = bgp_path_info_extra_get(pi); - if (!bgp_labels_same((const mpls_label_t *)extra->label, - extra->num_labels, label, - num_labels)) { + if (!bgp_path_info_labels_same(pi, label, num_labels)) { memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t)); extra->num_labels = num_labels; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 7afd77cf6b97..2aa721a3b65a 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -760,6 +760,8 @@ extern void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *path, uint32_t flag); extern void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf, size_t buf_len); +extern bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, + const mpls_label_t *label, uint32_t n); extern int bgp_nlri_parse_ip(struct peer *, struct attr *, struct bgp_nlri *); From c27ad436945850d9436c40be83e455f46cda16f9 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 14:13:25 +0100 Subject: [PATCH 200/472] bgpd: num_labels cannot be greater than BGP_MAX_LABELS num_labels cannot be greater than BGP_MAX_LABELS by design. Remove the check and the override. Signed-off-by: Louis Scalbert --- bgpd/bgp_mplsvpn.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 6e4f93f1ea73..fb1243d02939 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -2339,8 +2339,6 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ if (!origin_local && path_vpn->extra && path_vpn->extra->num_labels) { num_labels = path_vpn->extra->num_labels; - if (num_labels > BGP_MAX_LABELS) - num_labels = BGP_MAX_LABELS; pLabels = path_vpn->extra->label; } } From 1fcedd00d150ada5526e9f4b5dd86cfdc1218daa Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 11:04:18 +0100 Subject: [PATCH 201/472] bgpd: rework vni printing in route_vty_out_detail() In route_vty_out_detail(), tag_buf stores a string representation of the VNI label. Rename tag_buf to vni_buf for clarity and rework the code a little bit to prepare the following commits. Signed-off-by: Louis Scalbert --- bgpd/bgp_route.c | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index bf3ffaedfead..ebeaf9a474c4 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -10464,7 +10464,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, json_object *json_paths) { char buf[INET6_ADDRSTRLEN]; - char tag_buf[30]; + char vni_buf[30] = {}; struct attr *attr = path->attr; time_t tbuf; char timebuf[32]; @@ -10497,7 +10497,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, uint32_t bos = 0; uint32_t exp = 0; mpls_label_t label = MPLS_INVALID_LABEL; - tag_buf[0] = '\0'; struct bgp_path_info *bpi_ultimate = bgp_get_imported_bpi_ultimate(path); @@ -10507,26 +10506,21 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, json_nexthop_global = json_object_new_object(); } + if (path->extra && path->extra->num_labels) { + bgp_evpn_label2str(path->extra->label, path->extra->num_labels, + vni_buf, sizeof(vni_buf)); + } + if (safi == SAFI_EVPN) { if (!json_paths) vty_out(vty, " Route %pFX", p); - } - if (path->extra) { - if (path->extra && path->extra->num_labels) { - bgp_evpn_label2str(path->extra->label, - path->extra->num_labels, tag_buf, - sizeof(tag_buf)); - } - if (safi == SAFI_EVPN) { - if (!json_paths) { - if (tag_buf[0] != '\0') - vty_out(vty, " VNI %s", tag_buf); - } else { - if (tag_buf[0]) - json_object_string_add(json_path, "vni", - tag_buf); - } + if (vni_buf[0]) { + if (json_paths) + json_object_string_add(json_path, "vni", + vni_buf); + else + vty_out(vty, " VNI %s", vni_buf); } } @@ -10566,7 +10560,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, ":%pFX, VNI %s", (struct prefix_evpn *) bgp_dest_get_prefix(dest), - tag_buf); + vni_buf); if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG)) vty_out(vty, ", L3NHG %s", CHECK_FLAG( From 64fe15fd28774333c51352ed53022014ee090ade Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 10:42:42 +0100 Subject: [PATCH 202/472] bgpd: add bgp_path_info_num_labels() Add bgp_path_info_num_labels() to get the number of labels stored in a path_info structure. Signed-off-by: Louis Scalbert --- bgpd/bgp_evpn.c | 2 +- bgpd/bgp_label.c | 5 ++--- bgpd/bgp_mac.c | 10 ++++------ bgpd/bgp_mplsvpn.c | 18 ++++++++---------- bgpd/bgp_nht.c | 12 ++++++------ bgpd/bgp_route.c | 35 +++++++++++++++++++++-------------- bgpd/bgp_route.h | 1 + bgpd/bgp_routemap.c | 9 +++------ bgpd/bgp_rpki.c | 11 +++++------ bgpd/bgp_updgrp_packet.c | 7 ++++--- bgpd/bgp_zebra.c | 13 ++++--------- bgpd/rfapi/rfapi_import.c | 4 ++-- bgpd/rfapi/rfapi_rib.c | 2 +- bgpd/rfapi/rfapi_vty.c | 7 +++---- bgpd/rfapi/vnc_import_bgp.c | 21 ++++++++++++--------- 15 files changed, 77 insertions(+), 80 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index ce9666d6115a..ae5d837cbd85 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -2986,7 +2986,7 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi, if (parent_pi->extra) { memcpy(&pi->extra->label, &parent_pi->extra->label, sizeof(pi->extra->label)); - pi->extra->num_labels = parent_pi->extra->num_labels; + pi->extra->num_labels = bgp_path_info_num_labels(parent_pi); pi->extra->igpmetric = parent_pi->extra->igpmetric; } diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index d5732b567721..f57663d7a1b3 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -89,9 +89,8 @@ mpls_label_t bgp_adv_label(struct bgp_dest *dest, struct bgp_path_info *pi, if (!dest || !pi || !to) return MPLS_INVALID_LABEL; - remote_label = (pi->extra && pi->extra->num_labels) - ? pi->extra->label[0] - : MPLS_INVALID_LABEL; + remote_label = bgp_path_info_num_labels(pi) ? pi->extra->label[0] + : MPLS_INVALID_LABEL; from = pi->peer; reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP)); diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index e629732c78ee..aa793e999d84 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -125,6 +125,8 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, { struct bgp_dest *pdest, *dest; struct bgp_path_info *pi; + uint32_t num_labels; + mpls_label_t *label_pnt; for (pdest = bgp_table_top(table); pdest; pdest = bgp_route_next(pdest)) { @@ -140,8 +142,6 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, const struct prefix *p = bgp_dest_get_prefix(dest); struct prefix_evpn *pevpn = (struct prefix_evpn *)dest; struct prefix_rd prd; - uint32_t num_labels = 0; - mpls_label_t *label_pnt = NULL; struct bgp_route_evpn *evpn; if (pevpn->family == AF_EVPN @@ -169,10 +169,8 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, && !dest_affected) continue; - if (pi->extra) - num_labels = pi->extra->num_labels; - if (num_labels) - label_pnt = &pi->extra->label[0]; + num_labels = bgp_path_info_num_labels(pi); + label_pnt = num_labels ? &pi->extra->label[0] : NULL; prd.family = AF_UNSPEC; prd.prefixlen = 64; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index fb1243d02939..6c56b05dff2e 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -2088,7 +2088,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ safi_t safi = SAFI_UNICAST; const char *debugmsg; struct prefix nexthop_orig; - mpls_label_t *pLabels = NULL; + mpls_label_t *label_pnt = NULL; uint32_t num_labels = 0; int nexthop_self_flag = 1; struct bgp_path_info *bpi_ultimate = NULL; @@ -2335,19 +2335,16 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ origin_local = 1; } - /* copy labels */ - if (!origin_local && path_vpn->extra - && path_vpn->extra->num_labels) { - num_labels = path_vpn->extra->num_labels; - pLabels = path_vpn->extra->label; - } + num_labels = origin_local ? 0 + : bgp_path_info_num_labels(path_vpn); + label_pnt = num_labels ? path_vpn->extra->label : NULL; } if (debug) zlog_debug("%s: pfx %pBD: num_labels %d", __func__, path_vpn->net, num_labels); - if (!leak_update(to_bgp, bn, new_attr, afi, safi, path_vpn, pLabels, + if (!leak_update(to_bgp, bn, new_attr, afi, safi, path_vpn, label_pnt, num_labels, src_vrf, &nexthop_orig, nexthop_self_flag, debug)) bgp_dest_unlock_node(bn); @@ -4223,8 +4220,9 @@ void bgp_mplsvpn_nh_label_bind_register_local_label(struct bgp *bgp, struct bgp_mplsvpn_nh_label_bind_cache_head *tree; mpls_label_t label; - label = pi->extra->num_labels ? decode_label(&pi->extra->label[0]) - : MPLS_INVALID_LABEL; + label = bgp_path_info_num_labels(pi) + ? decode_label(&pi->extra->label[0]) + : MPLS_INVALID_LABEL; tree = &bgp->mplsvpn_nh_label_bind; bmnc = bgp_mplsvpn_nh_label_bind_find(tree, &pi->nexthop->prefix, label); diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 79f62ef60969..8ce45558e96f 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -499,8 +499,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, if (bgp_route->inst_type == BGP_INSTANCE_TYPE_VIEW) return 1; else if (safi == SAFI_UNICAST && pi && - pi->sub_type == BGP_ROUTE_IMPORTED && pi->extra && - pi->extra->num_labels && !bnc->is_evpn_gwip_nexthop) + pi->sub_type == BGP_ROUTE_IMPORTED && + bgp_path_info_num_labels(pi) && !bnc->is_evpn_gwip_nexthop) return bgp_isvalid_nexthop_for_l3vpn(bnc, pi); else if (safi == SAFI_MPLS_VPN && pi && pi->sub_type != BGP_ROUTE_IMPORTED) @@ -1301,10 +1301,10 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc) bool bnc_is_valid_nexthop = false; bool path_valid = false; - if (safi == SAFI_UNICAST && path->sub_type == BGP_ROUTE_IMPORTED - && path->extra && path->extra->num_labels - && (path->attr->evpn_overlay.type - != OVERLAY_INDEX_GATEWAY_IP)) { + if (safi == SAFI_UNICAST && + path->sub_type == BGP_ROUTE_IMPORTED && + bgp_path_info_num_labels(path) && + (path->attr->evpn_overlay.type != OVERLAY_INDEX_GATEWAY_IP)) { bnc_is_valid_nexthop = bgp_isvalid_nexthop_for_l3vpn(bnc, path) ? true diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ebeaf9a474c4..5e4c03ae365f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -324,9 +324,7 @@ struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi) bool bgp_path_info_has_valid_label(const struct bgp_path_info *path) { - if (!path->extra) - return false; - if (!path->extra->num_labels) + if (!bgp_path_info_num_labels(path)) return false; return bgp_is_valid_label(&path->extra->label[0]); @@ -338,13 +336,24 @@ bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, uint32_t bpi_num_labels; const mpls_label_t *bpi_label; - bpi_num_labels = bpi->extra ? bpi->extra->num_labels : 0; + bpi_num_labels = bgp_path_info_num_labels(bpi); bpi_label = bpi_num_labels ? bpi->extra->label : NULL; return bgp_labels_same(bpi_label, bpi_num_labels, (const mpls_label_t *)label, n); } +uint32_t bgp_path_info_num_labels(const struct bgp_path_info *pi) +{ + if (!pi) + return 0; + + if (!pi->extra) + return 0; + + return pi->extra->num_labels; +} + /* Free bgp route information. */ void bgp_path_info_free_with_caller(const char *name, struct bgp_path_info *path) @@ -2232,8 +2241,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, * off box as that the RT and RD created are localy * significant and globaly useless. */ - if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels - && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) + if (safi == SAFI_MPLS_VPN && bgp_path_info_num_labels(pi) && + pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) return false; /* If it's labeled safi, make sure the route has a valid label. */ @@ -5659,18 +5668,16 @@ static void bgp_soft_reconfig_table_update(struct peer *peer, safi_t safi, struct prefix_rd *prd) { struct bgp_path_info *pi; - uint32_t num_labels = 0; - mpls_label_t *label_pnt = NULL; + uint32_t num_labels; + mpls_label_t *label_pnt; struct bgp_route_evpn evpn; for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (pi->peer == peer) break; - if (pi && pi->extra) - num_labels = pi->extra->num_labels; - if (num_labels) - label_pnt = &pi->extra->label[0]; + num_labels = bgp_path_info_num_labels(pi); + label_pnt = num_labels ? &pi->extra->label[0] : NULL; if (pi) memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr), sizeof(evpn)); @@ -6835,7 +6842,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, bgp, p, pi); } } else { - if (pi->extra && pi->extra->num_labels) + if (bgp_path_info_num_labels(pi)) label = decode_label( &pi->extra->label[0]); } @@ -10506,7 +10513,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, json_nexthop_global = json_object_new_object(); } - if (path->extra && path->extra->num_labels) { + if (bgp_path_info_num_labels(path)) { bgp_evpn_label2str(path->extra->label, path->extra->num_labels, vni_buf, sizeof(vni_buf)); } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 2aa721a3b65a..37c5dec758c6 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -754,6 +754,7 @@ extern void bgp_path_info_delete(struct bgp_dest *dest, extern struct bgp_path_info_extra * bgp_path_info_extra_get(struct bgp_path_info *path); extern bool bgp_path_info_has_valid_label(const struct bgp_path_info *path); +extern uint32_t bgp_path_info_num_labels(const struct bgp_path_info *pi); extern void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *path, uint32_t flag); extern void bgp_path_info_unset_flag(struct bgp_dest *dest, diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index dc26a1f5dd82..8dbe705aa53c 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1056,7 +1056,7 @@ static enum route_map_cmd_result_t route_match_vni(void *rule, const struct prefix *prefix, void *object) { vni_t vni = 0; - unsigned int label_cnt = 0; + unsigned int label_cnt; struct bgp_path_info *path = NULL; struct prefix_evpn *evp = (struct prefix_evpn *) prefix; @@ -1081,11 +1081,8 @@ route_match_vni(void *rule, const struct prefix *prefix, void *object) && evp->prefix.route_type != BGP_EVPN_IP_PREFIX_ROUTE)) return RMAP_NOOP; - if (path->extra == NULL) - return RMAP_NOMATCH; - - for (; - label_cnt < BGP_MAX_LABELS && label_cnt < path->extra->num_labels; + for (label_cnt = 0; label_cnt < BGP_MAX_LABELS && + label_cnt < bgp_path_info_num_labels(path); label_cnt++) { if (vni == label2vni(&path->extra->label[label_cnt])) return RMAP_MATCH; diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index f5508a0a7345..63742fad4a9e 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -656,17 +656,16 @@ static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, safi_t safi) { struct bgp_adj_in *ain; + mpls_label_t *label; + uint32_t num_labels; for (ain = bgp_dest->adj_in; ain; ain = ain->next) { struct bgp_path_info *path = bgp_dest_get_bgp_path_info(bgp_dest); - mpls_label_t *label = NULL; - uint32_t num_labels = 0; - if (path && path->extra) { - label = path->extra->label; - num_labels = path->extra->num_labels; - } + num_labels = bgp_path_info_num_labels(path); + label = num_labels ? path->extra->label : NULL; + (void)bgp_update(ain->peer, bgp_dest_get_prefix(bgp_dest), ain->addpath_rx_id, ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, label, diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 1f691b6a9e19..def2afb6da51 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -814,9 +814,10 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) path); label_pnt = &label; num_labels = 1; - } else if (path && path->extra) { - label_pnt = &path->extra->label[0]; - num_labels = path->extra->num_labels; + } else { + num_labels = bgp_path_info_num_labels(path); + label_pnt = num_labels ? &path->extra->label[0] + : NULL; } if (stream_empty(snlri)) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 49b3ef371270..623839d21285 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1301,8 +1301,6 @@ static void bgp_zebra_announce_parse_nexthop( } for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) { - labels = NULL; - num_labels = 0; uint64_t nh_weight; bool is_evpn; bool is_parent_evpn; @@ -1341,7 +1339,7 @@ static void bgp_zebra_announce_parse_nexthop( api_nh->srte_color = bgp_attr_get_color(info->attr); if (bgp_debug_zebra(&api->prefix)) { - if (mpinfo->extra && mpinfo->extra->num_labels) { + if (bgp_path_info_num_labels(mpinfo)) { zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d", __func__, p, bgp_is_valid_label( @@ -1413,13 +1411,10 @@ static void bgp_zebra_announce_parse_nexthop( mpinfo->peer->sort == BGP_PEER_CONFED)) *allow_recursion = true; - if (mpinfo->extra) { - labels = mpinfo->extra->label; - num_labels = mpinfo->extra->num_labels; - } + num_labels = bgp_path_info_num_labels(mpinfo); + labels = num_labels ? mpinfo->extra->label : NULL; - if (labels && (num_labels > 0) && - (is_evpn || bgp_is_valid_label(&labels[0]))) { + if (num_labels && (is_evpn || bgp_is_valid_label(&labels[0]))) { enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE; if (is_evpn) { diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 7fb7d5d7aac5..7e19fb8c979b 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -1271,7 +1271,7 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, /* label comes from MP_REACH_NLRI label */ vo->v.l2addr.label = - bpi->extra->num_labels + bgp_path_info_num_labels(bpi) ? decode_label(&bpi->extra->label[0]) : MPLS_INVALID_LABEL; @@ -4166,7 +4166,7 @@ static void rfapiBgpTableFilteredImport(struct bgp *bgp, BGP_PATH_REMOVED)) continue; - if (bpi->extra && bpi->extra->num_labels) + if (bgp_path_info_num_labels(bpi)) label = decode_label( &bpi->extra->label[0]); (*rfapiBgpInfoFilteredImportFunction( diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 11dccbf1b5f5..5c6357672059 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -692,7 +692,7 @@ static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri, /* label comes from MP_REACH_NLRI label */ vo->v.l2addr.label = - bpi->extra->num_labels + bgp_path_info_num_labels(bpi) ? decode_label(&bpi->extra->label[0]) : MPLS_INVALID_LABEL; diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index 2576a283f522..ddf95b63fc71 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -413,7 +413,7 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p, XFREE(MTYPE_ECOMMUNITY_STR, s); } - if (bpi->extra != NULL && bpi->extra->num_labels) { + if (bgp_path_info_num_labels(bpi)) { if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) vty_out(vty, " label=VRF2VRF"); else @@ -1052,7 +1052,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, snprintf(buf_un, sizeof(buf_un), "%s", inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, sizeof(buf_ntop))); - if (bpi->extra && bpi->extra->num_labels) { + if (bgp_path_info_num_labels(bpi)) { uint32_t l = decode_label(&bpi->extra->label[0]); snprintf(buf_vn, sizeof(buf_vn), "Label: %d", l); } else /* should never happen */ @@ -1161,8 +1161,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, } } } - if (tun_type != BGP_ENCAP_TYPE_MPLS && bpi->extra && - bpi->extra->num_labels) { + if (tun_type != BGP_ENCAP_TYPE_MPLS && bgp_path_info_num_labels(bpi)) { uint32_t l = decode_label(&bpi->extra->label[0]); if (!MPLS_LABEL_IS_NULL(l)) { diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 09260dbca18a..fbc0256128df 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -470,7 +470,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( if (bgp_attr_get_ecommunity(bpi->attr)) ecommunity_merge(new_ecom, bgp_attr_get_ecommunity(bpi->attr)); - if (bpi->extra && bpi->extra->num_labels) + if (bgp_path_info_num_labels(bpi)) label = decode_label(&bpi->extra->label[0]); add_vnc_route(&vncHDResolveNve, bgp, SAFI_MPLS_VPN, @@ -1699,7 +1699,8 @@ static void vnc_import_bgp_exterior_add_route_it( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc .import.rd; - if (bpi_interior->extra->num_labels) + if (bgp_path_info_num_labels( + bpi_interior)) label = decode_label( &bpi_interior->extra ->label[0]); @@ -1870,7 +1871,8 @@ void vnc_import_bgp_exterior_del_route( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc .import.rd; - if (bpi_interior->extra->num_labels) + if (bgp_path_info_num_labels( + bpi_interior)) label = decode_label( &bpi_interior->extra ->label[0]); @@ -2019,7 +2021,7 @@ void vnc_import_bgp_exterior_add_route_interior( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc.import.rd; - if (bpi_interior->extra->num_labels) + if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( &bpi_interior->extra->label[0]); } else @@ -2134,7 +2136,7 @@ void vnc_import_bgp_exterior_add_route_interior( if (bpi->extra) { prd = &bpi->extra->vnc->vnc .import.rd; - if (bpi->extra->num_labels) + if (bgp_path_info_num_labels(bpi)) label = decode_label( &bpi->extra->label [0]); @@ -2158,7 +2160,8 @@ void vnc_import_bgp_exterior_add_route_interior( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc .import.rd; - if (bpi_interior->extra->num_labels) + if (bgp_path_info_num_labels( + bpi_interior)) label = decode_label( &bpi_interior->extra ->label[0]); @@ -2278,7 +2281,7 @@ void vnc_import_bgp_exterior_add_route_interior( */ if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc.import.rd; - if (bpi_interior->extra->num_labels) + if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( &bpi_interior->extra->label[0]); } else @@ -2387,7 +2390,7 @@ void vnc_import_bgp_exterior_del_route_interior( if (bpi_interior->extra) { prd = &bpi_interior->extra->vnc->vnc.import.rd; - if (bpi_interior->extra->num_labels) + if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( &bpi_interior->extra->label[0]); } else @@ -2466,7 +2469,7 @@ void vnc_import_bgp_exterior_del_route_interior( if (bpi->extra) { prd = &bpi->extra->vnc->vnc.import.rd; - if (bpi->extra->num_labels) + if (bgp_path_info_num_labels(bpi)) label = decode_label( &bpi->extra->label[0]); } else From ae54c9e455ec7a4fb5289a6c3a28626227e83e68 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Wed, 5 Jun 2024 11:27:15 +0200 Subject: [PATCH 203/472] bgpd: fix too leading tabs in vnc_import_bgp Small rework to fix the following checkpatch warning: > < WARNING: Too many leading tabs - consider code refactoring > < #2142: FILE: /tmp/f1-1616988/vnc_import_bgp.c:2142: Signed-off-by: Louis Scalbert --- bgpd/rfapi/vnc_import_bgp.c | 129 ++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 56 deletions(-) diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index fbc0256128df..255e87b0965b 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -414,7 +414,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( uint32_t lifetime; uint32_t *plifetime; struct bgp_attr_encap_subtlv *encaptlvs; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; struct rfapi_un_option optary[3]; struct rfapi_un_option *opt = NULL; @@ -472,6 +472,8 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( if (bgp_path_info_num_labels(bpi)) label = decode_label(&bpi->extra->label[0]); + else + label = MPLS_INVALID_LABEL; add_vnc_route(&vncHDResolveNve, bgp, SAFI_MPLS_VPN, prefix, /* unicast route prefix */ @@ -1679,7 +1681,7 @@ static void vnc_import_bgp_exterior_add_route_it( bpi_interior = bpi_interior->next) { struct prefix_rd *prd; struct attr new_attr; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; if (!is_usable_interior_route(bpi_interior)) continue; @@ -1696,17 +1698,18 @@ static void vnc_import_bgp_exterior_add_route_it( */ have_usable_route = 1; - if (bpi_interior->extra) { + if (bpi_interior->extra) prd = &bpi_interior->extra->vnc->vnc .import.rd; - if (bgp_path_info_num_labels( - bpi_interior)) - label = decode_label( - &bpi_interior->extra - ->label[0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi_interior)) + label = decode_label( + &bpi_interior->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + /* use local_pref from unicast route */ memset(&new_attr, 0, sizeof(new_attr)); new_attr = *bpi_interior->attr; @@ -1855,7 +1858,7 @@ void vnc_import_bgp_exterior_del_route( for (bpi_interior = rn->info; bpi_interior; bpi_interior = bpi_interior->next) { struct prefix_rd *prd; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; if (!is_usable_interior_route(bpi_interior)) continue; @@ -1868,17 +1871,18 @@ void vnc_import_bgp_exterior_del_route( */ have_usable_route = 1; - if (bpi_interior->extra) { + if (bpi_interior->extra) prd = &bpi_interior->extra->vnc->vnc .import.rd; - if (bgp_path_info_num_labels( - bpi_interior)) - label = decode_label( - &bpi_interior->extra - ->label[0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi_interior)) + label = decode_label( + &bpi_interior->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + rfapiBgpInfoFilteredImportVPN( it, FIF_ACTION_KILL, bpi_interior->peer, NULL, /* rfd */ @@ -2014,19 +2018,22 @@ void vnc_import_bgp_exterior_add_route_interior( struct prefix_rd *prd; struct attr new_attr; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; assert(bpi_exterior); assert(pfx_exterior); - if (bpi_interior->extra) { + if (bpi_interior->extra) prd = &bpi_interior->extra->vnc->vnc.import.rd; - if (bgp_path_info_num_labels(bpi_interior)) - label = decode_label( - &bpi_interior->extra->label[0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi_interior)) + label = decode_label( + &bpi_interior->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + /* use local_pref from unicast route */ memset(&new_attr, 0, sizeof(struct attr)); new_attr = *bpi_interior->attr; @@ -2105,7 +2112,7 @@ void vnc_import_bgp_exterior_add_route_interior( struct bgp_path_info *bpi; struct prefix_rd *prd; struct attr new_attr; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; /* do pull-down */ @@ -2132,17 +2139,18 @@ void vnc_import_bgp_exterior_add_route_interior( * parent routes. */ for (bpi = par->info; bpi; bpi = bpi->next) { - - if (bpi->extra) { + if (bpi->extra) prd = &bpi->extra->vnc->vnc .import.rd; - if (bgp_path_info_num_labels(bpi)) - label = decode_label( - &bpi->extra->label - [0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi)) + label = decode_label( + &bpi->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + rfapiBgpInfoFilteredImportVPN( it, FIF_ACTION_KILL, bpi->peer, NULL, /* rfd */ @@ -2157,17 +2165,18 @@ void vnc_import_bgp_exterior_add_route_interior( * Add constructed exterior routes based on * the new interior route at longer prefix. */ - if (bpi_interior->extra) { + if (bpi_interior->extra) prd = &bpi_interior->extra->vnc->vnc .import.rd; - if (bgp_path_info_num_labels( - bpi_interior)) - label = decode_label( - &bpi_interior->extra - ->label[0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi_interior)) + label = decode_label( + &bpi_interior->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + /* use local_pref from unicast route */ memset(&new_attr, 0, sizeof(struct attr)); new_attr = *bpi_interior->attr; @@ -2250,7 +2259,7 @@ void vnc_import_bgp_exterior_add_route_interior( struct prefix_rd *prd; struct attr new_attr; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; /* do pull-down */ @@ -2279,14 +2288,17 @@ void vnc_import_bgp_exterior_add_route_interior( * Add constructed exterior routes based on the * new interior route at the longer prefix. */ - if (bpi_interior->extra) { + if (bpi_interior->extra) prd = &bpi_interior->extra->vnc->vnc.import.rd; - if (bgp_path_info_num_labels(bpi_interior)) - label = decode_label( - &bpi_interior->extra->label[0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi_interior)) + label = decode_label( + &bpi_interior->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + /* use local_pref from unicast route */ memset(&new_attr, 0, sizeof(struct attr)); new_attr = *bpi_interior->attr; @@ -2386,16 +2398,18 @@ void vnc_import_bgp_exterior_del_route_interior( &cursor)) { struct prefix_rd *prd; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; - if (bpi_interior->extra) { + if (bpi_interior->extra) prd = &bpi_interior->extra->vnc->vnc.import.rd; - if (bgp_path_info_num_labels(bpi_interior)) - label = decode_label( - &bpi_interior->extra->label[0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi_interior)) + label = decode_label(&bpi_interior->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + rfapiBgpInfoFilteredImportVPN( it, FIF_ACTION_KILL, bpi_interior->peer, NULL, /* rfd */ pfx_exterior, NULL, afi, prd, bpi_interior->attr, @@ -2462,19 +2476,22 @@ void vnc_import_bgp_exterior_del_route_interior( struct prefix_rd *prd; struct attr new_attr; - uint32_t label = MPLS_INVALID_LABEL; + uint32_t label; if (bpi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT) continue; - if (bpi->extra) { + if (bpi->extra) prd = &bpi->extra->vnc->vnc.import.rd; - if (bgp_path_info_num_labels(bpi)) - label = decode_label( - &bpi->extra->label[0]); - } else + else prd = NULL; + if (bgp_path_info_num_labels(bpi)) + label = decode_label( + &bpi->extra->label[0]); + else + label = MPLS_INVALID_LABEL; + /* use local_pref from unicast route */ memset(&new_attr, 0, sizeof(new_attr)); new_attr = *bpi->attr; From a6de9104481814508deee38bdcf308f4693a6bca Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 18:11:09 +0100 Subject: [PATCH 204/472] bgpd: store number of labels with 8 bits 8 bits are sufficient to store the number of labels because the current maximum is 2. Signed-off-by: Louis Scalbert --- bgpd/bgp_attr.c | 6 +++--- bgpd/bgp_attr.h | 6 +++--- bgpd/bgp_debug.c | 2 +- bgpd/bgp_debug.h | 2 +- bgpd/bgp_evpn.c | 12 ++++++------ bgpd/bgp_evpn.h | 6 +++--- bgpd/bgp_label.c | 4 ++-- bgpd/bgp_label.h | 4 ++-- bgpd/bgp_mac.c | 2 +- bgpd/bgp_mplsvpn.c | 10 +++++----- bgpd/bgp_route.c | 14 +++++++------- bgpd/bgp_route.h | 8 ++++---- bgpd/bgp_rpki.c | 2 +- bgpd/bgp_updgrp_packet.c | 4 ++-- bgpd/bgp_zebra.c | 5 ++--- bgpd/bgp_zebra.h | 2 +- 16 files changed, 44 insertions(+), 45 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 71f02a7f83a2..da4701d069db 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -4158,7 +4158,7 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, const struct prefix *p, const struct prefix_rd *prd, mpls_label_t *label, - uint32_t num_labels, bool addpath_capable, + uint8_t num_labels, bool addpath_capable, uint32_t addpath_tx_id, struct attr *attr) { switch (safi) { @@ -4434,7 +4434,7 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, struct bpacket_attr_vec_arr *vecarr, struct prefix *p, afi_t afi, safi_t safi, struct peer *from, struct prefix_rd *prd, - mpls_label_t *label, uint32_t num_labels, + mpls_label_t *label, uint8_t num_labels, bool addpath_capable, uint32_t addpath_tx_id, struct bgp_path_info *bpi) { @@ -4963,7 +4963,7 @@ size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi) void bgp_packet_mpunreach_prefix(struct stream *s, const struct prefix *p, afi_t afi, safi_t safi, const struct prefix_rd *prd, - mpls_label_t *label, uint32_t num_labels, + mpls_label_t *label, uint8_t num_labels, bool addpath_capable, uint32_t addpath_tx_id, struct attr *attr) { diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index a8ba36d2d91e..f353e76913a7 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -393,7 +393,7 @@ extern bgp_size_t bgp_packet_attribute( struct bgp *bgp, struct peer *peer, struct stream *s, struct attr *attr, struct bpacket_attr_vec_arr *vecarr, struct prefix *p, afi_t afi, safi_t safi, struct peer *from, struct prefix_rd *prd, - mpls_label_t *label, uint32_t num_labels, bool addpath_capable, + mpls_label_t *label, uint8_t num_labels, bool addpath_capable, uint32_t addpath_tx_id, struct bgp_path_info *bpi); extern void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi, const struct prefix *p); @@ -451,7 +451,7 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi, const struct prefix *p, const struct prefix_rd *prd, - mpls_label_t *label, uint32_t num_labels, + mpls_label_t *label, uint8_t num_labels, bool addpath_capable, uint32_t addpath_tx_id, struct attr *); extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi, @@ -462,7 +462,7 @@ extern size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi); extern void bgp_packet_mpunreach_prefix( struct stream *s, const struct prefix *p, afi_t afi, safi_t safi, - const struct prefix_rd *prd, mpls_label_t *label, uint32_t num_labels, + const struct prefix_rd *prd, mpls_label_t *label, uint8_t num_labels, bool addpath_capable, uint32_t addpath_tx_id, struct attr *attr); extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt); diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index b4651ad0ba8a..6228432bd2e8 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -2713,7 +2713,7 @@ bool bgp_debug_zebra(const struct prefix *p) const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi, const struct prefix_rd *prd, union prefixconstptr pu, - mpls_label_t *label, uint32_t num_labels, + mpls_label_t *label, uint8_t num_labels, int addpath_valid, uint32_t addpath_id, struct bgp_route_evpn *overlay_index, char *str, int size) diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index 673926f24cff..061d966dc392 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -175,7 +175,7 @@ extern bool bgp_debug_zebra(const struct prefix *p); extern const char *bgp_debug_rdpfxpath2str( afi_t afi, safi_t safi, const struct prefix_rd *prd, - union prefixconstptr pu, mpls_label_t *label, uint32_t num_labels, + union prefixconstptr pu, mpls_label_t *label, uint8_t num_labels, int addpath_valid, uint32_t addpath_id, struct bgp_route_evpn *overlay_index, char *str, int size); const char *bgp_notify_admin_message(char *buf, size_t bufsz, uint8_t *data, diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index ae5d837cbd85..e19d5efe3488 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1931,7 +1931,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, struct attr *attr_new; struct attr local_attr; mpls_label_t label[BGP_MAX_LABELS]; - uint32_t num_labels = 1; + uint8_t num_labels = 1; int route_change = 1; uint8_t sticky = 0; const struct prefix_evpn *evp; @@ -4676,7 +4676,7 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, uint8_t macaddr_len; /* holds the VNI(s) as in packet */ mpls_label_t label[BGP_MAX_LABELS] = {}; - uint32_t num_labels = 0; + uint8_t num_labels = 0; uint32_t eth_tag; int ret = 0; @@ -5019,7 +5019,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, const struct prefix_rd *prd, - mpls_label_t *label, uint32_t num_labels, + mpls_label_t *label, uint8_t num_labels, struct attr *attr) { int len; @@ -5809,7 +5809,7 @@ int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn) /* * TODO: Hardcoded for a maximum of 2 VNIs right now */ -char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels, char *buf, +char *bgp_evpn_label2str(mpls_label_t *label, uint8_t num_labels, char *buf, int len) { vni_t vni1, vni2; @@ -5893,7 +5893,7 @@ void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json) */ void bgp_evpn_encode_prefix(struct stream *s, const struct prefix *p, const struct prefix_rd *prd, mpls_label_t *label, - uint32_t num_labels, struct attr *attr, + uint8_t num_labels, struct attr *attr, bool addpath_capable, uint32_t addpath_tx_id) { struct prefix_evpn *evp = (struct prefix_evpn *)p; @@ -7737,7 +7737,7 @@ void bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket, * */ mpls_label_t *bgp_evpn_path_info_labels_get_l3vni(mpls_label_t *labels, - uint32_t num_labels) + uint8_t num_labels) { if (!labels) return NULL; diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 11a6f45dd090..223f18a1777a 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -115,12 +115,12 @@ extern void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi); extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf); extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw); -extern char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels, +extern char *bgp_evpn_label2str(mpls_label_t *label, uint8_t num_labels, char *buf, int len); extern void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json); extern void bgp_evpn_encode_prefix(struct stream *s, const struct prefix *p, const struct prefix_rd *prd, - mpls_label_t *label, uint32_t num_labels, + mpls_label_t *label, uint8_t num_labels, struct attr *attr, bool addpath_capable, uint32_t addpath_tx_id); extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr, @@ -177,7 +177,7 @@ extern void bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket, void *arg); extern mpls_label_t *bgp_evpn_path_info_labels_get_l3vni(mpls_label_t *labels, - uint32_t num_labels); + uint8_t num_labels); extern vni_t bgp_evpn_path_info_get_l3vni(const struct bgp_path_info *pi); extern bool bgp_evpn_mpath_has_dvni(const struct bgp *bgp_vrf, struct bgp_path_info *mpinfo); diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index f57663d7a1b3..edd3a35e813c 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -472,8 +472,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, return BGP_NLRI_PARSE_OK; } -bool bgp_labels_same(const mpls_label_t *tbl_a, const uint32_t num_labels_a, - const mpls_label_t *tbl_b, const uint32_t num_labels_b) +bool bgp_labels_same(const mpls_label_t *tbl_a, const uint8_t num_labels_a, + const mpls_label_t *tbl_b, const uint8_t num_labels_b) { uint32_t i; diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h index b54403ee89b0..704d1b49585f 100644 --- a/bgpd/bgp_label.h +++ b/bgpd/bgp_label.h @@ -27,9 +27,9 @@ extern mpls_label_t bgp_adv_label(struct bgp_dest *dest, extern int bgp_nlri_parse_label(struct peer *peer, struct attr *attr, struct bgp_nlri *packet); extern bool bgp_labels_same(const mpls_label_t *tbl_a, - const uint32_t num_labels_a, + const uint8_t num_labels_a, const mpls_label_t *tbl_b, - const uint32_t num_labels_b); + const uint8_t num_labels_b); static inline int bgp_labeled_safi(safi_t safi) { diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index aa793e999d84..1f70ad797012 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -125,7 +125,7 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, { struct bgp_dest *pdest, *dest; struct bgp_path_info *pi; - uint32_t num_labels; + uint8_t num_labels; mpls_label_t *label_pnt; for (pdest = bgp_table_top(table); pdest; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 6c56b05dff2e..cecc91ac70df 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -969,7 +969,7 @@ void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, */ static void setlabels(struct bgp_path_info *bpi, mpls_label_t *label, /* array of labels */ - uint32_t num_labels) + uint8_t num_labels) { if (num_labels) assert(label); @@ -982,7 +982,7 @@ static void setlabels(struct bgp_path_info *bpi, } struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi); - uint32_t i; + uint8_t i; for (i = 0; i < num_labels; ++i) { extra->label[i] = label[i]; @@ -1071,7 +1071,7 @@ static struct bgp_path_info * leak_update(struct bgp *to_bgp, struct bgp_dest *bn, struct attr *new_attr, /* already interned */ afi_t afi, safi_t safi, struct bgp_path_info *source_bpi, - mpls_label_t *label, uint32_t num_labels, struct bgp *bgp_orig, + mpls_label_t *label, uint8_t num_labels, struct bgp *bgp_orig, struct prefix *nexthop_orig, int nexthop_self_flag, int debug) { const struct prefix *p = bgp_dest_get_prefix(bn); @@ -2089,7 +2089,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ const char *debugmsg; struct prefix nexthop_orig; mpls_label_t *label_pnt = NULL; - uint32_t num_labels = 0; + uint8_t num_labels = 0; int nexthop_self_flag = 1; struct bgp_path_info *bpi_ultimate = NULL; struct bgp_path_info *bpi; @@ -3976,7 +3976,7 @@ static void bgp_mplsvpn_nh_label_bind_send_nexthop_label( struct bgp_mplsvpn_nh_label_bind_cache *bmnc, int cmd) { struct prefix pfx_nh, *p = NULL; - uint32_t num_labels = 0, lsp_num_labels; + uint8_t num_labels = 0, lsp_num_labels; mpls_label_t label[MPLS_MAX_LABELS]; struct nexthop *nh; ifindex_t ifindex = IFINDEX_INTERNAL; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5e4c03ae365f..1de3707d7e4b 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -333,7 +333,7 @@ bool bgp_path_info_has_valid_label(const struct bgp_path_info *path) bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, const mpls_label_t *label, uint32_t n) { - uint32_t bpi_num_labels; + uint8_t bpi_num_labels; const mpls_label_t *bpi_label; bpi_num_labels = bgp_path_info_num_labels(bpi); @@ -343,7 +343,7 @@ bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, (const mpls_label_t *)label, n); } -uint32_t bgp_path_info_num_labels(const struct bgp_path_info *pi) +uint8_t bgp_path_info_num_labels(const struct bgp_path_info *pi) { if (!pi) return 0; @@ -1866,7 +1866,7 @@ static bool bgp_check_role_applicability(afi_t afi, safi_t safi) static int bgp_input_modifier(struct peer *peer, const struct prefix *p, struct attr *attr, afi_t afi, safi_t safi, const char *rmap_name, mpls_label_t *label, - uint32_t num_labels, struct bgp_dest *dest) + uint8_t num_labels, struct bgp_dest *dest) { struct bgp_filter *filter; struct bgp_path_info rmap_path = { 0 }; @@ -4528,7 +4528,7 @@ static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi, void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type, struct prefix_rd *prd, mpls_label_t *label, - uint32_t num_labels, int soft_reconfig, + uint8_t num_labels, int soft_reconfig, struct bgp_route_evpn *evpn) { int ret; @@ -5441,7 +5441,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, void bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id, afi_t afi, safi_t safi, int type, int sub_type, struct prefix_rd *prd, mpls_label_t *label, - uint32_t num_labels, struct bgp_route_evpn *evpn) + uint8_t num_labels, struct bgp_route_evpn *evpn) { struct bgp *bgp; char pfx_buf[BGP_PRD_PATH_STRLEN]; @@ -5668,7 +5668,7 @@ static void bgp_soft_reconfig_table_update(struct peer *peer, safi_t safi, struct prefix_rd *prd) { struct bgp_path_info *pi; - uint32_t num_labels; + uint8_t num_labels; mpls_label_t *label_pnt; struct bgp_route_evpn evpn; @@ -6691,7 +6691,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, int vnc_implicit_withdraw = 0; mpls_label_t label = MPLS_INVALID_LABEL; #endif - uint32_t num_labels = 0; + uint8_t num_labels = 0; struct bgp *bgp_nexthop = bgp; assert(bgp_static); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 37c5dec758c6..a1c00dcb162d 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -238,7 +238,7 @@ struct bgp_path_info_extra { /* MPLS label(s) - VNI(s) for EVPN-VxLAN */ mpls_label_t label[BGP_MAX_LABELS]; - uint32_t num_labels; + uint8_t num_labels; /* timestamp of the rib installation */ time_t bgp_rib_uptime; @@ -754,7 +754,7 @@ extern void bgp_path_info_delete(struct bgp_dest *dest, extern struct bgp_path_info_extra * bgp_path_info_extra_get(struct bgp_path_info *path); extern bool bgp_path_info_has_valid_label(const struct bgp_path_info *path); -extern uint32_t bgp_path_info_num_labels(const struct bgp_path_info *pi); +extern uint8_t bgp_path_info_num_labels(const struct bgp_path_info *pi); extern void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *path, uint32_t flag); extern void bgp_path_info_unset_flag(struct bgp_dest *dest, @@ -799,12 +799,12 @@ extern void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type, struct prefix_rd *prd, mpls_label_t *label, - uint32_t num_labels, int soft_reconfig, + uint8_t num_labels, int soft_reconfig, struct bgp_route_evpn *evpn); extern void bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id, afi_t afi, safi_t safi, int type, int sub_type, struct prefix_rd *prd, - mpls_label_t *label, uint32_t num_labels, + mpls_label_t *label, uint8_t num_labels, struct bgp_route_evpn *evpn); /* for bgp_nexthop and bgp_damp */ diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 63742fad4a9e..ccac7545490d 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -657,7 +657,7 @@ static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, { struct bgp_adj_in *ain; mpls_label_t *label; - uint32_t num_labels; + uint8_t num_labels; for (ain = bgp_dest->adj_in; ain; ain = ain->next) { struct bgp_path_info *path = diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index def2afb6da51..be3e27afcb1a 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -667,7 +667,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) uint32_t addpath_tx_id = 0; struct prefix_rd *prd = NULL; mpls_label_t label = MPLS_INVALID_LABEL, *label_pnt = NULL; - uint32_t num_labels = 0; + uint8_t num_labels = 0; if (!subgrp) return NULL; @@ -1084,7 +1084,7 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp, struct bpacket_attr_vec_arr vecarr; bool addpath_capable = false; mpls_label_t label = MPLS_LABEL_IMPLICIT_NULL; - uint32_t num_labels = 0; + uint8_t num_labels = 0; if (DISABLE_BGP_ANNOUNCE) return; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 623839d21285..3558ebfd2d39 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1273,7 +1273,7 @@ static void bgp_zebra_announce_parse_nexthop( struct bgp_path_info local_info; struct bgp_path_info *mpinfo_cp = &local_info; mpls_label_t *labels; - uint32_t num_labels = 0; + uint8_t num_labels = 0; mpls_label_t nh_label; int nh_othervrf = 0; bool nh_updated = false; @@ -4105,8 +4105,7 @@ int bgp_zebra_srv6_manager_release_locator_chunk(const char *name) void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label, ifindex_t ifindex, vrf_id_t vrf_id, enum lsp_types_t ltype, struct prefix *p, - uint32_t num_labels, - mpls_label_t out_labels[]) + uint8_t num_labels, mpls_label_t out_labels[]) { struct zapi_labels zl = {}; struct zapi_nexthop *znh; diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index ef296b963c57..55a4185bde71 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -120,7 +120,7 @@ extern int bgp_zebra_srv6_manager_release_locator_chunk(const char *name); extern void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label, ifindex_t index, vrf_id_t vrfid, enum lsp_types_t ltype, - struct prefix *p, uint32_t num_labels, + struct prefix *p, uint8_t num_labels, mpls_label_t out_labels[]); extern bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size, bool label_auto); From 191675451e5f06f1ab5979f426bab7dc7a79da2d Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 23 Jan 2024 14:24:08 +0100 Subject: [PATCH 205/472] topotests: clarify bgp_vpnv4_ebgp Clarify bgp_vpnv4_ebgp Signed-off-by: Louis Scalbert --- .../bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py index 8b2e674aadf3..6746043aa53b 100644 --- a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py +++ b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py @@ -228,7 +228,12 @@ def test_export_route_target_empty(): router = tgen.gears["r1"] logger.info("r1, Remove 'rt vpn export 52:100' command") router.vtysh_cmd( - "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nno rt vpn export 52:100\n" + """ +configure terminal +router bgp 65500 vrf vrf1 + address-family ipv4 unicast + no rt vpn export 52:100 +""" ) prefix = "172.31.0.1/32" @@ -254,10 +259,15 @@ def test_export_route_target_with_routemap_with_export_route_target(): router = tgen.gears["r1"] logger.info("r1, configuring route target with route-map with export route target") router.vtysh_cmd( - "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nroute-map vpn export rmap\n" - ) - router.vtysh_cmd( - "configure terminal\nroute-map rmap permit 1\nset extcommunity rt 52:100\n" + """ +configure terminal +router bgp 65500 vrf vrf1 + address-family ipv4 unicast + route-map vpn export RMAP +! +route-map RMAP permit 1 + set extcommunity rt 52:100 +""" ) prefix = "172.31.0.1/32" @@ -283,7 +293,11 @@ def test_export_route_target_with_routemap_without_export_route_target(): router = tgen.gears["r1"] logger.info("r1, removing 'set extcommunity rt 52:100.") router.vtysh_cmd( - "configure terminal\nroute-map rmap permit 1\nno set extcommunity rt\n" + """ +configure terminal +route-map RMAP permit 1 + no set extcommunity rt +""" ) prefix = "172.31.0.1/32" @@ -309,7 +323,12 @@ def test_export_route_target_with_default_command(): router = tgen.gears["r1"] logger.info("r1, detach route-map and re-add route target vpn export") router.vtysh_cmd( - "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nrt vpn export 52:100\n" + """ +configure terminal +router bgp 65500 vrf vrf1 + address-family ipv4 unicast + rt vpn export 52:100 +""" ) prefix = "172.31.0.1/32" logger.info("r1, check that exported prefix {} is added back".format(prefix)) @@ -334,9 +353,14 @@ def test_export_suppress_route_target_with_route_map_command(): router = tgen.gears["r1"] logger.info("r1, add an extended comm-list to delete 52:100") - router.vtysh_cmd("configure terminal\nbgp extcommunity-list 1 permit rt 52:100\n") router.vtysh_cmd( - "configure terminal\nroute-map rmap permit 1\nset extended-comm-list 1 delete\n" + """ +configure terminal +bgp extcommunity-list 1 permit rt 52:100 +! +route-map RMAP permit 1 + set extended-comm-list 1 delete +""" ) prefix = "172.31.0.1/32" logger.info("r1, check that exported prefix {} is removed".format(prefix)) @@ -361,7 +385,11 @@ def test_export_add_route_target_to_route_map_command(): router = tgen.gears["r1"] logger.info("r1, add an additional set extcommunity 52:101") router.vtysh_cmd( - "configure terminal\nroute-map rmap permit 1\nset extcommunity rt 52:101\n" + """ +configure terminal +route-map RMAP permit 1 + set extcommunity rt 52:101 +""" ) prefix = "172.31.0.1/32" logger.info("r1, check that exported prefix {} is added back".format(prefix)) From 415befc30a9bfd678734a41ccbb72ce873ee406d Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 24 Feb 2023 11:22:14 +0100 Subject: [PATCH 206/472] topotests: add bgp test to check the ADJ-RIB-OUT label value This test ensures that when r1 changes the label value, then the new value is automatically propagated to remote peer. This demonstrates that the ADJ-RIB-OUT to r2 has been correctly updated. Signed-off-by: Philippe Guibert Signed-off-by: Louis Scalbert --- .../r2/bgp_ipv4_vpn_route_1723101.json | 50 +++++++++++++++++++ .../bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py | 34 +++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 tests/topotests/bgp_vpnv4_ebgp/r2/bgp_ipv4_vpn_route_1723101.json diff --git a/tests/topotests/bgp_vpnv4_ebgp/r2/bgp_ipv4_vpn_route_1723101.json b/tests/topotests/bgp_vpnv4_ebgp/r2/bgp_ipv4_vpn_route_1723101.json new file mode 100644 index 000000000000..2ed76314b21c --- /dev/null +++ b/tests/topotests/bgp_vpnv4_ebgp/r2/bgp_ipv4_vpn_route_1723101.json @@ -0,0 +1,50 @@ +{ + "444:1":{ + "prefix":"172.31.0.1/32", + "advertisedTo":{ + "192.168.0.1":{ + } + }, + "paths":[ + { + "aspath":{ + "string":"65500", + "segments":[ + { + "type":"as-sequence", + "list":[ + 65500 + ] + } + ], + "length":1 + }, + "origin":"incomplete", + "metric":0, + "valid":true, + "bestpath":{ + "overall":true, + "selectionReason":"First path received" + }, + "extendedCommunity":{ + "string":"RT:52:101" + }, + "remoteLabel":102, + "nexthops":[ + { + "ip":"192.168.0.1", + "afi":"ipv4", + "metric":0, + "accessible":true, + "used":true + } + ], + "peer":{ + "peerId":"192.168.0.1", + "routerId":"192.0.2.1", + "type":"external" + } + } + ] + } +} diff --git a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py index 6746043aa53b..da7ac96e6035 100644 --- a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py +++ b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py @@ -404,6 +404,40 @@ def test_export_add_route_target_to_route_map_command(): assert success, "{}, vpnv4 update {} still not present".format(router.name, prefix) +def test_adj_rib_out_label_change(): + """ + Check that changing the VPN label on r1 + is propagated on r2 + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Changing VPN label value to export") + dump = tgen.gears["r1"].vtysh_cmd( + """ +configure terminal + router bgp 65500 vrf vrf1 + address-family ipv4 unicast + label vpn export 102 +""" + ) + # Check BGP IPv4 route entry for 172.31.0.1 on r1 + logger.info("Checking BGP IPv4 routes for convergence on r1") + router = tgen.gears["r2"] + json_file = "{}/{}/bgp_ipv4_vpn_route_1723101.json".format(CWD, router.name) + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + router, + "show bgp ipv4 vpn 172.31.0.1/32 json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() From 40706d5c42bff0400118a332f652219ff49cac62 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 24 Feb 2023 11:53:46 +0100 Subject: [PATCH 207/472] topotests: add bgp test to check the ADJ-RIB-IN label value The test is done on r2. A BGP update is received on r2, and is filtered on r2. The RIB of r2 does not have the BGP update stored, but the ADJ-RIB-IN is yet present. To demonstrate this, if the inbound route-map is removed, then the BGP update should be copied from the the ADJ-RIB-IN and added to the RIB with the label value. Signed-off-by: Philippe Guibert Signed-off-by: Louis Scalbert --- .../bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py index da7ac96e6035..189824311dfe 100644 --- a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py +++ b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py @@ -438,6 +438,92 @@ def test_adj_rib_out_label_change(): assert result is None, assertmsg +def test_adj_rib_in_label_change(): + """ + Check that syncinig with ADJ-RIB-in on r2 + permits restoring the initial label value + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Enable soft-reconfiguration inbound on r2") + + r2 = tgen.gears["r2"] + r2.vtysh_cmd( + """ +configure terminal +router bgp 65501 + address-family ipv4 vpn + neighbor 192.168.0.1 soft-reconfiguration inbound +""" + ) + + logger.info("Applying a deny-all route-map to input on r2") + r2.vtysh_cmd( + """ +configure terminal +route-map DENY-ALL deny 1 +! +router bgp 65501 + address-family ipv4 vpn + neighbor 192.168.0.1 route-map DENY-ALL in +""" + ) + + # check that 172.31.0.1 should not be present + logger.info("Check that received update 172.31.0.1 is not present") + + expected = {} + test_func = partial( + topotest.router_json_cmp, + r2, + "show bgp ipv4 vpn 172.31.0.1/32 json", + expected, + exact=True, + ) + success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assert success, "r2, vpnv4 update 172.31.0.1 still present" + + +def test_adj_rib_in_label_change_remove_rmap(): + """ + Check that syncinig with ADJ-RIB-in on r2 + permits restoring the initial label value + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Removing the deny-all route-map from input on r2") + + r2 = tgen.gears["r2"] + r2.vtysh_cmd( + """ +configure terminal +router bgp 65501 + address-family ipv4 vpn + no neighbor 192.168.0.1 route-map DENY-ALL in +""" + ) + # Check BGP IPv4 route entry for 172.31.0.1 on r1 + logger.info( + "Checking that 172.31.0.1 BGP update is present and has valid label on r2" + ) + json_file = "{}/{}/bgp_ipv4_vpn_route_1723101.json".format(CWD, r2.name) + + expected = json.loads(open(json_file).read()) + test_func = partial( + topotest.router_json_cmp, + r2, + "show bgp ipv4 vpn 172.31.0.1/32 json", + expected, + ) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assertmsg = '"{}" JSON output mismatches'.format(r2.name) + assert result is None, assertmsg + + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() From 3c86f776f053bc9032da8dc3b713f7726117b800 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 23 Feb 2024 15:18:03 +0100 Subject: [PATCH 208/472] bgpd: add bgp_labels hash Add bgp_labels type and hash list. Signed-off-by: Louis Scalbert --- bgpd/bgp_label.c | 119 ++++++++++++++++++++++++++++++++++++ bgpd/bgp_label.h | 15 +++++ bgpd/bgp_main.c | 3 + bgpd/bgp_memory.c | 2 + bgpd/bgp_memory.h | 2 + bgpd/bgpd.c | 1 + tests/bgpd/test_mp_attr.c | 2 + tests/bgpd/test_peer_attr.c | 2 + 8 files changed, 146 insertions(+) diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index edd3a35e813c..f967638de1e5 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -15,6 +15,7 @@ #include "memory.h" #include "nexthop.h" #include "mpls.h" +#include "jhash.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -27,6 +28,124 @@ extern struct zclient *zclient; + +/* MPLS Labels hash routines. */ +static struct hash *labels_hash; + +static void *bgp_labels_hash_alloc(void *p) +{ + const struct bgp_labels *labels = p; + struct bgp_labels *new; + uint8_t i; + + new = XMALLOC(MTYPE_BGP_LABELS, sizeof(struct bgp_labels)); + + new->num_labels = labels->num_labels; + for (i = 0; i < labels->num_labels; i++) + new->label[i] = labels->label[i]; + + return new; +} + +static uint32_t bgp_labels_hash_key_make(const void *p) +{ + const struct bgp_labels *labels = p; + uint32_t key = 0; + + if (labels->num_labels) + key = jhash(&labels->label, + labels->num_labels * sizeof(mpls_label_t), key); + + return key; +} + +static bool bgp_labels_hash_cmp(const void *p1, const void *p2) +{ + return bgp_labels_cmp(p1, p2); +} + +void bgp_labels_init(void) +{ + labels_hash = hash_create(bgp_labels_hash_key_make, bgp_labels_hash_cmp, + "BGP Labels hash"); +} + +/* + * special for hash_clean below + */ +static void bgp_labels_free(void *labels) +{ + XFREE(MTYPE_BGP_LABELS, labels); +} + +void bgp_labels_finish(void) +{ + hash_clean_and_free(&labels_hash, bgp_labels_free); +} + +struct bgp_labels *bgp_labels_intern(struct bgp_labels *labels) +{ + struct bgp_labels *find; + + if (!labels) + return NULL; + + if (!labels->num_labels) + /* do not intern void labels structure */ + return NULL; + + find = (struct bgp_labels *)hash_get(labels_hash, labels, + bgp_labels_hash_alloc); + find->refcnt++; + + return find; +} + +void bgp_labels_unintern(struct bgp_labels **plabels) +{ + struct bgp_labels *labels = *plabels; + struct bgp_labels *ret; + + if (!*plabels) + return; + + /* Decrement labels reference. */ + labels->refcnt--; + + /* If reference becomes zero then free labels object. */ + if (labels->refcnt == 0) { + ret = hash_release(labels_hash, labels); + assert(ret != NULL); + bgp_labels_free(labels); + *plabels = NULL; + } +} + +bool bgp_labels_cmp(const struct bgp_labels *labels1, + const struct bgp_labels *labels2) +{ + uint8_t i; + + if (!labels1 && !labels2) + return true; + + if (!labels1 && labels2) + return false; + + if (labels1 && !labels2) + return false; + + if (labels1->num_labels != labels2->num_labels) + return false; + + for (i = 0; i < labels1->num_labels; i++) { + if (labels1->label[i] != labels2->label[i]) + return false; + } + + return true; +} + int bgp_parse_fec_update(void) { struct stream *s; diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h index 704d1b49585f..ecb8dd3543f4 100644 --- a/bgpd/bgp_label.h +++ b/bgpd/bgp_label.h @@ -15,6 +15,21 @@ struct bgp_dest; struct bgp_path_info; struct peer; +/* MPLS label(s) - VNI(s) for EVPN-VxLAN */ +struct bgp_labels { + mpls_label_t label[BGP_MAX_LABELS]; + uint8_t num_labels; + + unsigned long refcnt; +}; + +extern void bgp_labels_init(void); +extern void bgp_labels_finish(void); +extern struct bgp_labels *bgp_labels_intern(struct bgp_labels *labels); +extern void bgp_labels_unintern(struct bgp_labels **plabels); +extern bool bgp_labels_cmp(const struct bgp_labels *labels1, + const struct bgp_labels *labels2); + extern int bgp_reg_for_label_callback(mpls_label_t new_label, void *labelid, bool allocated); extern void bgp_reg_dereg_for_label(struct bgp_dest *dest, diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 2bbd3a4b1bb8..97658d340bf3 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -225,6 +225,9 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) /* reverse bgp_attr_init */ bgp_attr_finish(); + /* reverse bgp_labels_init */ + bgp_labels_finish(); + /* stop pthreads */ bgp_pthreads_finish(); diff --git a/bgpd/bgp_memory.c b/bgpd/bgp_memory.c index 53c03d8102ea..c1804fb70a33 100644 --- a/bgpd/bgp_memory.c +++ b/bgpd/bgp_memory.c @@ -102,6 +102,8 @@ DEFINE_MTYPE(BGPD, BGP_FILTER_NAME, "BGP Filter Information"); DEFINE_MTYPE(BGPD, BGP_DUMP_STR, "BGP Dump String Information"); DEFINE_MTYPE(BGPD, ENCAP_TLV, "ENCAP TLV"); +DEFINE_MTYPE(BGPD, BGP_LABELS, "BGP LABELS"); + DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS, "BGP TEA Options"); DEFINE_MTYPE(BGPD, BGP_TEA_OPTIONS_VALUE, "BGP TEA Options Value"); diff --git a/bgpd/bgp_memory.h b/bgpd/bgp_memory.h index 865c5880db58..4ae49a2c17ec 100644 --- a/bgpd/bgp_memory.h +++ b/bgpd/bgp_memory.h @@ -98,6 +98,8 @@ DECLARE_MTYPE(BGP_FILTER_NAME); DECLARE_MTYPE(BGP_DUMP_STR); DECLARE_MTYPE(ENCAP_TLV); +DECLARE_MTYPE(BGP_LABELS); + DECLARE_MTYPE(BGP_TEA_OPTIONS); DECLARE_MTYPE(BGP_TEA_OPTIONS_VALUE); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index d8eba0ab2234..2e69b3fc3850 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -8547,6 +8547,7 @@ void bgp_init(unsigned short instance) /* BGP inits. */ bgp_attr_init(); + bgp_labels_init(); bgp_debug_init(); bgp_community_alias_init(); bgp_dump_init(); diff --git a/tests/bgpd/test_mp_attr.c b/tests/bgpd/test_mp_attr.c index cebdda9e5c71..44a210403f40 100644 --- a/tests/bgpd/test_mp_attr.c +++ b/tests/bgpd/test_mp_attr.c @@ -23,6 +23,7 @@ #include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_vty.h" #include "bgpd/bgp_network.h" +#include "bgpd/bgp_label.h" #define VT100_RESET "\x1b[0m" #define VT100_RED "\x1b[31m" @@ -1075,6 +1076,7 @@ int main(void) vrf_init(NULL, NULL, NULL, NULL); bgp_option_set(BGP_OPT_NO_LISTEN); bgp_attr_init(); + bgp_labels_init(); if (fileno(stdout) >= 0) tty = isatty(fileno(stdout)); diff --git a/tests/bgpd/test_peer_attr.c b/tests/bgpd/test_peer_attr.c index 12c2f1103abe..767c41cfee67 100644 --- a/tests/bgpd/test_peer_attr.c +++ b/tests/bgpd/test_peer_attr.c @@ -18,6 +18,7 @@ #include "bgpd/bgp_vty.h" #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_network.h" +#include "bgpd/bgp_label.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -1374,6 +1375,7 @@ static void bgp_shutdown(void) bgp_route_finish(); bgp_route_map_terminate(); bgp_attr_finish(); + bgp_labels_finish(); bgp_pthreads_finish(); access_list_add_hook(NULL); access_list_delete_hook(NULL); From ca32945b1fd694d10307d2885df62251f46bf581 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 18:23:11 +0100 Subject: [PATCH 209/472] bgpd: move labels from extra to extra->labels Move labels from extra to extra->labels. Labels are now stored in a hash list. Signed-off-by: Louis Scalbert --- bgpd/bgp_bmp.c | 26 +++++++++---- bgpd/bgp_evpn.c | 62 +++++++++++++++++++------------ bgpd/bgp_evpn_mh.c | 14 +++++-- bgpd/bgp_label.c | 5 ++- bgpd/bgp_label.h | 5 +++ bgpd/bgp_mac.c | 4 +- bgpd/bgp_mplsvpn.c | 60 +++++++++++------------------- bgpd/bgp_route.c | 73 +++++++++++++++++++++++-------------- bgpd/bgp_route.h | 8 +--- bgpd/bgp_routemap.c | 2 +- bgpd/bgp_rpki.c | 3 +- bgpd/bgp_updgrp_packet.c | 6 ++- bgpd/bgp_zebra.c | 5 ++- bgpd/rfapi/rfapi.c | 7 ++-- bgpd/rfapi/rfapi_import.c | 14 ++++--- bgpd/rfapi/rfapi_rib.c | 2 +- bgpd/rfapi/rfapi_vty.c | 8 ++-- bgpd/rfapi/vnc_import_bgp.c | 23 +++++++----- 18 files changed, 185 insertions(+), 142 deletions(-) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index bf08e30509af..43f8006e2d4b 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -38,6 +38,7 @@ #include "bgpd/bgp_vty.h" #include "bgpd/bgp_trace.h" #include "bgpd/bgp_network.h" +#include "bgpd/bgp_label.h" static void bmp_close(struct bmp *bmp); static struct bmp_bgp *bmp_bgp_find(struct bgp *bgp); @@ -1046,6 +1047,7 @@ static void bmp_monitor(struct bmp *bmp, struct peer *peer, uint8_t flags, static bool bmp_wrsync(struct bmp *bmp, struct pullwr *pullwr) { + uint8_t bpi_num_labels; afi_t afi; safi_t safi; @@ -1219,14 +1221,16 @@ static bool bmp_wrsync(struct bmp *bmp, struct pullwr *pullwr) (safi == SAFI_MPLS_VPN)) prd = (struct prefix_rd *)bgp_dest_get_prefix(bmp->syncrdpos); + bpi_num_labels = bgp_path_info_num_labels(bpi); + if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_SELECTED) && CHECK_FLAG(bmp->targets->afimon[afi][safi], BMP_MON_LOC_RIB)) { bmp_monitor(bmp, bpi->peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, bn_p, prd, bpi->attr, afi, safi, bpi && bpi->extra ? bpi->extra->bgp_rib_uptime : (time_t)(-1L), - bpi->extra ? bpi->extra->label : NULL, - bpi->extra ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); } if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_VALID) && @@ -1234,8 +1238,8 @@ static bool bmp_wrsync(struct bmp *bmp, struct pullwr *pullwr) bmp_monitor(bmp, bpi->peer, BMP_PEER_FLAG_L, BMP_PEER_TYPE_GLOBAL_INSTANCE, bn_p, prd, bpi->attr, afi, safi, bpi->uptime, - bpi->extra ? bpi->extra->label : NULL, - bpi->extra ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); if (adjin) /* TODO: set label here when adjin supports labels */ @@ -1292,6 +1296,7 @@ static bool bmp_wrqueue_locrib(struct bmp *bmp, struct pullwr *pullwr) struct peer *peer; struct bgp_dest *bn = NULL; bool written = false; + uint8_t bpi_num_labels; bqe = bmp_pull_locrib(bmp); if (!bqe) @@ -1351,12 +1356,14 @@ static bool bmp_wrqueue_locrib(struct bmp *bmp, struct pullwr *pullwr) break; } + bpi_num_labels = bgp_path_info_num_labels(bpi); + bmp_monitor(bmp, peer, 0, BMP_PEER_TYPE_LOC_RIB_INSTANCE, &bqe->p, prd, bpi ? bpi->attr : NULL, afi, safi, bpi && bpi->extra ? bpi->extra->bgp_rib_uptime : (time_t)(-1L), - (bpi && bpi->extra) ? bpi->extra->label : NULL, - (bpi && bpi->extra) ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); written = true; out: @@ -1375,6 +1382,7 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) struct peer *peer; struct bgp_dest *bn = NULL; bool written = false; + uint8_t bpi_num_labels; bqe = bmp_pull(bmp); if (!bqe) @@ -1426,12 +1434,14 @@ static bool bmp_wrqueue(struct bmp *bmp, struct pullwr *pullwr) break; } + bpi_num_labels = bgp_path_info_num_labels(bpi); + bmp_monitor(bmp, peer, BMP_PEER_FLAG_L, BMP_PEER_TYPE_GLOBAL_INSTANCE, &bqe->p, prd, bpi ? bpi->attr : NULL, afi, safi, bpi ? bpi->uptime : monotime(NULL), - (bpi && bpi->extra) ? bpi->extra->label : NULL, - (bpi && bpi->extra) ? bpi->extra->num_labels : 0); + bpi_num_labels ? bpi->extra->labels->label : NULL, + bpi_num_labels); written = true; } diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index e19d5efe3488..5ce5b19b1840 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1602,7 +1602,7 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, { struct attr *attr_new = NULL; struct bgp_path_info *pi = NULL; - mpls_label_t label = MPLS_INVALID_LABEL; + struct bgp_labels bgp_labels = {}; struct bgp_path_info *local_pi = NULL; struct bgp_path_info *tmp_pi = NULL; @@ -1630,9 +1630,14 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, /* Type-5 routes advertise the L3-VNI */ bgp_path_info_extra_get(pi); - vni2label(bgp_vrf->l3vni, &label); - memcpy(&pi->extra->label, &label, sizeof(label)); - pi->extra->num_labels = 1; + vni2label(bgp_vrf->l3vni, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; + if (!bgp_path_info_labels_same(pi, &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&pi->extra->labels); + pi->extra->labels = bgp_labels_intern(&bgp_labels); + } + /* add the route entry to route node*/ bgp_path_info_add(dest, pi); @@ -1930,15 +1935,13 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, struct bgp_path_info *local_pi; struct attr *attr_new; struct attr local_attr; - mpls_label_t label[BGP_MAX_LABELS]; - uint8_t num_labels = 1; + struct bgp_labels bgp_labels = {}; int route_change = 1; uint8_t sticky = 0; const struct prefix_evpn *evp; *pi = NULL; evp = (const struct prefix_evpn *)bgp_dest_get_prefix(dest); - memset(&label, 0, sizeof(label)); /* See if this is an update of an existing route, or a new add. */ local_pi = bgp_evpn_route_get_local_path(bgp, dest); @@ -1980,7 +1983,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, bgp_path_info_extra_get(tmp_pi); /* The VNI goes into the 'label' field of the route */ - vni2label(vpn->vni, &label[0]); + vni2label(vpn->vni, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; /* Type-2 routes may carry a second VNI - the L3-VNI. * Only attach second label if we are advertising two labels for @@ -1992,13 +1996,16 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, l3vni = bgpevpn_get_l3vni(vpn); if (l3vni) { - vni2label(l3vni, &label[1]); - num_labels++; + vni2label(l3vni, &bgp_labels.label[1]); + bgp_labels.num_labels++; } } - memcpy(&tmp_pi->extra->label, label, sizeof(label)); - tmp_pi->extra->num_labels = num_labels; + if (!bgp_path_info_labels_same(tmp_pi, &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&tmp_pi->extra->labels); + tmp_pi->extra->labels = bgp_labels_intern(&bgp_labels); + } if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { if (mac) @@ -2022,7 +2029,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, * The attributes have changed, type-2 routes needs to * be advertised with right labels. */ - vni2label(vpn->vni, &label[0]); + vni2label(vpn->vni, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && CHECK_FLAG(vpn->flags, VNI_FLAG_USE_TWO_LABELS)) { @@ -2030,12 +2038,17 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, l3vni = bgpevpn_get_l3vni(vpn); if (l3vni) { - vni2label(l3vni, &label[1]); - num_labels++; + vni2label(l3vni, &bgp_labels.label[1]); + bgp_labels.num_labels++; } } - memcpy(&tmp_pi->extra->label, label, sizeof(label)); - tmp_pi->extra->num_labels = num_labels; + if (!bgp_path_info_labels_same(tmp_pi, + &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&tmp_pi->extra->labels); + tmp_pi->extra->labels = + bgp_labels_intern(&bgp_labels); + } if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { if (mac) @@ -2983,12 +2996,11 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi, sizeof(struct bgp_path_info_extra_vrfleak)); pi->extra->vrfleak->parent = bgp_path_info_lock(parent_pi); bgp_dest_lock_node((struct bgp_dest *)parent_pi->net); - if (parent_pi->extra) { - memcpy(&pi->extra->label, &parent_pi->extra->label, - sizeof(pi->extra->label)); - pi->extra->num_labels = bgp_path_info_num_labels(parent_pi); + if (parent_pi->extra) pi->extra->igpmetric = parent_pi->extra->igpmetric; - } + + if (bgp_path_info_num_labels(parent_pi)) + pi->extra->labels = bgp_labels_intern(parent_pi->extra->labels); bgp_path_info_add(dest, pi); @@ -7756,8 +7768,10 @@ vni_t bgp_evpn_path_info_get_l3vni(const struct bgp_path_info *pi) if (!pi->extra) return 0; - return label2vni(bgp_evpn_path_info_labels_get_l3vni( - pi->extra->label, pi->extra->num_labels)); + return label2vni( + bgp_evpn_path_info_labels_get_l3vni(pi->extra->labels->label, + pi->extra->labels + ->num_labels)); } /* diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index d63e011560a5..d557c0a8dbc8 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -358,6 +358,7 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, struct bgp_path_info *tmp_pi = NULL; struct bgp_path_info *local_pi = NULL; /* local route entry if any */ struct bgp_path_info *remote_pi = NULL; /* remote route entry if any */ + struct bgp_labels bgp_labels = {}; struct attr *attr_new = NULL; struct prefix_evpn *evp; @@ -404,11 +405,16 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE) { bgp_path_info_extra_get(tmp_pi); - tmp_pi->extra->num_labels = 1; + bgp_labels.num_labels = 1; if (vpn) - vni2label(vpn->vni, &tmp_pi->extra->label[0]); - else - tmp_pi->extra->label[0] = 0; + vni2label(vpn->vni, &bgp_labels.label[0]); + if (!bgp_path_info_labels_same(tmp_pi, + &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&tmp_pi->extra->labels); + tmp_pi->extra->labels = + bgp_labels_intern(&bgp_labels); + } } /* add the newly created path to the route-node */ diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index f967638de1e5..839437e1202b 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -208,8 +208,9 @@ mpls_label_t bgp_adv_label(struct bgp_dest *dest, struct bgp_path_info *pi, if (!dest || !pi || !to) return MPLS_INVALID_LABEL; - remote_label = bgp_path_info_num_labels(pi) ? pi->extra->label[0] - : MPLS_INVALID_LABEL; + remote_label = bgp_path_info_num_labels(pi) + ? pi->extra->labels->label[0] + : MPLS_INVALID_LABEL; from = pi->peer; reflect = ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP)); diff --git a/bgpd/bgp_label.h b/bgpd/bgp_label.h index ecb8dd3543f4..2ffd5b699dc0 100644 --- a/bgpd/bgp_label.h +++ b/bgpd/bgp_label.h @@ -15,6 +15,11 @@ struct bgp_dest; struct bgp_path_info; struct peer; +/* Maximum number of labels we can process or send with a prefix. We + * really do only 1 for MPLS (BGP-LU) but we can do 2 for EVPN-VxLAN. + */ +#define BGP_MAX_LABELS 2 + /* MPLS label(s) - VNI(s) for EVPN-VxLAN */ struct bgp_labels { mpls_label_t label[BGP_MAX_LABELS]; diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index 1f70ad797012..31e84d13c4ee 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -14,6 +14,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_mac.h" #include "bgpd/bgp_memory.h" +#include "bgpd/bgp_label.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_packet.h" #include "bgpd/bgp_rd.h" @@ -170,7 +171,8 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer, continue; num_labels = bgp_path_info_num_labels(pi); - label_pnt = num_labels ? &pi->extra->label[0] : NULL; + label_pnt = num_labels ? &pi->extra->labels->label[0] + : NULL; prd.family = AF_UNSPEC; prd.prefixlen = 64; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index cecc91ac70df..90881621b331 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -964,35 +964,6 @@ void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, } } -/* - * make encoded route labels match specified encoded label set - */ -static void setlabels(struct bgp_path_info *bpi, - mpls_label_t *label, /* array of labels */ - uint8_t num_labels) -{ - if (num_labels) - assert(label); - assert(num_labels <= BGP_MAX_LABELS); - - if (!num_labels) { - if (bpi->extra) - bpi->extra->num_labels = 0; - return; - } - - struct bgp_path_info_extra *extra = bgp_path_info_extra_get(bpi); - uint8_t i; - - for (i = 0; i < num_labels; ++i) { - extra->label[i] = label[i]; - if (!bgp_is_valid_label(&label[i])) { - bgp_set_valid_label(&extra->label[i]); - } - } - extra->num_labels = num_labels; -} - static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn, struct attr *new_attr, afi_t afi, safi_t safi, @@ -1079,6 +1050,9 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, struct bgp_path_info *new; struct bgp_path_info_extra *extra; struct bgp_path_info *parent = source_bpi; + struct bgp_labels bgp_labels = {}; + bool labelssame; + uint8_t i; if (debug) zlog_debug( @@ -1113,9 +1087,15 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, break; } + bgp_labels.num_labels = num_labels; + for (i = 0; i < num_labels; i++) { + bgp_labels.label[i] = label[i]; + bgp_set_valid_label(&bgp_labels.label[i]); + } + if (bpi) { - bool labelssame = bgp_path_info_labels_same(bpi, label, - num_labels); + labelssame = bgp_path_info_labels_same(bpi, bgp_labels.label, + bgp_labels.num_labels); if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED) && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) { @@ -1173,11 +1153,13 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, bpi->uptime = monotime(NULL); /* - * rewrite labels + * update labels */ - if (!labelssame) - setlabels(bpi, label, num_labels); - + if (!labelssame) { + bgp_path_info_extra_get(bpi); + bgp_labels_unintern(&bpi->extra->labels); + bpi->extra->labels = bgp_labels_intern(&bgp_labels); + } if (nexthop_self_flag) bgp_path_info_set_flag(bn, bpi, BGP_PATH_ANNC_NH_SELF); @@ -1235,8 +1217,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, if (CHECK_FLAG(source_bpi->flags, BGP_PATH_ACCEPT_OWN)) bgp_path_info_set_flag(bn, new, BGP_PATH_ACCEPT_OWN); - if (num_labels) - setlabels(new, label, num_labels); + if (bgp_labels.num_labels) + new->extra->labels = bgp_labels_intern(&bgp_labels); new->extra->vrfleak->parent = bgp_path_info_lock(parent); bgp_dest_lock_node( @@ -2337,7 +2319,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ num_labels = origin_local ? 0 : bgp_path_info_num_labels(path_vpn); - label_pnt = num_labels ? path_vpn->extra->label : NULL; + label_pnt = num_labels ? path_vpn->extra->labels->label : NULL; } if (debug) @@ -4221,7 +4203,7 @@ void bgp_mplsvpn_nh_label_bind_register_local_label(struct bgp *bgp, mpls_label_t label; label = bgp_path_info_num_labels(pi) - ? decode_label(&pi->extra->label[0]) + ? decode_label(&pi->extra->labels->label[0]) : MPLS_INVALID_LABEL; tree = &bgp->mplsvpn_nh_label_bind; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 1de3707d7e4b..919c219c6ce9 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -305,6 +305,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra) XFREE(MTYPE_BGP_ROUTE_EXTRA_VNC, e->vnc); #endif + if (e->labels) + bgp_labels_unintern(&e->labels); + XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra); } @@ -327,7 +330,7 @@ bool bgp_path_info_has_valid_label(const struct bgp_path_info *path) if (!bgp_path_info_num_labels(path)) return false; - return bgp_is_valid_label(&path->extra->label[0]); + return bgp_is_valid_label(&path->extra->labels->label[0]); } bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, @@ -337,7 +340,7 @@ bool bgp_path_info_labels_same(const struct bgp_path_info *bpi, const mpls_label_t *bpi_label; bpi_num_labels = bgp_path_info_num_labels(bpi); - bpi_label = bpi_num_labels ? bpi->extra->label : NULL; + bpi_label = bpi_num_labels ? bpi->extra->labels->label : NULL; return bgp_labels_same(bpi_label, bpi_num_labels, (const mpls_label_t *)label, n); @@ -351,7 +354,10 @@ uint8_t bgp_path_info_num_labels(const struct bgp_path_info *pi) if (!pi->extra) return 0; - return pi->extra->num_labels; + if (!pi->extra->labels) + return 0; + + return pi->extra->labels->num_labels; } /* Free bgp route information. */ @@ -1871,6 +1877,7 @@ static int bgp_input_modifier(struct peer *peer, const struct prefix *p, struct bgp_filter *filter; struct bgp_path_info rmap_path = { 0 }; struct bgp_path_info_extra extra = { 0 }; + struct bgp_labels bgp_labels = {}; route_map_result_t ret; struct route_map *rmap = NULL; @@ -1902,11 +1909,12 @@ static int bgp_input_modifier(struct peer *peer, const struct prefix *p, rmap_path.attr = attr; rmap_path.extra = &extra; rmap_path.net = dest; + extra.labels = &bgp_labels; - extra.num_labels = num_labels; + bgp_labels.num_labels = num_labels; if (label && num_labels && num_labels <= BGP_MAX_LABELS) - memcpy(extra.label, label, - num_labels * sizeof(mpls_label_t)); + memcpy(bgp_labels.label, label, + num_labels * sizeof(mpls_label_t)); SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN); @@ -2242,7 +2250,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, * significant and globaly useless. */ if (safi == SAFI_MPLS_VPN && bgp_path_info_num_labels(pi) && - pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) + pi->extra->labels->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) return false; /* If it's labeled safi, make sure the route has a valid label. */ @@ -4539,7 +4547,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, struct attr *attr_new; struct bgp_path_info *pi; struct bgp_path_info *new = NULL; - struct bgp_path_info_extra *extra; const char *reason; char pfx_buf[BGP_PRD_PATH_STRLEN]; int connected = 0; @@ -4549,6 +4556,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bool force_evpn_import = false; safi_t orig_safi = safi; int allowas_in = 0; + struct bgp_labels bgp_labels = {}; if (frrtrace_enabled(frr_bgp, process_update)) { char pfxprint[PREFIX2STR_BUFFER]; @@ -5056,14 +5064,18 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { - extra = bgp_path_info_extra_get(pi); - if (!bgp_path_info_labels_same(pi, label, num_labels)) { - memcpy(&extra->label, label, - num_labels * sizeof(mpls_label_t)); - extra->num_labels = num_labels; - } + bgp_path_info_extra_get(pi); + bgp_labels.label[0] = *label; + bgp_labels.num_labels = num_labels; if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) - bgp_set_valid_label(&extra->label[0]); + bgp_set_valid_label(&bgp_labels.label[0]); + + if (!bgp_path_info_labels_same(pi, &bgp_labels.label[0], + bgp_labels.num_labels)) { + bgp_labels_unintern(&pi->extra->labels); + pi->extra->labels = + bgp_labels_intern(&bgp_labels); + } } #ifdef ENABLE_BGP_VNC @@ -5255,11 +5267,13 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update MPLS label */ if (has_valid_label) { - extra = bgp_path_info_extra_get(new); - memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t)); - extra->num_labels = num_labels; + bgp_path_info_extra_get(new); + bgp_labels.label[0] = *label; + bgp_labels.num_labels = num_labels; if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) - bgp_set_valid_label(&extra->label[0]); + bgp_set_valid_label(&bgp_labels.label[0]); + + new->extra->labels = bgp_labels_intern(&bgp_labels); } /* Nexthop reachability check. */ @@ -5677,7 +5691,7 @@ static void bgp_soft_reconfig_table_update(struct peer *peer, break; num_labels = bgp_path_info_num_labels(pi); - label_pnt = num_labels ? &pi->extra->label[0] : NULL; + label_pnt = num_labels ? &pi->extra->labels->label[0] : NULL; if (pi) memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr), sizeof(evpn)); @@ -6693,6 +6707,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, #endif uint8_t num_labels = 0; struct bgp *bgp_nexthop = bgp; + struct bgp_labels labels = {}; assert(bgp_static); @@ -6844,7 +6859,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, } else { if (bgp_path_info_num_labels(pi)) label = decode_label( - &pi->extra->label[0]); + &pi->extra->labels->label[0]); } #endif if (pi->extra && pi->extra->vrfleak->bgp_orig) @@ -6893,8 +6908,9 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, SET_FLAG(new->flags, BGP_PATH_VALID); bgp_path_info_extra_get(new); if (num_labels) { - new->extra->label[0] = bgp_static->label; - new->extra->num_labels = num_labels; + labels.num_labels = num_labels; + labels.label[0] = bgp_static->label; + new->extra->labels = bgp_labels_intern(&labels); } #ifdef ENABLE_BGP_VNC label = decode_label(&bgp_static->label); @@ -10081,7 +10097,7 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p, } if (bgp_path_info_has_valid_label(path)) { - label = decode_label(&path->extra->label[0]); + label = decode_label(&path->extra->labels->label[0]); if (json) { json_object_int_add(json_out, "notag", label); json_object_array_add(json, json_out); @@ -10514,8 +10530,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, } if (bgp_path_info_num_labels(path)) { - bgp_evpn_label2str(path->extra->label, path->extra->num_labels, - vni_buf, sizeof(vni_buf)); + bgp_evpn_label2str(path->extra->labels->label, + path->extra->labels->num_labels, vni_buf, + sizeof(vni_buf)); } if (safi == SAFI_EVPN) { @@ -11281,8 +11298,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, /* Remote Label */ if (bgp_path_info_has_valid_label(path) && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) { - mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp, - &bos); + mpls_lse_decode(path->extra->labels->label[0], &label, &ttl, + &exp, &bos); if (json_paths) json_object_int_add(json_path, "remoteLabel", label); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index a1c00dcb162d..89449ac5b96e 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -69,11 +69,6 @@ enum bgp_show_adj_route_type { #define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n" #define BGP_SHOW_HEADER_WIDE " Network Next Hop Metric LocPrf Weight Path\n" -/* Maximum number of labels we can process or send with a prefix. We - * really do only 1 for MPLS (BGP-LU) but we can do 2 for EVPN-VxLAN. - */ -#define BGP_MAX_LABELS 2 - /* Maximum number of sids we can process or send with a prefix. */ #define BGP_MAX_SIDS 6 @@ -237,8 +232,7 @@ struct bgp_path_info_extra { uint32_t igpmetric; /* MPLS label(s) - VNI(s) for EVPN-VxLAN */ - mpls_label_t label[BGP_MAX_LABELS]; - uint8_t num_labels; + struct bgp_labels *labels; /* timestamp of the rib installation */ time_t bgp_rib_uptime; diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 8dbe705aa53c..9b0ca72e4c21 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1084,7 +1084,7 @@ route_match_vni(void *rule, const struct prefix *prefix, void *object) for (label_cnt = 0; label_cnt < BGP_MAX_LABELS && label_cnt < bgp_path_info_num_labels(path); label_cnt++) { - if (vni == label2vni(&path->extra->label[label_cnt])) + if (vni == label2vni(&path->extra->labels->label[label_cnt])) return RMAP_MATCH; } diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index ccac7545490d..a487f49e64a4 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -29,6 +29,7 @@ #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" #include "bgp_advertise.h" +#include "bgp_label.h" #include "bgpd/bgp_debug.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_aspath.h" @@ -664,7 +665,7 @@ static void revalidate_bgp_node(struct bgp_dest *bgp_dest, afi_t afi, bgp_dest_get_bgp_path_info(bgp_dest); num_labels = bgp_path_info_num_labels(path); - label = num_labels ? path->extra->label : NULL; + label = num_labels ? path->extra->labels->label : NULL; (void)bgp_update(ain->peer, bgp_dest_get_prefix(bgp_dest), ain->addpath_rx_id, ain->attr, afi, safi, diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index be3e27afcb1a..6e30d4f8464a 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -816,8 +816,10 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp) num_labels = 1; } else { num_labels = bgp_path_info_num_labels(path); - label_pnt = num_labels ? &path->extra->label[0] - : NULL; + label_pnt = + num_labels + ? &path->extra->labels->label[0] + : NULL; } if (stream_empty(snlri)) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 3558ebfd2d39..8fab0d1c055d 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1343,7 +1343,8 @@ static void bgp_zebra_announce_parse_nexthop( zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d", __func__, p, bgp_is_valid_label( - &mpinfo->extra->label[0])); + &mpinfo->extra->labels + ->label[0])); } else { zlog_debug("%s: p=%pFX, no label", __func__, p); } @@ -1412,7 +1413,7 @@ static void bgp_zebra_announce_parse_nexthop( *allow_recursion = true; num_labels = bgp_path_info_num_labels(mpinfo); - labels = num_labels ? mpinfo->extra->label : NULL; + labels = num_labels ? mpinfo->extra->labels->label : NULL; if (num_labels && (is_evpn || bgp_is_valid_label(&labels[0]))) { enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE; diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index bea9bfb618fb..23e3eb482308 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -549,6 +549,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ int flags) { afi_t afi; /* of the VN address */ + struct bgp_labels bgp_labels = {}; struct bgp_path_info *new; struct bgp_path_info *bpi; struct bgp_dest *bn; @@ -1021,8 +1022,9 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ sizeof(struct bgp_path_info_extra_vnc)); new->extra->vnc->vnc.export.rfapi_handle = (void *)rfd; - encode_label(label_val, &new->extra->label[0]); - new->extra->num_labels = 1; + encode_label(label_val, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; + new->extra->labels = bgp_labels_intern(&bgp_labels); /* debug */ @@ -1045,7 +1047,6 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ bgp, prd, table, p, new); bgp_dest_unlock_node(pdest); encode_label(label_val, &bn->local_label); - new->extra->num_labels = 1; } bgp_dest_unlock_node(bn); diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c index 7e19fb8c979b..2afcb2f45c8c 100644 --- a/bgpd/rfapi/rfapi_import.c +++ b/bgpd/rfapi/rfapi_import.c @@ -442,6 +442,7 @@ static struct bgp_path_info *rfapiBgpInfoCreate(struct attr *attr, uint32_t *label) { struct bgp_path_info *new; + struct bgp_labels bgp_labels = {}; new = info_make(type, sub_type, 0, peer, attr, NULL); @@ -455,10 +456,10 @@ static struct bgp_path_info *rfapiBgpInfoCreate(struct attr *attr, new->extra->vnc->vnc.import.create_time = monotime(NULL); } if (label && *label != MPLS_INVALID_LABEL) { - encode_label(*label, &new->extra->label[0]); - new->extra->num_labels = 1; - } else - new->extra->num_labels = 0; + encode_label(*label, &bgp_labels.label[0]); + bgp_labels.num_labels = 1; + new->extra->labels = bgp_labels_intern(&bgp_labels); + } peer_lock(peer); @@ -1272,7 +1273,7 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix, /* label comes from MP_REACH_NLRI label */ vo->v.l2addr.label = bgp_path_info_num_labels(bpi) - ? decode_label(&bpi->extra->label[0]) + ? decode_label(&bpi->extra->labels->label[0]) : MPLS_INVALID_LABEL; new->vn_options = vo; @@ -4168,7 +4169,8 @@ static void rfapiBgpTableFilteredImport(struct bgp *bgp, if (bgp_path_info_num_labels(bpi)) label = decode_label( - &bpi->extra->label[0]); + &bpi->extra->labels + ->label[0]); (*rfapiBgpInfoFilteredImportFunction( safi))( it, /* which import table */ diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c index 5c6357672059..a0bdf4961f23 100644 --- a/bgpd/rfapi/rfapi_rib.c +++ b/bgpd/rfapi/rfapi_rib.c @@ -693,7 +693,7 @@ static void rfapiRibBi2Ri(struct bgp_path_info *bpi, struct rfapi_info *ri, /* label comes from MP_REACH_NLRI label */ vo->v.l2addr.label = bgp_path_info_num_labels(bpi) - ? decode_label(&bpi->extra->label[0]) + ? decode_label(&bpi->extra->labels->label[0]) : MPLS_INVALID_LABEL; rfapi_vn_options_free( diff --git a/bgpd/rfapi/rfapi_vty.c b/bgpd/rfapi/rfapi_vty.c index ddf95b63fc71..9bfb6c4b45e6 100644 --- a/bgpd/rfapi/rfapi_vty.c +++ b/bgpd/rfapi/rfapi_vty.c @@ -414,11 +414,11 @@ void rfapi_vty_out_vncinfo(struct vty *vty, const struct prefix *p, } if (bgp_path_info_num_labels(bpi)) { - if (bpi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) + if (bpi->extra->labels->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK) vty_out(vty, " label=VRF2VRF"); else vty_out(vty, " label=%u", - decode_label(&bpi->extra->label[0])); + decode_label(&bpi->extra->labels->label[0])); } if (bpi->attr->srv6_l3vpn || bpi->attr->srv6_vpn) { @@ -1053,7 +1053,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, inet_ntop(pfx_vn.family, &pfx_vn.u.prefix, buf_ntop, sizeof(buf_ntop))); if (bgp_path_info_num_labels(bpi)) { - uint32_t l = decode_label(&bpi->extra->label[0]); + uint32_t l = decode_label(&bpi->extra->labels->label[0]); snprintf(buf_vn, sizeof(buf_vn), "Label: %d", l); } else /* should never happen */ { @@ -1162,7 +1162,7 @@ static int rfapiPrintRemoteRegBi(struct bgp *bgp, void *stream, } } if (tun_type != BGP_ENCAP_TYPE_MPLS && bgp_path_info_num_labels(bpi)) { - uint32_t l = decode_label(&bpi->extra->label[0]); + uint32_t l = decode_label(&bpi->extra->labels->label[0]); if (!MPLS_LABEL_IS_NULL(l)) { fp(out, " Label: %d", l); diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c index 255e87b0965b..2bb7c1b161f5 100644 --- a/bgpd/rfapi/vnc_import_bgp.c +++ b/bgpd/rfapi/vnc_import_bgp.c @@ -471,7 +471,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_bi( ecommunity_merge(new_ecom, bgp_attr_get_ecommunity(bpi->attr)); if (bgp_path_info_num_labels(bpi)) - label = decode_label(&bpi->extra->label[0]); + label = decode_label(&bpi->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -1706,7 +1706,8 @@ static void vnc_import_bgp_exterior_add_route_it( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -1879,7 +1880,8 @@ void vnc_import_bgp_exterior_del_route( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -2030,7 +2032,7 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -2147,7 +2149,8 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi)) label = decode_label( - &bpi->extra->label[0]); + &bpi->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -2173,7 +2176,8 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels + ->label[0]); else label = MPLS_INVALID_LABEL; @@ -2295,7 +2299,7 @@ void vnc_import_bgp_exterior_add_route_interior( if (bgp_path_info_num_labels(bpi_interior)) label = decode_label( - &bpi_interior->extra->label[0]); + &bpi_interior->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -2406,7 +2410,8 @@ void vnc_import_bgp_exterior_del_route_interior( prd = NULL; if (bgp_path_info_num_labels(bpi_interior)) - label = decode_label(&bpi_interior->extra->label[0]); + label = decode_label( + &bpi_interior->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; @@ -2488,7 +2493,7 @@ void vnc_import_bgp_exterior_del_route_interior( if (bgp_path_info_num_labels(bpi)) label = decode_label( - &bpi->extra->label[0]); + &bpi->extra->labels->label[0]); else label = MPLS_INVALID_LABEL; From b80499339406dbfed0ffee32e1fb2d6505c23679 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 26 Feb 2024 16:55:11 +0100 Subject: [PATCH 210/472] bgpd: get rid of has_valid_label in bgp_update() Get rid of has_valid_label in bgp_update() to prepare the next commits. Signed-off-by: Louis Scalbert --- bgpd/bgp_route.c | 47 +++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 919c219c6ce9..eada9264ac29 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4551,12 +4551,12 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, char pfx_buf[BGP_PRD_PATH_STRLEN]; int connected = 0; int do_loop_check = 1; - int has_valid_label = 0; afi_t nh_afi; bool force_evpn_import = false; safi_t orig_safi = safi; int allowas_in = 0; struct bgp_labels bgp_labels = {}; + uint8_t i; if (frrtrace_enabled(frr_bgp, process_update)) { char pfxprint[PREFIX2STR_BUFFER]; @@ -4578,15 +4578,12 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp = peer->bgp; dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd); - /* TODO: Check to see if we can get rid of "is_valid_label" */ - if (afi == AFI_L2VPN && safi == SAFI_EVPN) - has_valid_label = (num_labels > 0) ? 1 : 0; - else - has_valid_label = bgp_is_valid_label(label); - - if (has_valid_label) - assert(label != NULL); + if ((afi == AFI_L2VPN && safi == SAFI_EVPN) || + bgp_is_valid_label(&label[0])) + bgp_labels.num_labels = num_labels; + for (i = 0; i < bgp_labels.num_labels; i++) + bgp_labels.label[i] = label[i]; /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ @@ -4880,8 +4877,9 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Same attribute comes in. */ if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) && same_attr && - (!has_valid_label || - bgp_path_info_labels_same(pi, label, num_labels))) { + (!bgp_labels.num_labels || + bgp_path_info_labels_same(pi, bgp_labels.label, + bgp_labels.num_labels))) { if (get_active_bdc_from_pi(pi, afi, safi) && peer->sort == BGP_PEER_EBGP && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { @@ -5063,19 +5061,11 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, pi->attr = attr_new; /* Update MPLS label */ - if (has_valid_label) { + if (!bgp_path_info_labels_same(pi, &bgp_labels.label[0], + bgp_labels.num_labels)) { bgp_path_info_extra_get(pi); - bgp_labels.label[0] = *label; - bgp_labels.num_labels = num_labels; - if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) - bgp_set_valid_label(&bgp_labels.label[0]); - - if (!bgp_path_info_labels_same(pi, &bgp_labels.label[0], - bgp_labels.num_labels)) { - bgp_labels_unintern(&pi->extra->labels); - pi->extra->labels = - bgp_labels_intern(&bgp_labels); - } + bgp_labels_unintern(&pi->extra->labels); + pi->extra->labels = bgp_labels_intern(&bgp_labels); } #ifdef ENABLE_BGP_VNC @@ -5266,15 +5256,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, new = info_make(type, sub_type, 0, peer, attr_new, dest); /* Update MPLS label */ - if (has_valid_label) { - bgp_path_info_extra_get(new); - bgp_labels.label[0] = *label; - bgp_labels.num_labels = num_labels; - if (!(afi == AFI_L2VPN && safi == SAFI_EVPN)) - bgp_set_valid_label(&bgp_labels.label[0]); - - new->extra->labels = bgp_labels_intern(&bgp_labels); - } + bgp_path_info_extra_get(new); + new->extra->labels = bgp_labels_intern(&bgp_labels); /* Nexthop reachability check. */ if (((afi == AFI_IP || afi == AFI_IP6) && From 9fd26c1aa5348bc1d73b92feab2f4e96196c00e3 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 13 Jan 2023 15:59:52 +0100 Subject: [PATCH 211/472] bgpd: fix labels in adj-rib-in In a BGP L3VPN context using ADJ-RIB-IN (ie. enabled with 'soft-reconfiguration inbound'), after applying a deny route-map and removing it, the remote MPLS label information is lost. As a result, BGP is unable to re-install the related routes in the RIB. For example, > router bgp 65500 > [..] > neighbor 192.0.2.2 remote-as 65501 > address-family ipv4 vpn > neighbor 192.0.2.2 activate > neighbor 192.0.2.2 soft-reconfiguration inbound The 192.168.0.0/24 prefix has a remote label value of 102 in the BGP RIB. > # show bgp ipv4 vpn 192.168.0.0/24 > BGP routing table entry for 444:1:192.168.0.0/24, version 2 > [..] > 192.168.0.0 from 192.0.2.2 > Origin incomplete, metric 0, valid, external, best (First path received) > Extended Community: RT:52:100 > Remote label: 102 A route-map now filter all incoming BGP updates: > route-map rmap deny 1 > router bgp 65500 > address-family ipv4 vpn > neighbor 192.0.2.2 route-map rmap in The prefix is now filtered: > # show bgp ipv4 vpn 192.168.0.0/24 > # The route-map is detached: > router bgp 65500 > address-family ipv4 vpn > no neighbor 192.168.0.1 route-map rmap in The BGP RIB entry is present but the remote label is lost: > # show bgp ipv4 vpn 192.168.0.0/24 > BGP routing table entry for 444:1:192.168.0.0/24, version 2 > [..] > 192.168.0.0 from 192.0.2.2 > Origin incomplete, metric 0, valid, external, best (First path received) > Extended Community: RT:52:100 The reason for the loose is that labels are stored within struct attr -> struct extra -> struct bgp_labels but not in the struct bgp_adj_in. Reference the bgp_labels pointer in struct bgp_adj_in and use its values when doing a soft reconfiguration of the BGP table. Signed-off-by: Philippe Guibert Signed-off-by: Louis Scalbert --- bgpd/bgp_advertise.c | 8 +++++++- bgpd/bgp_advertise.h | 6 +++++- bgpd/bgp_route.c | 6 +++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_advertise.c b/bgpd/bgp_advertise.c index d519749f6bca..d5c7e1887b60 100644 --- a/bgpd/bgp_advertise.c +++ b/bgpd/bgp_advertise.c @@ -163,7 +163,7 @@ bool bgp_adj_out_lookup(struct peer *peer, struct bgp_dest *dest, void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr, - uint32_t addpath_id) + uint32_t addpath_id, struct bgp_labels *labels) { struct bgp_adj_in *adj; @@ -173,6 +173,10 @@ void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr, bgp_attr_unintern(&adj->attr); adj->attr = bgp_attr_intern(attr); } + if (!bgp_labels_cmp(adj->labels, labels)) { + bgp_labels_unintern(&adj->labels); + adj->labels = bgp_labels_intern(labels); + } return; } } @@ -181,6 +185,7 @@ void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr, adj->attr = bgp_attr_intern(attr); adj->uptime = monotime(NULL); adj->addpath_rx_id = addpath_id; + adj->labels = bgp_labels_intern(labels); BGP_ADJ_IN_ADD(dest, adj); peer->stat_pfx_adj_rib_in++; bgp_dest_lock_node(dest); @@ -189,6 +194,7 @@ void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, struct attr *attr, void bgp_adj_in_remove(struct bgp_dest **dest, struct bgp_adj_in *bai) { bgp_attr_unintern(&bai->attr); + bgp_labels_unintern(&bai->labels); if (bai->peer) bai->peer->stat_pfx_adj_rib_in--; BGP_ADJ_IN_DEL(*dest, bai); diff --git a/bgpd/bgp_advertise.h b/bgpd/bgp_advertise.h index 49821061b1b8..e3cd743d43d2 100644 --- a/bgpd/bgp_advertise.h +++ b/bgpd/bgp_advertise.h @@ -95,6 +95,9 @@ struct bgp_adj_in { /* Received attribute. */ struct attr *attr; + /* VPN label information */ + struct bgp_labels *labels; + /* timestamp (monotime) */ time_t uptime; @@ -135,7 +138,8 @@ struct bgp_synchronize { extern bool bgp_adj_out_lookup(struct peer *peer, struct bgp_dest *dest, uint32_t addpath_tx_id); extern void bgp_adj_in_set(struct bgp_dest *dest, struct peer *peer, - struct attr *attr, uint32_t addpath_id); + struct attr *attr, uint32_t addpath_id, + struct bgp_labels *labels); extern bool bgp_adj_in_unset(struct bgp_dest **dest, struct peer *peer, uint32_t addpath_id); extern void bgp_adj_in_remove(struct bgp_dest **dest, struct bgp_adj_in *bai); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index eada9264ac29..94c21e186150 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4600,7 +4600,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, memcpy(&attr->evpn_overlay, evpn, sizeof(struct bgp_route_evpn)); } - bgp_adj_in_set(dest, peer, attr, addpath_id); + bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels); } /* Update permitted loop count */ @@ -5673,8 +5673,8 @@ static void bgp_soft_reconfig_table_update(struct peer *peer, if (pi->peer == peer) break; - num_labels = bgp_path_info_num_labels(pi); - label_pnt = num_labels ? &pi->extra->labels->label[0] : NULL; + num_labels = ain->labels ? ain->labels->num_labels : 0; + label_pnt = num_labels ? &ain->labels->label[0] : NULL; if (pi) memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr), sizeof(evpn)); From 2b6bcda64bdf58f6c6dc1690880edb473af2ec66 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 23 Feb 2023 15:38:11 +0100 Subject: [PATCH 212/472] bgpd: fix label in adj-rib-out After modifying the "label vpn export value", the vpn label information of the VRF is not updated to the peers. For example, the 192.168.0.0/24 prefix is announced to the peer with a label value of 222. > router bgp 65500 > [..] > neighbor 192.0.2.2 remote-as 65501 > address-family ipv4-vpn > neighbor 192.0.2.2 activate > exit-address-family > exit > router bgp 65500 vrf vrf2 > address-family ipv4 unicast > network 192.168.0.0/24 > label vpn export 222 > rd vpn export 444:444 > rt vpn both 53:100 > export vpn > import vpn > exit-address-family Changing the label with "label vpn export" does not update the label value to the peer unless the BGP sessions is re-established. No labels are stored are stored struct bgp_adj_out so that it is impossible to compare the current value with the previous value in adj-RIB-out. Reference the bgp_labels pointer in struct bgp_adj_out and compare the values when updating adj-RIB-out. Signed-off-by: Philippe Guibert Signed-off-by: Louis Scalbert --- bgpd/bgp_advertise.h | 3 +++ bgpd/bgp_updgrp_adv.c | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_advertise.h b/bgpd/bgp_advertise.h index e3cd743d43d2..8c831892b33d 100644 --- a/bgpd/bgp_advertise.h +++ b/bgpd/bgp_advertise.h @@ -75,6 +75,9 @@ struct bgp_adj_out { /* Advertised attribute. */ struct attr *attr; + /* VPN label information */ + struct bgp_labels *labels; + /* Advertisement information. */ struct bgp_advertise *adv; }; diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 0a852c75de77..250378af6845 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -78,6 +78,8 @@ static inline struct bgp_adj_out *adj_lookup(struct bgp_dest *dest, static void adj_free(struct bgp_adj_out *adj) { + bgp_labels_unintern(&adj->labels); + TAILQ_REMOVE(&(adj->subgroup->adjq), adj, subgrp_adj_train); SUBGRP_DECR_STAT(adj->subgroup, adj_count); @@ -572,7 +574,9 @@ bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, attr_hash = attrhash_key_make(attr); if (!CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES) && - attr_hash && adj->attr_hash == attr_hash) { + attr_hash && adj->attr_hash == attr_hash && + bgp_labels_cmp(path->extra ? path->extra->labels : NULL, + adj->labels)) { if (BGP_DEBUG(update, UPDATE_OUT)) { char attr_str[BUFSIZ] = {0}; @@ -614,6 +618,10 @@ bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, adv->baa = bgp_advertise_attr_intern(subgrp->hash, attr); adv->adj = adj; adj->attr_hash = attr_hash; + if (path->extra) + adj->labels = bgp_labels_intern(path->extra->labels); + else + adj->labels = NULL; /* Add new advertisement to advertisement attribute list. */ bgp_advertise_add(adv->baa, adv); From 2b7e357cf902190aad544b4f7d46e9f229454346 Mon Sep 17 00:00:00 2001 From: Dave LeRoy Date: Wed, 5 Jun 2024 10:22:57 -0700 Subject: [PATCH 213/472] nhrpd: cleans up shortcut cache entries on termination nhrp_shortcut_terminate() previously was just freeing the associated AFI shortcut RIBs and not addressing existing shortcut cache entries. This cause a use after free issue in vrf_terminate() later in the terminate sequence NHRP: Received signal 7 at 1717516286 (si_addr 0x1955d, PC 0x7098786912c0); aborting... NHRP: zlog_signal+0xf5 709878ad1255 7fff3d992eb0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: core_handler+0xb5 709878b0db85 7fff3d992ff0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: __sigaction+0x50 709878642520 7fff3d993140 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000) NHRP: ---- signal ---- NHRP: __lll_lock_wait_private+0x90 7098786912c0 7fff3d9936d8 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000) NHRP: pthread_mutex_lock+0x112 709878698002 7fff3d9936e0 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000) NHRP: _event_add_read_write+0x63 709878b1f423 7fff3d993700 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: zclient_send_message+0xd4 709878b37614 7fff3d993770 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: nhrp_route_announce+0x1ad 5ab34d63d39d 7fff3d993790 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) NHRP: nhrp_shortcut_cache_notify+0xd8 5ab34d63e758 7fff3d99d4e0 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) NHRP: nhrp_cache_free+0x165 5ab34d632f25 7fff3d99d510 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) NHRP: hash_iterate+0x4d 709878ab949d 7fff3d99d540 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: nhrp_cache_interface_del+0x37 5ab34d633eb7 7fff3d99d580 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) NHRP: nhrp_if_delete_hook+0x26 5ab34d6350d6 7fff3d99d5a0 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) NHRP: if_delete_retain+0x3d 709878abcd1d 7fff3d99d5c0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: if_delete+0x4c 709878abd87c 7fff3d99d600 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: if_terminate+0x53 709878abda83 7fff3d99d630 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: vrf_terminate_single+0x24 709878b23c74 7fff3d99d670 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: nhrp_request_stop+0x34 5ab34d636844 7fff3d99d690 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) NHRP: frr_sigevent_process+0x53 709878b0df53 7fff3d99d6a0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: event_fetch+0x6c5 709878b20405 7fff3d99d6c0 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: frr_run+0xd3 709878ac8163 7fff3d99d840 /usr/lib/frr/libfrr.so.0 (mapped at 0x709878a00000) NHRP: main+0x195 5ab34d631915 7fff3d99d960 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) NHRP: __libc_init_first+0x90 709878629d90 7fff3d99d980 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000) NHRP: __libc_start_main+0x80 709878629e40 7fff3d99da20 /lib/x86_64-linux-gnu/libc.so.6 (mapped at 0x709878600000) NHRP: _start+0x25 5ab34d631b65 7fff3d99da70 /usr/lib/frr/nhrpd (mapped at 0x5ab34d621000) Signed-off-by: Dave LeRoy --- nhrpd/nhrp_main.c | 4 ++-- nhrpd/nhrp_shortcut.c | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index 5d492249d32c..adb8be36d303 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -83,13 +83,13 @@ static void nhrp_request_stop(void) debugf(NHRP_DEBUG_COMMON, "Exiting..."); frr_early_fini(); - vrf_terminate(); + nhrp_shortcut_terminate(); nhrp_nhs_terminate(); nhrp_zebra_terminate(); vici_terminate(); evmgr_terminate(); + vrf_terminate(); nhrp_vc_terminate(); - nhrp_shortcut_terminate(); debugf(NHRP_DEBUG_COMMON, "Done."); diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index 04dad2aea627..e83ce7f58f47 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -19,7 +19,8 @@ DEFINE_MTYPE_STATIC(NHRPD, NHRP_SHORTCUT, "NHRP shortcut"); static struct route_table *shortcut_rib[AFI_MAX]; static void nhrp_shortcut_do_purge(struct event *t); -static void nhrp_shortcut_delete(struct nhrp_shortcut *s); +static void nhrp_shortcut_delete(struct nhrp_shortcut *s, + void *arg __attribute__((__unused__))); static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s); static void nhrp_shortcut_check_use(struct nhrp_shortcut *s) @@ -72,7 +73,7 @@ static void nhrp_shortcut_cache_notify(struct notifier_block *n, s->route_installed = 0; } if (cmd == NOTIFY_CACHE_DELETE) - nhrp_shortcut_delete(s); + nhrp_shortcut_delete(s, NULL); break; } } @@ -132,7 +133,8 @@ static void nhrp_shortcut_update_binding(struct nhrp_shortcut *s, } } -static void nhrp_shortcut_delete(struct nhrp_shortcut *s) +static void nhrp_shortcut_delete(struct nhrp_shortcut *s, + void *arg __attribute__((__unused__))) { struct route_node *rn; afi_t afi = family2afi(PREFIX_FAMILY(s->p)); @@ -158,7 +160,7 @@ static void nhrp_shortcut_do_purge(struct event *t) { struct nhrp_shortcut *s = EVENT_ARG(t); s->t_timer = NULL; - nhrp_shortcut_delete(s); + nhrp_shortcut_delete(s, NULL); } static struct nhrp_shortcut *nhrp_shortcut_get(struct prefix *p) @@ -469,6 +471,8 @@ void nhrp_shortcut_init(void) void nhrp_shortcut_terminate(void) { + nhrp_shortcut_foreach(AFI_IP, nhrp_shortcut_delete, NULL); + nhrp_shortcut_foreach(AFI_IP6, nhrp_shortcut_delete, NULL); route_table_finish(shortcut_rib[AFI_IP]); route_table_finish(shortcut_rib[AFI_IP6]); } From 28d2e126c7fea07de22e52201a70fbf0c94b5dc6 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Wed, 5 Jun 2024 14:37:41 -0400 Subject: [PATCH 214/472] zebra: fix incoming FPM message length validation Validate incoming message length against correct (struct rtmsg) len, not top-level netlink message header size. Signed-off-by: Mark Stapp --- zebra/dplane_fpm_nl.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 245b799a91d4..9ad92d6269dd 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -654,14 +654,6 @@ static void fpm_read(struct event *t) hdr_available_bytes = fpm.msg_len - FPM_MSG_HDR_LEN; available_bytes -= hdr_available_bytes; - /* Sanity check: must be at least header size. */ - if (hdr->nlmsg_len < sizeof(*hdr)) { - zlog_warn( - "%s: [seq=%u] invalid message length %u (< %zu)", - __func__, hdr->nlmsg_seq, hdr->nlmsg_len, - sizeof(*hdr)); - continue; - } if (hdr->nlmsg_len > fpm.msg_len) { zlog_warn( "%s: Received a inner header length of %u that is greater than the fpm total length of %u", @@ -691,6 +683,14 @@ static void fpm_read(struct event *t) switch (hdr->nlmsg_type) { case RTM_NEWROUTE: + /* Sanity check: need at least route msg header size. */ + if (hdr->nlmsg_len < sizeof(struct rtmsg)) { + zlog_warn("%s: [seq=%u] invalid message length %u (< %zu)", + __func__, hdr->nlmsg_seq, + hdr->nlmsg_len, sizeof(struct rtmsg)); + break; + } + ctx = dplane_ctx_alloc(); dplane_ctx_route_init(ctx, DPLANE_OP_ROUTE_NOTIFY, NULL, NULL); From a4650000353365521c09e3d0c466c69d5771b3ab Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Thu, 6 Jun 2024 08:50:05 +0000 Subject: [PATCH 215/472] tests: munet: update to version 0.14.9 Topotest relevant changes: - add support for `timeout` arg to `cmd_*()` - handle invalid regexp in CLI commands - fix long interface name support Full munet changelog: munet: 0.14.9: add support for `timeout` arg to `cmd_*()` munet: 0.14.8: cleanup the cleanup (kill) on launch options munet: 0.14.7: allow multiple extra commands for shell console init munet: 0.14.6: - qemu: gather gcda files where munet can find them - handle invalid regexp in CLI commands munet: 0.14.5: - (podman) pull missing images for containers - fix long interface name support - add another router example munet: 0.14.4: mutest: add color to PASS/FAIL indicators on tty consoles munet: 0.14.3: Add hostnet node that runs it's commands in the host network namespace. munet: 0.14.2: - always fail mutest tests on bad json inputs - improve ssh-remote for common use-case of connecting to host connected devices - fix ready-cmd for python v3.11+ munet: 0.14.1: Improved host interface support. Signed-off-by: Christian Hopps --- tests/topotests/munet/__main__.py | 24 ++- tests/topotests/munet/base.py | 60 ++++-- tests/topotests/munet/cleanup.py | 34 ++-- tests/topotests/munet/cli.py | 12 +- tests/topotests/munet/logconf-mutest.yaml | 5 +- tests/topotests/munet/mucmd.py | 4 +- tests/topotests/munet/mulog.py | 26 +++ tests/topotests/munet/munet-schema.json | 9 + tests/topotests/munet/mutest/__main__.py | 15 +- tests/topotests/munet/mutest/userapi.py | 8 +- tests/topotests/munet/native.py | 216 +++++++++++++++------- tests/topotests/munet/testing/fixtures.py | 24 ++- tests/topotests/munet/watchlog.py | 1 - 13 files changed, 322 insertions(+), 116 deletions(-) diff --git a/tests/topotests/munet/__main__.py b/tests/topotests/munet/__main__.py index e50fea691597..145eb265ab77 100644 --- a/tests/topotests/munet/__main__.py +++ b/tests/topotests/munet/__main__.py @@ -19,6 +19,7 @@ from .args import add_launch_args from .base import get_event_loop from .cleanup import cleanup_previous +from .cleanup import is_running_in_rundir from .compat import PytestConfig @@ -139,10 +140,11 @@ def main(*args): eap = ap.add_argument_group(title="Uncommon", description="uncommonly used options") eap.add_argument("--log-config", help="logging config file (yaml, toml, json, ...)") eap.add_argument( - "--no-kill", + "--kill", action="store_true", - help="Do not kill previous running processes", + help="Kill previous running processes using same rundir and exit", ) + eap.add_argument("--no-kill", action="store_true", help=argparse.SUPPRESS) eap.add_argument( "--no-cli", action="store_true", help="Do not run the interactive CLI" ) @@ -157,7 +159,18 @@ def main(*args): sys.exit(0) rundir = args.rundir if args.rundir else "/tmp/munet" + rundir = os.path.abspath(rundir) args.rundir = rundir + + if args.kill: + logging.info("Killing any previous run using rundir: {rundir}") + cleanup_previous(args.rundir) + elif is_running_in_rundir(args.rundir): + logging.fatal( + "Munet processes using rundir: %s, use `--kill` to cleanup first", rundir + ) + return 1 + if args.cleanup: if os.path.exists(rundir): if not os.path.exists(f"{rundir}/config.json"): @@ -169,6 +182,10 @@ def main(*args): sys.exit(1) else: subprocess.run(["/usr/bin/rm", "-rf", rundir], check=True) + + if args.kill: + return 0 + subprocess.run(f"mkdir -p {rundir} && chmod 755 {rundir}", check=True, shell=True) os.environ["MUNET_RUNDIR"] = rundir @@ -183,9 +200,6 @@ def main(*args): logger.critical("No nodes defined in config file") return 1 - if not args.no_kill: - cleanup_previous() - loop = None status = 4 try: diff --git a/tests/topotests/munet/base.py b/tests/topotests/munet/base.py index a4811f179c7d..e77eb15dc844 100644 --- a/tests/topotests/munet/base.py +++ b/tests/topotests/munet/base.py @@ -469,6 +469,8 @@ def _get_sub_args(self, cmd_list, defaults, use_pty=False, ns_only=False, **kwar env = {**(kwargs["env"] if "env" in kwargs else os.environ)} if "MUNET_NODENAME" not in env: env["MUNET_NODENAME"] = self.name + if "MUNET_PID" not in env and "MUNET_PID" in os.environ: + env["MUNET_PID"] = os.environ["MUNET_PID"] kwargs["env"] = env defaults.update(kwargs) @@ -780,8 +782,14 @@ async def shell_spawn( ps1 = re.escape(ps1) ps2 = re.escape(ps2) - - extra = "PAGER=cat; export PAGER; TERM=dumb; unset HISTFILE; set +o emacs +o vi" + extra = [ + "TERM=dumb", + "set +o emacs", + "set +o vi", + "unset HISTFILE", + "PAGER=cat", + "export PAGER", + ] pchg = "PS1='{0}' PS2='{1}' PROMPT_COMMAND=''\n".format(ps1p, ps2p) p.send(pchg) return ShellWrapper(p, ps1, ps2, extra_init_cmd=extra, will_echo=will_echo) @@ -934,15 +942,25 @@ def _cmd_status_finish(self, p, c, ac, o, e, raises, warn): def _cmd_status(self, cmds, raises=False, warn=True, stdin=None, **kwargs): """Execute a command.""" + timeout = None + if "timeout" in kwargs: + timeout = kwargs["timeout"] + del kwargs["timeout"] + pinput, stdin = Commander._cmd_status_input(stdin) p, actual_cmd = self._popen("cmd_status", cmds, stdin=stdin, **kwargs) - o, e = p.communicate(pinput) + o, e = p.communicate(pinput, timeout=timeout) return self._cmd_status_finish(p, cmds, actual_cmd, o, e, raises, warn) async def _async_cmd_status( self, cmds, raises=False, warn=True, stdin=None, text=None, **kwargs ): """Execute a command.""" + timeout = None + if "timeout" in kwargs: + timeout = kwargs["timeout"] + del kwargs["timeout"] + pinput, stdin = Commander._cmd_status_input(stdin) p, actual_cmd = await self._async_popen( "async_cmd_status", cmds, stdin=stdin, **kwargs @@ -955,7 +973,12 @@ async def _async_cmd_status( if encoding is not None and isinstance(pinput, str): pinput = pinput.encode(encoding) - o, e = await p.communicate(pinput) + try: + o, e = await asyncio.wait_for(p.communicate(), timeout=timeout) + except (TimeoutError, asyncio.TimeoutError) as error: + raise subprocess.TimeoutExpired( + cmd=actual_cmd, timeout=timeout, output=None, stderr=None + ) from error if encoding is not None: o = o.decode(encoding) if o is not None else o e = e.decode(encoding) if e is not None else e @@ -1220,7 +1243,13 @@ def run_in_window( if self.is_vm and self.use_ssh and not ns_only: # pylint: disable=E1101 if isinstance(cmd, str): cmd = shlex.split(cmd) - cmd = ["/usr/bin/env", f"MUNET_NODENAME={self.name}"] + cmd + cmd = [ + "/usr/bin/env", + f"MUNET_NODENAME={self.name}", + ] + if "MUNET_PID" in os.environ: + cmd.append(f"MUNET_PID={os.environ.get('MUNET_PID')}") + cmd += cmd # get the ssh cmd cmd = self._get_pre_cmd(False, True, ns_only=ns_only) + [shlex.join(cmd)] @@ -1240,6 +1269,8 @@ def run_in_window( envvars = f"MUNET_NODENAME={self.name} NODENAME={self.name}" if hasattr(self, "rundir"): envvars += f" RUNDIR={self.rundir}" + if "MUNET_PID" in os.environ: + envvars += f" MUNET_PID={os.environ.get('MUNET_PID')}" if hasattr(self.unet, "config_dirname") and self.unet.config_dirname: envvars += f" CONFIGDIR={self.unet.config_dirname}" elif "CONFIGDIR" in os.environ: @@ -2520,7 +2551,7 @@ def __init__(self, name=None, mtu=None, unet=None, **kwargs): self.logger.debug("Bridge: Creating") - assert len(self.name) <= 16 # Make sure fits in IFNAMSIZE + # assert len(self.name) <= 16 # Make sure fits in IFNAMSIZE self.cmd_raises(f"ip link delete {name} || true") self.cmd_raises(f"ip link add {name} type bridge") if self.mtu: @@ -2644,10 +2675,6 @@ def __init__( self.cfgopt = munet_config.ConfigOptionsProxy(pytestconfig) - super().__init__( - name, mount=True, net=isolated, uts=isolated, pid=pid, unet=None, **kwargs - ) - # This allows us to cleanup any leftover running munet's if "MUNET_PID" in os.environ: if os.environ["MUNET_PID"] != str(our_pid): @@ -2658,6 +2685,10 @@ def __init__( ) os.environ["MUNET_PID"] = str(our_pid) + super().__init__( + name, mount=True, net=isolated, uts=isolated, pid=pid, unet=None, **kwargs + ) + # this is for testing purposes do not use if not BaseMunet.g_unet: BaseMunet.g_unet = self @@ -2765,7 +2796,7 @@ def add_link(self, node1, node2, if1, if2, mtu=None, **intf_constraints): self.logger.error('"%s" len %s > 16', nsif1, len(nsif1)) elif len(nsif2) > 16: self.logger.error('"%s" len %s > 16', nsif2, len(nsif2)) - assert len(nsif1) <= 16 and len(nsif2) <= 16 # Make sure fits in IFNAMSIZE + assert len(nsif1) < 16 and len(nsif2) < 16 # Make sure fits in IFNAMSIZE self.logger.debug("%s: Creating veth pair for link %s", self, lname) @@ -2993,8 +3024,11 @@ def __init__( self._expectf = self.child.expect if extra_init_cmd: - self.expect_prompt() - self.child.sendline(extra_init_cmd) + if isinstance(extra_init_cmd, str): + extra_init_cmd = [extra_init_cmd] + for ecmd in extra_init_cmd: + self.expect_prompt() + self.child.sendline(ecmd) self.expect_prompt() def expect_prompt(self, timeout=-1): diff --git a/tests/topotests/munet/cleanup.py b/tests/topotests/munet/cleanup.py index c641cda68596..12ea6e2840e6 100644 --- a/tests/topotests/munet/cleanup.py +++ b/tests/topotests/munet/cleanup.py @@ -59,25 +59,33 @@ def _get_our_pids(): return {} -def _get_other_pids(): - piddict = get_pids_with_env("MUNET_PID") - unet_pids = {d["MUNET_PID"] for d in piddict.values()} +def _get_other_pids(rundir): + if rundir: + # get only munet pids using the given rundir + piddict = get_pids_with_env("MUNET_RUNDIR", str(rundir)) + else: + # Get all munet pids + piddict = get_pids_with_env("MUNET_PID") + unet_pids = {d["MUNET_PID"] for d in piddict.values() if "MUNET_PID" in d} pids_by_upid = {p: set() for p in unet_pids} for pid, envdict in piddict.items(): + if "MUNET_PID" not in envdict: + continue unet_pid = envdict["MUNET_PID"] pids_by_upid[unet_pid].add(pid) # Filter out any child pid sets whos munet pid is still running return {x: y for x, y in pids_by_upid.items() if x not in y} -def _get_pids_by_upid(ours): +def _get_pids_by_upid(ours, rundir): if ours: + assert rundir is None return _get_our_pids() - return _get_other_pids() + return _get_other_pids(rundir) -def _cleanup_pids(ours): - pids_by_upid = _get_pids_by_upid(ours).items() +def _cleanup_pids(ours, rundir): + pids_by_upid = _get_pids_by_upid(ours, rundir).items() if not pids_by_upid: return @@ -94,7 +102,7 @@ def _cleanup_pids(ours): # return # time.sleep(1) - pids_by_upid = _get_pids_by_upid(ours).items() + pids_by_upid = _get_pids_by_upid(ours, rundir).items() _kill_piddict(pids_by_upid, signal.SIGKILL) @@ -103,12 +111,16 @@ def cleanup_current(): Currently this only scans for old processes. """ - _cleanup_pids(True) + _cleanup_pids(True, None) -def cleanup_previous(): +def cleanup_previous(rundir=None): """Attempt to cleanup preview runs. Currently this only scans for old processes. """ - _cleanup_pids(False) + _cleanup_pids(False, rundir) + + +def is_running_in_rundir(rundir): + return bool(get_pids_with_env("MUNET_RUNDIR", str(rundir))) diff --git a/tests/topotests/munet/cli.py b/tests/topotests/munet/cli.py index 133644e85e16..01a7091512c7 100644 --- a/tests/topotests/munet/cli.py +++ b/tests/topotests/munet/cli.py @@ -106,9 +106,13 @@ def is_host_regex(restr): def get_host_regex(restr): - if len(restr) < 3 or restr[0] != "/" or restr[-1] != "/": + try: + if len(restr) < 3 or restr[0] != "/" or restr[-1] != "/": + return None + return re.compile(restr[1:-1]) + except re.error: + logging.error("Invalid regex") return None - return re.compile(restr[1:-1]) def host_in(restr, names): @@ -126,8 +130,8 @@ def expand_host(restr, names): hosts = [] regexp = get_host_regex(restr) if not regexp: - assert restr in names - hosts.append(restr) + if restr in names: + hosts.append(restr) else: for name in names: if regexp.fullmatch(name): diff --git a/tests/topotests/munet/logconf-mutest.yaml b/tests/topotests/munet/logconf-mutest.yaml index b450fb938227..c0b636cd6176 100644 --- a/tests/topotests/munet/logconf-mutest.yaml +++ b/tests/topotests/munet/logconf-mutest.yaml @@ -1,5 +1,8 @@ version: 1 formatters: + result_color: + class: munet.mulog.ResultColorFormatter + format: '%(levelname)5s: %(message)s' brief: format: '%(levelname)5s: %(message)s' operfmt: @@ -22,7 +25,7 @@ handlers: info_console: level: INFO class: logging.StreamHandler - formatter: brief + formatter: result_color stream: ext://sys.stderr oper_console: level: DEBUG diff --git a/tests/topotests/munet/mucmd.py b/tests/topotests/munet/mucmd.py index d6101e1a55c7..cd356f38ad20 100644 --- a/tests/topotests/munet/mucmd.py +++ b/tests/topotests/munet/mucmd.py @@ -89,14 +89,14 @@ def main(*args): ecmd = "/usr/bin/nsenter" eargs = [ecmd] - # start mucmd same way base process is started + #start mucmd same way base process is started eargs.append(f"--mount=/proc/{pid}/ns/mnt") eargs.append(f"--net=/proc/{pid}/ns/net") eargs.append(f"--pid=/proc/{pid}/ns/pid_for_children") eargs.append(f"--uts=/proc/{pid}/ns/uts") eargs.append(f"--wd={rundir}") eargs += args.shellcmd - # print("Using ", eargs) + #print("Using ", eargs) return os.execvpe(ecmd, eargs, {**env, **envcfg}) diff --git a/tests/topotests/munet/mulog.py b/tests/topotests/munet/mulog.py index f840eae2d800..968acd9d19e6 100644 --- a/tests/topotests/munet/mulog.py +++ b/tests/topotests/munet/mulog.py @@ -12,6 +12,9 @@ from pathlib import Path +do_color = True + + class MultiFileHandler(logging.FileHandler): """A logging handler that logs to new files based on the logger name. @@ -118,5 +121,28 @@ def __init__(self, fmt=None, datefmt=None, style="%", **kwargs): super().__init__(fmt, datefmt, style, **kwargs) def format(self, record): + if not do_color: + return super().format(record) formatter = self.formatters.get(record.levelno) return formatter.format(record) + + +class ResultColorFormatter(logging.Formatter): + """A formatter that colorizes PASS/FAIL strings based on level.""" + + green = "\x1b[32m" + red = "\x1b[31m" + reset = "\x1b[0m" + + def format(self, record): + s = super().format(record) + if not do_color: + return s + idx = s.find("FAIL") + if idx >= 0 and record.levelno > logging.INFO: + s = s[:idx] + self.red + "FAIL" + self.reset + s[idx + 4 :] + elif record.levelno == logging.INFO: + idx = s.find("PASS") + if idx >= 0: + s = s[:idx] + self.green + "PASS" + self.reset + s[idx + 4 :] + return s diff --git a/tests/topotests/munet/munet-schema.json b/tests/topotests/munet/munet-schema.json index 7d577e63b3ce..6ebc368dcb21 100644 --- a/tests/topotests/munet/munet-schema.json +++ b/tests/topotests/munet/munet-schema.json @@ -93,6 +93,9 @@ "image": { "type": "string" }, + "hostnet": { + "type": "boolean" + }, "server": { "type": "string" }, @@ -383,6 +386,9 @@ }, "ipv6": { "type": "string" + }, + "external": { + "type": "boolean" } } } @@ -422,6 +428,9 @@ "image": { "type": "string" }, + "hostnet": { + "type": "boolean" + }, "server": { "type": "string" }, diff --git a/tests/topotests/munet/mutest/__main__.py b/tests/topotests/munet/mutest/__main__.py index d94e702c52cf..a78c69e26efd 100644 --- a/tests/topotests/munet/mutest/__main__.py +++ b/tests/topotests/munet/mutest/__main__.py @@ -20,6 +20,7 @@ from pathlib import Path from typing import Union +from munet import mulog from munet import parser from munet.args import add_testing_args from munet.base import Bridge @@ -380,8 +381,10 @@ async def run_tests(args): for result in results: test_name, passed, failed, e = result tnum += 1 - s = "FAIL" if failed or e else "PASS" - reslog.info(" %s %s:%s", s, tnum, test_name) + if failed or e: + reslog.warning(" FAIL %s:%s", tnum, test_name) + else: + reslog.info(" PASS %s:%s", tnum, test_name) reslog.info("-" * 70) reslog.info( @@ -447,8 +450,9 @@ def main(): sys.exit(0) rundir = args.rundir if args.rundir else "/tmp/mutest" - args.rundir = Path(rundir) - os.environ["MUNET_RUNDIR"] = rundir + rundir = Path(rundir).absolute() + args.rundir = rundir + os.environ["MUNET_RUNDIR"] = str(rundir) subprocess.run(f"mkdir -p {rundir} && chmod 755 {rundir}", check=True, shell=True) config = parser.setup_logging(args, config_base="logconf-mutest") @@ -459,6 +463,9 @@ def main(): fconfig.get("format"), fconfig.get("datefmt") ) + if not hasattr(sys.stderr, "isatty") or not sys.stderr.isatty(): + mulog.do_color = False + loop = None status = 4 try: diff --git a/tests/topotests/munet/mutest/userapi.py b/tests/topotests/munet/mutest/userapi.py index f42fbc18932b..abc63af36588 100644 --- a/tests/topotests/munet/mutest/userapi.py +++ b/tests/topotests/munet/mutest/userapi.py @@ -544,7 +544,9 @@ def _match_command_json( """ js = self._command_json(target, cmd) if js is None: - return expect_fail, {} + # Always fail on bad json, even if user expected failure + # return expect_fail, {} + return False, {} try: # Convert to string to validate the input is valid JSON @@ -556,7 +558,9 @@ def _match_command_json( self.olog.warning( "JSON load failed. Check match value is in JSON format: %s", error ) - return expect_fail, {} + # Always fail on bad json, even if user expected failure + # return expect_fail, {} + return False, {} if exact_match: deep_diff = json_cmp(expect, js) diff --git a/tests/topotests/munet/native.py b/tests/topotests/munet/native.py index de0f0ffc6cbb..5747d5e1d70e 100644 --- a/tests/topotests/munet/native.py +++ b/tests/topotests/munet/native.py @@ -28,8 +28,10 @@ from .base import BaseMunet from .base import Bridge from .base import Commander +from .base import InterfaceMixin from .base import LinuxNamespace from .base import MunetError +from .base import SharedNamespace from .base import Timeout from .base import _async_get_exec_path from .base import _get_exec_path @@ -132,6 +134,22 @@ def convert_ranges_to_bitmask(ranges): return bitmask +class ExternalNetwork(SharedNamespace, InterfaceMixin): + """A network external to munet.""" + + def __init__(self, name=None, unet=None, logger=None, mtu=None, config=None): + """Create an external network.""" + del logger # avoid linter + del mtu # avoid linter + # Do we want to use os.getpid() rather than unet.pid? + super().__init__(name, pid=unet.pid, nsflags=unet.nsflags, unet=unet) + self.config = config if config else {} + + async def _async_delete(self): + self.logger.debug("%s: deleting", self) + await super()._async_delete() + + class L2Bridge(Bridge): """A linux bridge with no IP network address.""" @@ -555,17 +573,38 @@ async def _async_delete(self): await super()._async_delete() +class HostnetNode(NodeMixin, LinuxNamespace): + """A node for running commands in the host network namespace.""" + + def __init__(self, name, pid=True, **kwargs): + if "net" in kwargs: + del kwargs["net"] + super().__init__(name, pid=pid, net=False, **kwargs) + + self.logger.debug("%s: creating", self) + + self.mgmt_ip = None + self.mgmt_ip6 = None + self.set_ns_cwd(self.rundir) + + super().pytest_hook_open_shell() + self.logger.info("%s: created", self) + + def get_ifname(self, netname): # pylint: disable=useless-return + del netname + return None + + async def _async_delete(self): + self.logger.debug("%s: deleting", self) + await super()._async_delete() + + class SSHRemote(NodeMixin, Commander): """SSHRemote a node representing an ssh connection to something.""" def __init__( self, name, - server, - port=22, - user=None, - password=None, - idfile=None, **kwargs, ): super().__init__(name, **kwargs) @@ -580,32 +619,33 @@ def __init__( self.mgmt_ip = None self.mgmt_ip6 = None - self.port = port - - if user: - self.user = user - elif "SUDO_USER" in os.environ: - self.user = os.environ["SUDO_USER"] - else: + self.server = self.config["server"] + self.port = int(self.config.get("server-port", 22)) + self.sudo_user = os.environ.get("SUDO_USER") + self.user = self.config.get("ssh-user") + if not self.user: + self.user = self.sudo_user + if not self.user: self.user = getpass.getuser() - self.password = password - self.idfile = idfile - - self.server = f"{self.user}@{server}" + self.password = self.config.get("ssh-password") + self.idfile = self.config.get("ssh-identity-file") + self.use_host_network = None # Setup our base `pre-cmd` values # # We maybe should add environment variable transfer here in particular # MUNET_NODENAME. The problem is the user has to explicitly approve # of SendEnv variables. - self.__base_cmd = [ - get_exec_path_host("sudo"), - "-E", - f"-u{self.user}", - get_exec_path_host("ssh"), - ] - if port != 22: - self.__base_cmd.append(f"-p{port}") + self.__base_cmd = [] + if self.idfile and self.sudo_user: + self.__base_cmd += [ + get_exec_path_host("sudo"), + "-E", + f"-u{self.sudo_user}", + ] + self.__base_cmd.append(get_exec_path_host("ssh")) + if self.port != 22: + self.__base_cmd.append(f"-p{self.port}") self.__base_cmd.append("-q") self.__base_cmd.append("-oStrictHostKeyChecking=no") self.__base_cmd.append("-oUserKnownHostsFile=/dev/null") @@ -615,15 +655,34 @@ def __init__( # self.__base_cmd.append("-oSendVar='TEST'") self.__base_cmd_pty = list(self.__base_cmd) self.__base_cmd_pty.append("-t") - self.__base_cmd.append(self.server) - self.__base_cmd_pty.append(self.server) + server_str = f"{self.user}@{self.server}" + self.__base_cmd.append(server_str) + self.__base_cmd_pty.append(server_str) # self.set_pre_cmd(pre_cmd, pre_cmd_tty) self.logger.info("%s: created", self) def _get_pre_cmd(self, use_str, use_pty, ns_only=False, **kwargs): - pre_cmd = [] - if self.unet: + # None on first use, set after + if self.use_host_network is None: + # We have networks now so try and ping the server in the namespace + if not self.unet: + self.use_host_network = True + else: + rc, _, _ = self.unet.cmd_status(f"ping -w1 -c1 {self.server}") + if rc: + self.use_host_network = True + else: + self.use_host_network = False + + if self.use_host_network: + self.logger.debug("Using host namespace for ssh connection") + else: + self.logger.debug("Using munet namespace for ssh connection") + + if self.use_host_network: + pre_cmd = [] + else: pre_cmd = self.unet._get_pre_cmd(False, use_pty, ns_only=False, **kwargs) if ns_only: return pre_cmd @@ -979,17 +1038,16 @@ async def add_host_intf(self, hname, lname, mtu=None): ) self.unet.rootcmd.cmd_status(f"ip link set {dname} name {hname}") - rc, o, _ = self.unet.rootcmd.cmd_status("ip -o link show") - m = re.search(rf"\d+:\s+{re.escape(hname)}:.*", o) - if m: - self.unet.rootcmd.cmd_nostatus(f"ip link set {hname} down ") - self.unet.rootcmd.cmd_raises(f"ip link set {hname} netns {self.pid}") + # Make sure the interface is there. + self.unet.rootcmd.cmd_raises(f"ip -o link show {hname}") + self.unet.rootcmd.cmd_nostatus(f"ip link set {hname} down ") + self.unet.rootcmd.cmd_raises(f"ip link set {hname} netns {self.pid}") + # Wait for interface to show up in namespace for retry in range(0, 10): rc, o, _ = self.cmd_status(f"ip -o link show {hname}") if not rc: - if re.search(rf"\d+: {re.escape(hname)}:.*", o): - break + break if retry > 0: await asyncio.sleep(1) self.cmd_raises(f"ip link set {hname} name {lname}") @@ -1001,12 +1059,11 @@ async def rem_host_intf(self, hname): lname = self.host_intfs[hname] self.cmd_raises(f"ip link set {lname} down") self.cmd_raises(f"ip link set {lname} name {hname}") - self.cmd_status(f"ip link set netns 1 dev {hname}") - # The above is failing sometimes and not sure why - # logging.error( - # "XXX after setns %s", - # self.unet.rootcmd.cmd_nostatus(f"ip link show {hname}"), - # ) + # We need to NOT run this command in the new pid namespace so that pid 1 is the + # root init process and so the interface gets returned to the root namespace + self.unet.rootcmd.cmd_raises( + f"nsenter -t {self.pid} -n ip link set netns 1 dev {hname}" + ) del self.host_intfs[hname] async def add_phy_intf(self, devaddr, lname): @@ -1917,7 +1974,11 @@ async def run_cmd(self): # InterfaceMixin override # We need a name unique in the shared namespace. def get_ns_ifname(self, ifname): - return self.name + ifname + ifname = self.name + ifname + ifname = re.sub("gigabitethernet", "GE", ifname, flags=re.I) + if len(ifname) >= 16: + ifname = ifname[0:7] + ifname[-8:] + return ifname async def add_host_intf(self, hname, lname, mtu=None): # L3QemuVM needs it's own add_host_intf for macvtap, We need to create the tap @@ -2093,16 +2154,22 @@ async def gather_coverage_data(self): ) con.cmd_raises(rf"rm -rf {tmpdir}") - self.logger.info("Saved coverage data in VM at %s", dest) + self.logger.debug("Saved coverage data in VM at %s", dest) ldest = os.path.join(self.rundir, "gcov-data.tgz") if self.use_ssh: self.cmd_raises(["/bin/cat", dest], stdout=open(ldest, "wb")) - self.logger.info("Saved coverage data on host at %s", ldest) + self.logger.debug("Saved coverage data on host at %s", ldest) else: output = con.cmd_raises(rf"base64 {dest}") with open(ldest, "wb") as f: f.write(base64.b64decode(output)) - self.logger.info("Saved coverage data on host at %s", ldest) + self.logger.debug("Saved coverage data on host at %s", ldest) + self.logger.info("Extracting coverage for %s into %s", self.name, ldest) + + # We need to place the gcda files where munet expects to find them + gcdadir = Path(os.environ["GCOV_PREFIX"]) / self.name + self.unet.cmd_raises_nsonly(f"mkdir -p {gcdadir}") + self.unet.cmd_raises_nsonly(f"tar -C {gcdadir} -xzf {ldest}") async def _opencons( self, @@ -2878,7 +2945,9 @@ async def add_native_link(self, node1, node2, c1=None, c2=None): else: node2.set_lan_addr(node1, c2) - if "physical" not in c1 and not node1.is_vm: + if isinstance(node1, ExternalNetwork): + pass + elif "physical" not in c1 and not node1.is_vm: node1.set_intf_constraints(if1, **c1) if "physical" not in c2 and not node2.is_vm: node2.set_intf_constraints(if2, **c2) @@ -2891,14 +2960,8 @@ def add_l3_node(self, name, config=None, **kwargs): cls = L3QemuVM elif config and config.get("server"): cls = SSHRemote - kwargs["server"] = config["server"] - kwargs["port"] = int(config.get("server-port", 22)) - if "ssh-identity-file" in config: - kwargs["idfile"] = config.get("ssh-identity-file") - if "ssh-user" in config: - kwargs["user"] = config.get("ssh-user") - if "ssh-password" in config: - kwargs["password"] = config.get("ssh-password") + elif config and config.get("hostnet"): + cls = HostnetNode else: cls = L3NamespaceNode return super().add_host(name, cls=cls, config=config, **kwargs) @@ -2908,7 +2971,12 @@ def add_network(self, name, config=None, **kwargs): if config is None: config = {} - cls = L3Bridge if config.get("ip") else L2Bridge + if config.get("external"): + cls = ExternalNetwork + elif config.get("ip"): + cls = L3Bridge + else: + cls = L2Bridge mtu = kwargs.get("mtu", config.get("mtu")) return super().add_switch(name, cls=cls, config=config, mtu=mtu, **kwargs) @@ -2947,7 +3015,7 @@ async def coverage_finish(self): bdir = Path(os.environ["GCOV_BUILD_DIR"]) gcdadir = Path(os.environ["GCOV_PREFIX"]) - # Create GCNO symlinks + # Create .gcno symlinks if they don't already exist, for kernel they will self.logger.info("Creating .gcno symlinks from '%s' to '%s'", gcdadir, bdir) commander.cmd_raises( f'cd "{gcdadir}"; bdir="{bdir}"' @@ -2955,9 +3023,11 @@ async def coverage_finish(self): for f in $(find . -name '*.gcda'); do f=${f#./}; f=${f%.gcda}.gcno; - ln -fs $bdir/$f $f; - touch -h -r $bdir/$f $f; - echo $f; + if [ ! -h "$f" ]; then + ln -fs $bdir/$f $f; + touch -h -r $bdir/$f $f; + echo $f; + fi; done""" ) @@ -2977,10 +3047,30 @@ async def coverage_finish(self): # f"\nCOVERAGE-SUMMARY-START\n{output}\nCOVERAGE-SUMMARY-END\n" # ) - async def run(self): + async def load_images(self, images): tasks = [] + for image in images: + logging.debug("Checking for image %s", image) + rc, _, _ = self.rootcmd.cmd_status( + f"podman image inspect {image}", warn=False + ) + if not rc: + continue + logging.info("Pulling missing image %s", image) + aw = self.rootcmd.async_cmd_raises(f"podman pull {image}") + tasks.append(asyncio.create_task(aw)) + if not tasks: + return + _, pending = await asyncio.wait(tasks, timeout=600) + assert not pending, "Failed to pull container images" + async def run(self): + tasks = [] hosts = self.hosts.values() + + images = {x.container_image for x in hosts if hasattr(x, "container_image")} + await self.load_images(images) + launch_nodes = [x for x in hosts if hasattr(x, "launch")] launch_nodes = [x for x in launch_nodes if x.config.get("qemu")] run_nodes = [x for x in hosts if x.has_run_cmd()] @@ -3049,10 +3139,10 @@ async def wait_until_ready(x): await asyncio.sleep(0.25) logging.debug("%s is ready!", x) + tasks = [asyncio.create_task(wait_until_ready(x)) for x in ready_nodes] + logging.debug("Waiting for ready on nodes: %s", ready_nodes) - _, pending = await asyncio.wait( - [wait_until_ready(x) for x in ready_nodes], timeout=30 - ) + _, pending = await asyncio.wait(tasks, timeout=30) if pending: logging.warning("Timeout waiting for ready: %s", pending) for nr in pending: diff --git a/tests/topotests/munet/testing/fixtures.py b/tests/topotests/munet/testing/fixtures.py index 4150d28b593a..3c6ddf9aedef 100644 --- a/tests/topotests/munet/testing/fixtures.py +++ b/tests/topotests/munet/testing/fixtures.py @@ -25,7 +25,6 @@ from ..base import Bridge from ..base import get_event_loop from ..cleanup import cleanup_current -from ..cleanup import cleanup_previous from ..native import L3NodeMixin from ..parser import async_build_topology from ..parser import get_config @@ -130,9 +129,12 @@ def session_autouse(): else: is_worker = True - if not is_worker: - # This is unfriendly to multi-instance - cleanup_previous() + # We dont want to kill all munet and we don't have the rundir here yet + # This was more useful back when we used to leave processes around a lot + # more. + # if not is_worker: + # # This is unfriendly to multi-instance + # cleanup_previous() # We never pop as we want to keep logging _push_log_handler("session", "/tmp/unet-test/pytest-session.log") @@ -150,8 +152,9 @@ def session_autouse(): @pytest.fixture(autouse=True, scope="module") def module_autouse(request): + root_path = os.environ.get("MUNET_RUNDIR", "/tmp/unet-test") logpath = get_test_logdir(request.node.nodeid, True) - logpath = os.path.join("/tmp/unet-test", logpath, "pytest-exec.log") + logpath = os.path.join(root_path, logpath, "pytest-exec.log") with log_handler("module", logpath): sdir = os.path.dirname(os.path.realpath(request.fspath)) with chdir(sdir, "module autouse fixture"): @@ -174,7 +177,8 @@ def event_loop(): @pytest.fixture(scope="module") def rundir_module(): - d = os.path.join("/tmp/unet-test", get_test_logdir(module=True)) + root_path = os.environ.get("MUNET_RUNDIR", "/tmp/unet-test") + d = os.path.join(root_path, get_test_logdir(module=True)) logging.debug("conftest: test module rundir %s", d) return d @@ -375,7 +379,8 @@ async def stepfunction(desc=""): @pytest.fixture(scope="function") def rundir(): - d = os.path.join("/tmp/unet-test", get_test_logdir(module=False)) + root_path = os.environ.get("MUNET_RUNDIR", "/tmp/unet-test") + d = os.path.join(root_path, get_test_logdir(module=False)) logging.debug("conftest: test function rundir %s", d) return d @@ -383,9 +388,8 @@ def rundir(): # Configure logging @pytest.hookimpl(hookwrapper=True, tryfirst=True) def pytest_runtest_setup(item): - d = os.path.join( - "/tmp/unet-test", get_test_logdir(nodeid=item.nodeid, module=False) - ) + root_path = os.environ.get("MUNET_RUNDIR", "/tmp/unet-test") + d = os.path.join(root_path, get_test_logdir(nodeid=item.nodeid, module=False)) config = item.config logging_plugin = config.pluginmanager.get_plugin("logging-plugin") filename = Path(d, "pytest-exec.log") diff --git a/tests/topotests/munet/watchlog.py b/tests/topotests/munet/watchlog.py index f764f9dac337..27bc3251a679 100644 --- a/tests/topotests/munet/watchlog.py +++ b/tests/topotests/munet/watchlog.py @@ -15,7 +15,6 @@ class MatchFoundError(Exception): """An error raised when a match is not found.""" - def __init__(self, watchlog, match): self.watchlog = watchlog self.match = match From a41b484f0a12b49ebbe70a6dd64b5dc5fdbf99ce Mon Sep 17 00:00:00 2001 From: Rajesh Girada Date: Mon, 20 May 2024 09:34:41 -0700 Subject: [PATCH 216/472] ospf6d: Handling Topo Change in GR-HELPER mode for max-age lsas Description: OSPF6 GR HELPER router should consider as TOPOCHANGE when it receives lsas with max age and should exit from Helper. But, it is not exiting from helper because this max age lsa is considered as duplicated lsa since the sender uses same seq number for max age lsa from the previous lsa update. Currently, topo change is not considered for duplicated lsas. So removed the duplicated check when validating TOPOCHNAGE. Signed-off-by: Rajesh Girada --- ospf6d/ospf6_flood.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c index 98d3bbc5197b..b87aa2ffe103 100644 --- a/ospf6d/ospf6_flood.c +++ b/ospf6d/ospf6_flood.c @@ -295,9 +295,7 @@ void ospf6_install_lsa(struct ospf6_lsa *lsa) lsa->installed = now; /* Topo change handling */ - if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa->header->type)) - && !CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)) { - + if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa->header->type))) { /* check if it is new lsa ? or existing lsa got modified ?*/ if (!old || OSPF6_LSA_IS_CHANGED(old, lsa)) ospf6_helper_handle_topo_chg(ospf6, lsa); From e14781eb1d9be38ad89c58dcb20afc64062eab2a Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 4 Jun 2024 05:43:49 -0400 Subject: [PATCH 217/472] lib: darr: add free with element cleanup functions - `darr_free_free` to `darr_free` each element prior to `darr_free` the array. - `darr_free_func` to call `func` on each element prior to `darr_free` the array. Signed-off-by: Christian Hopps --- lib/darr.h | 37 +++++++++++++++++++++++++++++++++++++ tests/lib/test_darr.c | 27 +++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/lib/darr.h b/lib/darr.h index 404869d9a252..2b9a0a0c025b 100644 --- a/lib/darr.h +++ b/lib/darr.h @@ -24,6 +24,8 @@ * - darr_ensure_i * - darr_ensure_i_mt * - darr_free + * - darr_free_free + * - darr_free_func * - darr_insert * - darr_insert_mt * - darr_insertz @@ -217,6 +219,41 @@ void *__darr_resize(void *a, uint count, size_t esize, struct memtype *mt); } \ } while (0) +/** + * Free memory allocated for the dynamic array `A`, calling `darr_free` for + * each element of the array first. + * + * Args: + * A: The dynamic array, can be NULL. + */ +#define darr_free_free(A) \ + do { \ + for (uint __i = 0; __i < darr_len(A); __i++) \ + if ((A)[__i]) { \ + struct darr_metadata *__meta = \ + _darr_meta((A)[__i]); \ + XFREE(__meta->mtype, __meta); \ + } \ + darr_free(A); \ + } while (0) + +/** + * Free memory allocated for the dynamic array `A`, calling `F` routine + * for each element of the array first. + * + * Args: + * A: The dynamic array, can be NULL. + * F: The function to call for each element. + */ + +#define darr_free_func(A, F) \ + do { \ + for (uint __i = 0; __i < darr_len(A); __i++) { \ + F((A)[__i]); \ + } \ + darr_free(A); \ + } while (0) + /** * Make sure that there is room in the dynamic array `A` to add `C` elements. * diff --git a/tests/lib/test_darr.c b/tests/lib/test_darr.c index 74aedac4b7e7..87f9e3e5642c 100644 --- a/tests/lib/test_darr.c +++ b/tests/lib/test_darr.c @@ -20,6 +20,8 @@ * [x] - darr_foreach_i * [x] - darr_foreach_p * [x] - darr_free + * [x] - darr_free_free + * [x] - darr_free_func * [x] - darr_insert * [ ] - darr_insertz * [x] - darr_insert_n @@ -318,6 +320,8 @@ static void test_string(void) uint addlen = strlen(add); char *da1 = NULL; char *da2 = NULL; + const char **strings = NULL; + uint sum = 0; assert(darr_strlen(da1) == 0); @@ -412,6 +416,29 @@ static void test_string(void) da1 = darr_in_strcatf(da1, "0123456789: %08x", 0xDEADBEEF); assert(!strcmp("0123456789: deadbeef", da1)); darr_free(da1); + + sum = 0; + *darr_append(strings) = "1"; + *darr_append(strings) = "2"; + *darr_append(strings) = "3"; +#define adder(x) (sum += atoi(x)) + darr_free_func(strings, adder); + assert(sum == 6); + assert(strings == NULL); + + sum = 0; + darr_free_func(strings, adder); + assert(sum == 0); + assert(strings == NULL); + + *darr_append(strings) = NULL; + *darr_append(strings) = darr_strdup("2"); + *darr_append(strings) = darr_strdup("3"); + darr_free_free(strings); + assert(strings == NULL); + + darr_free_free(strings); + assert(strings == NULL); } int main(int argc, char **argv) From 22eccbfab916b2c6b64037e872a5c5a870d1a4d6 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 4 Jun 2024 06:01:59 -0400 Subject: [PATCH 218/472] lib: fix incorrect use of error checking macro Signed-off-by: Christian Hopps --- lib/yang.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/yang.c b/lib/yang.c index 702fcf436d14..44459df4a50a 100644 --- a/lib/yang.c +++ b/lib/yang.c @@ -897,7 +897,7 @@ char *yang_convert_lyd_format(const char *data, size_t data_len, assert(out_format != LYD_LYB); - if (in_format != LYD_LYB && !MGMT_MSG_VALIDATE_NUL_TERM(data, data_len)) { + if (in_format != LYD_LYB && (!data_len || data[data_len - 1] != 0)) { zlog_err("Corrupt input data, no NUL terminating byte"); return NULL; } From 33b73f8e3aa13679ba3aad82be2a88d7cb69f426 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 4 Jun 2024 10:28:48 -0400 Subject: [PATCH 219/472] lib: native msg add array of strings support Signed-off-by: Christian Hopps --- lib/mgmt_msg_native.c | 18 ++++++++++++++++++ lib/mgmt_msg_native.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/lib/mgmt_msg_native.c b/lib/mgmt_msg_native.c index 39ce9abae649..d0a0b72189ba 100644 --- a/lib/mgmt_msg_native.c +++ b/lib/mgmt_msg_native.c @@ -6,6 +6,7 @@ * */ #include +#include "darr.h" #include "mgmt_msg_native.h" DEFINE_MGROUP(MSG_NATIVE, "Native message allocations"); @@ -50,3 +51,20 @@ int vmgmt_msg_native_send_error(struct msg_conn *conn, uint64_t sess_or_txn_id, mgmt_msg_native_free_msg(msg); return ret; } + +const char **_mgmt_msg_native_strings_decode(const void *_sdata, int sdlen) +{ + const char *sdata = _sdata; + const char **strings = NULL; + int len; + + if (sdata[sdlen - 1] != 0) + return NULL; + + for (; sdlen; sdata += len, sdlen -= len) { + *darr_append(strings) = darr_strdup(sdata); + len = 1 + darr_strlen(strings[darr_lasti(strings)]); + } + + return strings; +} diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index 21f702cc6134..cb1101d24f1c 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -524,6 +524,25 @@ extern int vmgmt_msg_native_send_error(struct msg_conn *conn, p; \ }) +/** + * mgmt_msg_native_add_str() - Append [another] string to the msg. + * @msg: (IN/OUT) Pointer to the native message, variable may be updated. + * @s: string to append. + * + * Append string @s to the native message @msg. @msg is assumed to have a + * sequence of NUL-terminated strings at the end of it. This function appends + * the string @s and it's NUL terminating octet to the message. + * + * NOTE: Be aware @msg pointer may change as a result of reallocating the + * message to fit the new data. Any other pointers into the old message should + * be discarded. + */ +#define mgmt_msg_native_add_str(msg, s) \ + do { \ + int __len = strlen(s) + 1; \ + mgmt_msg_native_append(msg, s, __len); \ + } while (0) + /** * mgmt_msg_native_send_msg(msg, short_circuit_ok) - Send a native msg. * @conn: the mgmt_msg connection. @@ -689,6 +708,27 @@ extern int vmgmt_msg_native_send_error(struct msg_conn *conn, #define mgmt_msg_native_data_len_decode(msg, msglen) \ ((msglen) - sizeof(*msg) - msg->vsplit) +/** + * mgmt_msg_native_strings_decode() - Get dynamic array of str ptrs from the msg. + * @msg: Pointer to the native message. + * @msglen: Length of the message. + * @sdata: pointer to the variable length string data at end of @msg. + * + * Given a pointer to a sequence of NUL-terminated strings allocate + * and return a dynamic array of dynamic array strings. This function + * can be used to decode a message that was built using + * mgmt_msg_native_add_str(). + * + * Return: a dynamic array (darr) of string pointers, or NULL if the message + * is corrupt. + */ +#define mgmt_msg_native_strings_decode(msg, msg_len, sdata) \ + _mgmt_msg_native_strings_decode(sdata, \ + (msg_len) - ((sdata) - (char *)(msg))) + +extern const char **_mgmt_msg_native_strings_decode(const void *sdata, + int sdlen); + #ifdef __cplusplus } #endif From 657f1650e697b2020f5f2fb4f5c271a9c6e30c53 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 4 Jun 2024 10:29:46 -0400 Subject: [PATCH 220/472] mgmtd: add front-end notification selector support Signed-off-by: Christian Hopps --- lib/mgmt_msg_native.h | 22 ++++++++++ mgmtd/mgmt_fe_adapter.c | 97 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 112 insertions(+), 7 deletions(-) diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index cb1101d24f1c..e61346e6e5d5 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -176,6 +176,7 @@ DECLARE_MTYPE(MSG_NATIVE_RPC_REPLY); #define MGMT_MSG_CODE_EDIT_REPLY 6 /* Public API */ #define MGMT_MSG_CODE_RPC 7 /* Public API */ #define MGMT_MSG_CODE_RPC_REPLY 8 /* Public API */ +#define MGMT_MSG_CODE_NOTIFY_SELECT 9 /* Public API */ /* * Datastores @@ -426,6 +427,27 @@ _Static_assert(sizeof(struct mgmt_msg_rpc_reply) == offsetof(struct mgmt_msg_rpc_reply, data), "Size mismatch"); +/** + * struct mgmt_msg_notify_select - Add notification selectors for FE client. + * + * Add xpath prefix notification selectors to limit the notifications sent + * to the front-end client. + * + * @selectors: the xpath prefixes to selectors notifications through. + * @repalce: if true replace existing selectors with `selectors`. + */ +struct mgmt_msg_notify_select { + struct mgmt_msg_header; + uint8_t replace; + uint8_t resv2[7]; + + alignas(8) char selectors[]; +}; + +_Static_assert(sizeof(struct mgmt_msg_notify_select) == + offsetof(struct mgmt_msg_notify_select, selectors), + "Size mismatch"); + /* * Validate that the message ends in a NUL terminating byte */ diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index fc1bde0b38ae..a076dc72f96b 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -43,6 +43,7 @@ struct mgmt_fe_session_ctx { uint64_t txn_id; uint64_t cfg_txn_id; uint8_t ds_locked[MGMTD_DS_MAX_ID]; + const char **notify_xpaths; struct event *proc_cfg_txn_clnp; struct event *proc_show_txn_clnp; @@ -1401,10 +1402,45 @@ static void fe_adapter_handle_edit(struct mgmt_fe_session_ctx *session, } } +/** + * fe_adapter_handle_notify_select() - Handle an Notify Select message. + * @session: the client session. + * @__msg: the message data. + * @msg_len: the length of the message data. + */ +static void fe_adapter_handle_notify_select(struct mgmt_fe_session_ctx *session, + void *__msg, size_t msg_len) +{ + struct mgmt_msg_notify_select *msg = __msg; + uint64_t req_id = msg->req_id; + const char **selectors = NULL; + const char **new; + + /* An empty message clears the selectors */ + if (msg_len >= sizeof(*msg)) { + selectors = mgmt_msg_native_strings_decode(msg, msg_len, + msg->selectors); + if (!selectors) { + fe_adapter_send_error(session, req_id, false, -EINVAL, + "Invalid message"); + return; + } + } + if (msg->replace) { + darr_free_free(session->notify_xpaths); + session->notify_xpaths = selectors; + } else { + new = darr_append_nz(session->notify_xpaths, + darr_len(selectors)); + memcpy(new, selectors, darr_len(selectors) * sizeof(*selectors)); + darr_free(selectors); + } +} + /** * fe_adapter_handle_rpc() - Handle an RPC message from an FE client. * @session: the client session. - * @msg_raw: the message data. + * @__msg: the message data. * @msg_len: the length of the message data. */ static void fe_adapter_handle_rpc(struct mgmt_fe_session_ctx *session, @@ -1503,13 +1539,26 @@ static void fe_adapter_handle_native_msg(struct mgmt_fe_client_adapter *adapter, assert(session->adapter == adapter); switch (msg->code) { - case MGMT_MSG_CODE_GET_DATA: - fe_adapter_handle_get_data(session, msg, msg_len); - break; case MGMT_MSG_CODE_EDIT: + __dbg("adapter %s: session-id %" PRIu64 " received EDIT message", + adapter->name, msg->refer_id); fe_adapter_handle_edit(session, msg, msg_len); break; + case MGMT_MSG_CODE_NOTIFY_SELECT: + __dbg("adapter %s: session-id %" PRIu64 + " received NOTIFY_SELECT message", + adapter->name, msg->refer_id); + fe_adapter_handle_notify_select(session, msg, msg_len); + break; + case MGMT_MSG_CODE_GET_DATA: + __dbg("adapter %s: session-id %" PRIu64 + " received GET_DATA message", + adapter->name, msg->refer_id); + fe_adapter_handle_get_data(session, msg, msg_len); + break; case MGMT_MSG_CODE_RPC: + __dbg("adapter %s: session-id %" PRIu64 " received RPC message", + adapter->name, msg->refer_id); fe_adapter_handle_rpc(session, msg, msg_len); break; default: @@ -1554,14 +1603,48 @@ void mgmt_fe_adapter_send_notify(struct mgmt_msg_notify_data *msg, size_t msglen { struct mgmt_fe_client_adapter *adapter; struct mgmt_fe_session_ctx *session; + struct nb_node *nb_node; + const char **xpath_prefix; + const char *notif; + bool sendit; + uint len; assert(msg->refer_id == 0); + notif = mgmt_msg_native_xpath_decode(msg, msglen); + if (!notif) { + __log_err("Corrupt notify msg"); + return; + } + + /* + * We need the nb_node to obtain a path which does not include any + * specific list entry selectors + */ + nb_node = nb_node_find(notif); + if (!nb_node) { + __log_err("No schema found for notification: %s", notif); + return; + } + FOREACH_ADAPTER_IN_LIST (adapter) { FOREACH_SESSION_IN_LIST (adapter, session) { - msg->refer_id = session->session_id; - (void)fe_adapter_send_native_msg(adapter, msg, msglen, - false); + /* If no selectors then always send */ + sendit = !session->notify_xpaths; + darr_foreach_p (session->notify_xpaths, xpath_prefix) { + len = strlen(*xpath_prefix); + if (!strncmp(*xpath_prefix, notif, len) || + !strncmp(*xpath_prefix, nb_node->xpath, + len)) { + sendit = true; + break; + } + } + if (sendit) { + msg->refer_id = session->session_id; + (void)fe_adapter_send_native_msg(adapter, msg, + msglen, false); + } } } msg->refer_id = 0; From 8772e444a7dca8c80aac9e9918f0ed977e0d7322 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 4 Jun 2024 10:57:10 -0400 Subject: [PATCH 221/472] tests: add notify select support in fe client test utility Signed-off-by: Christian Hopps --- tests/topotests/lib/fe_client.py | 49 +++++++++++++++++++------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/tests/topotests/lib/fe_client.py b/tests/topotests/lib/fe_client.py index a47544633ba6..019b3239ca99 100755 --- a/tests/topotests/lib/fe_client.py +++ b/tests/topotests/lib/fe_client.py @@ -18,6 +18,8 @@ import time from pathlib import Path +from munet.base import Timeout + CWD = os.path.dirname(os.path.realpath(__file__)) # This is painful but works if you have installed protobuf would be better if we @@ -80,6 +82,8 @@ MSG_NOTIFY_FMT = "=B7x" NOTIFY_FIELD_RESULT_TYPE = 0 +MSG_NOTIFY_SELECT_FMT = "=B7x" + # # Native message codes # @@ -88,6 +92,7 @@ MSG_CODE_TREE_DATA = 2 MSG_CODE_GET_DATA = 3 MSG_CODE_NOTIFY = 4 +MSG_CODE_NOTIFY_SELECT = 9 msg_native_formats = { MSG_CODE_ERROR: MSG_ERROR_FMT, @@ -95,6 +100,7 @@ MSG_CODE_TREE_DATA: MSG_TREE_DATA_FMT, MSG_CODE_GET_DATA: MSG_GET_DATA_FMT, MSG_CODE_NOTIFY: MSG_NOTIFY_FMT, + MSG_CODE_NOTIFY_SELECT: MSG_NOTIFY_SELECT_FMT, } @@ -308,17 +314,22 @@ def get_data(self, query, data=True, config=False): logging.debug("Received GET: %s: %s", mfixed, mdata) return result - # def subscribe(self, notif_xpath): - # # Create the message - # mdata, req_id = self.get_native_msg_header(MSG_CODE_SUBSCRIBE) - # mdata += struct.pack(MSG_SUBSCRIBE_FMT, MSG_FORMAT_JSON) - # mdata += notif_xpath.encode("utf-8") + b"\x00" + def add_notify_select(self, replace, notif_xpaths): + # Create the message + mdata, req_id = self.get_native_msg_header(MSG_CODE_NOTIFY_SELECT) + mdata += struct.pack(MSG_NOTIFY_SELECT_FMT, replace) + + for xpath in notif_xpaths: + mdata += xpath.encode("utf-8") + b"\x00" - # self.send_native_msg(mdata) - # logging.debug("Sent SUBSCRIBE") + self.send_native_msg(mdata) + logging.debug("Sent NOTIFY_SELECT") def recv_notify(self, xpaths=None): - while True: + if xpaths: + self.add_notify_select(True, xpaths) + + for remaining in Timeout(60): logging.debug("Waiting for Notify Message") mhdr, mfixed, mdata = self.recv_native_msg() if mhdr[HDR_FIELD_CODE] == MSG_CODE_NOTIFY: @@ -328,19 +339,11 @@ def recv_notify(self, xpaths=None): vsplit = mhdr[HDR_FIELD_VSPLIT] assert mdata[vsplit - 1] == 0 - xpath = mdata[: vsplit - 1].decode("utf-8") - assert mdata[-1] == 0 - result = mdata[vsplit:-1].decode("utf-8") - - if not xpaths: - return result - js = json.loads(result) - key = [x for x in js.keys()][0] - for xpath in xpaths: - if key.startswith(xpath): - return result - logging.debug("'%s' didn't match xpath filters", key) + # xpath = mdata[: vsplit - 1].decode("utf-8") + return mdata[vsplit:-1].decode("utf-8") + else: + raise TimeoutError("Timeout waiting for notifications") def __parse_args(): @@ -381,6 +384,8 @@ def __server_connect(spath): logging.warn("retry server connection in .5s (%s)", os.strerror(ec)) time.sleep(0.5) logging.info("Connected to server on %s", spath) + # Set a timeout of 5 minutes for socket operations. + sock.settimeout(60 * 5) return sock @@ -412,8 +417,12 @@ def main(): __main() except KeyboardInterrupt: logging.info("Exiting") + except TimeoutError as error: + logging.error("Timeout: %s", error) + sys.exit(2) except Exception as error: logging.error("Unexpected error exiting: %s", error, exc_info=True) + sys.exit(1) if __name__ == "__main__": From 56ce19891b01c07461103de3dd427e85e3cc2252 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Thu, 6 Jun 2024 10:06:04 -0400 Subject: [PATCH 222/472] tests: switch test to new fe_client notify selector syntax Signed-off-by: Christian Hopps --- tests/topotests/mgmt_notif/test_notif.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/topotests/mgmt_notif/test_notif.py b/tests/topotests/mgmt_notif/test_notif.py index c85e7ba79596..de984b12e1ec 100644 --- a/tests/topotests/mgmt_notif/test_notif.py +++ b/tests/topotests/mgmt_notif/test_notif.py @@ -51,7 +51,7 @@ def test_frontend_notification(tgen): check_kernel_32(r1, "11.11.11.11", 1, "") - fe_client_path = CWD + "/../lib/fe_client.py" + fe_client_path = CWD + "/../lib/fe_client.py --verbose" rc, _, _ = r1.cmd_status(fe_client_path + " --help") if rc: @@ -61,7 +61,7 @@ def test_frontend_notification(tgen): # So we filter to avoid that, all the rest are frr-ripd:authentication-failure # making our test deterministic output = r1.cmd_raises( - fe_client_path + " --listen frr-ripd:authentication-failure" + fe_client_path + " --listen /frr-ripd:authentication-failure" ) jsout = json.loads(output) From 0c6f14ec145342ce793db8ae4efa31adc2972e21 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 24 May 2024 16:46:17 +0200 Subject: [PATCH 223/472] Revert "vtysh, zebra: Fix malformed json output for multiple vrfs in command 'show ip route vrf all json'" This reverts commit 0e2fc3d67f1d358896a764373f41cb59c095eda9. This fix was correct but not optimal for memory consumption at scale. Signed-off-by: Louis Scalbert --- zebra/zebra_vty.c | 81 +++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 52 deletions(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 44720754ba8b..cc2d9b2164a8 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -60,8 +60,8 @@ struct route_show_ctx { }; static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, json_object *vrf_json, - bool use_json, route_tag_t tag, + safi_t safi, bool use_fib, bool use_json, + route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, uint32_t tableid, @@ -153,8 +153,8 @@ DEFPY (show_ip_rpf, }; return do_show_ip_route(vty, VRF_DEFAULT_NAME, ip ? AFI_IP : AFI_IP6, - SAFI_MULTICAST, false, NULL, uj, 0, NULL, false, - 0, 0, 0, false, &ctx); + SAFI_MULTICAST, false, uj, 0, NULL, false, 0, 0, + 0, false, &ctx); } DEFPY (show_ip_rpf_addr, @@ -858,13 +858,14 @@ static void vty_show_ip_route_detail_json(struct vty *vty, vty_json(vty, json); } -static void -do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, - struct route_table *table, afi_t afi, bool use_fib, - json_object *vrf_json, route_tag_t tag, - const struct prefix *longer_prefix_p, bool supernets_only, - int type, unsigned short ospf_instance_id, bool use_json, - uint32_t tableid, bool show_ng, struct route_show_ctx *ctx) +static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, + struct route_table *table, afi_t afi, + bool use_fib, route_tag_t tag, + const struct prefix *longer_prefix_p, + bool supernets_only, int type, + unsigned short ospf_instance_id, bool use_json, + uint32_t tableid, bool show_ng, + struct route_show_ctx *ctx) { struct route_node *rn; struct route_entry *re; @@ -886,7 +887,7 @@ do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, * => display the VRF and table if specific */ - if (use_json && !vrf_json) + if (use_json) json = json_object_new_object(); /* Show all routes. */ @@ -961,11 +962,7 @@ do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, if (json_prefix) { prefix2str(&rn->p, buf, sizeof(buf)); - if (!vrf_json) - json_object_object_add(json, buf, json_prefix); - else - json_object_object_add(vrf_json, buf, - json_prefix); + json_object_object_add(json, buf, json_prefix); json_prefix = NULL; } } @@ -974,15 +971,13 @@ do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, * This is an extremely expensive operation at scale * and non-pretty reduces memory footprint significantly. */ - if (use_json && !vrf_json) { + if (use_json) vty_json_no_pretty(vty, json); - json = NULL; - } } static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, - afi_t afi, bool use_fib, json_object *vrf_json, - bool use_json, route_tag_t tag, + afi_t afi, bool use_fib, bool use_json, + route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, bool show_ng, @@ -1002,15 +997,15 @@ static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, continue; do_show_ip_route(vty, zvrf_name(zvrf), afi, SAFI_UNICAST, - use_fib, vrf_json, use_json, tag, - longer_prefix_p, supernets_only, type, - ospf_instance_id, zrt->tableid, show_ng, ctx); + use_fib, use_json, tag, longer_prefix_p, + supernets_only, type, ospf_instance_id, + zrt->tableid, show_ng, ctx); } } static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, - safi_t safi, bool use_fib, json_object *vrf_json, - bool use_json, route_tag_t tag, + safi_t safi, bool use_fib, bool use_json, + route_tag_t tag, const struct prefix *longer_prefix_p, bool supernets_only, int type, unsigned short ospf_instance_id, uint32_t tableid, @@ -1045,7 +1040,7 @@ static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi, return CMD_SUCCESS; } - do_show_route_helper(vty, zvrf, table, afi, use_fib, vrf_json, tag, + do_show_route_helper(vty, zvrf, table, afi, use_fib, tag, longer_prefix_p, supernets_only, type, ospf_instance_id, use_json, tableid, show_ng, ctx); @@ -1750,7 +1745,6 @@ DEFPY (show_route, struct route_show_ctx ctx = { .multi = vrf_all || table_all, }; - json_object *root_json = NULL; if (!vrf_is_backend_netns()) { if ((vrf_all || vrf_name) && (table || table_all)) { @@ -1772,42 +1766,25 @@ DEFPY (show_route, } if (vrf_all) { - if (!!json) - root_json = json_object_new_object(); RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - json_object *vrf_json = NULL; - if ((zvrf = vrf->info) == NULL || (zvrf->table[afi][SAFI_UNICAST] == NULL)) continue; - if (!!json) - vrf_json = json_object_new_object(); - if (table_all) do_show_ip_route_all(vty, zvrf, afi, !!fib, - vrf_json, !!json, tag, + !!json, tag, prefix_str ? prefix : NULL, !!supernets_only, type, ospf_instance_id, !!ng, &ctx); else do_show_ip_route(vty, zvrf_name(zvrf), afi, - SAFI_UNICAST, !!fib, vrf_json, - !!json, tag, - prefix_str ? prefix : NULL, + SAFI_UNICAST, !!fib, !!json, + tag, prefix_str ? prefix : NULL, !!supernets_only, type, ospf_instance_id, table, !!ng, &ctx); - - if (!!json) - json_object_object_add(root_json, - zvrf_name(zvrf), - vrf_json); - } - if (!!json) { - vty_json_no_pretty(vty, root_json); - root_json = NULL; } } else { vrf_id_t vrf_id = VRF_DEFAULT; @@ -1823,13 +1800,13 @@ DEFPY (show_route, return CMD_SUCCESS; if (table_all) - do_show_ip_route_all(vty, zvrf, afi, !!fib, NULL, !!json, - tag, prefix_str ? prefix : NULL, + do_show_ip_route_all(vty, zvrf, afi, !!fib, !!json, tag, + prefix_str ? prefix : NULL, !!supernets_only, type, ospf_instance_id, !!ng, &ctx); else do_show_ip_route(vty, vrf->name, afi, SAFI_UNICAST, - !!fib, NULL, !!json, tag, + !!fib, !!json, tag, prefix_str ? prefix : NULL, !!supernets_only, type, ospf_instance_id, table, !!ng, &ctx); From 03b1ee7a39d1ac166f4dff62c75374f85029c918 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 27 May 2024 10:04:14 +0200 Subject: [PATCH 224/472] lib: add helpers to print json keys Add helpers to print json keys in order to prepare the next commits. Signed-off-by: Louis Scalbert --- lib/vty.c | 15 +++++++++++++++ lib/vty.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/lib/vty.c b/lib/vty.c index 628c694e95bc..0dcd118a97a0 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -390,6 +390,21 @@ int vty_json_no_pretty(struct vty *vty, struct json_object *json) return vty_json_helper(vty, json, JSON_C_TO_STRING_NOSLASHESCAPE); } + +void vty_json_key(struct vty *vty, const char *key, bool *first_key) +{ + vty_out(vty, "%s\"%s\":", *first_key ? "{" : ",", key); + *first_key = false; +} + +void vty_json_close(struct vty *vty, bool first_key) +{ + if (first_key) + /* JSON was not opened */ + vty_out(vty, "{"); + vty_out(vty, "}\n"); +} + void vty_json_empty(struct vty *vty, struct json_object *json) { json_object *jsonobj = json; diff --git a/lib/vty.h b/lib/vty.h index a9570ef048d5..c336a816cc1f 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -378,6 +378,8 @@ extern bool vty_set_include(struct vty *vty, const char *regexp); */ extern int vty_json(struct vty *vty, struct json_object *json); extern int vty_json_no_pretty(struct vty *vty, struct json_object *json); +void vty_json_key(struct vty *vty, const char *key, bool *first_key); +void vty_json_close(struct vty *vty, bool first_key); extern void vty_json_empty(struct vty *vty, struct json_object *json); /* post fd to be passed to the vtysh client * fd is owned by the VTY code after this and will be closed when done From cb440058f2d85d1408f932ad820c38e8e1b17191 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 24 May 2024 17:06:59 +0200 Subject: [PATCH 225/472] zebra: fix show route vrf all memory consumption 0e2fc3d67f ("vtysh, zebra: Fix malformed json output for multiple vrfs in command 'show ip route vrf all json'") has been reverted in the previous commit. Although the fix was correct, it was consuming too muca memory when displaying large route tables. A root JSON object was storing all the JSON objects containing the route tables, each containing their respective prefixes in JSON objects. This resulted in excessive memory allocation for JSON objects, potentially leading to an out-of-memory error on the machine. To Fix the memory consumption issue for the "show ip[v6] route vrf all json" command, display the tables one by one and free the memory of each JSON object after it has been displayed. Signed-off-by: Louis Scalbert --- zebra/zebra_vty.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index cc2d9b2164a8..97245d55b9eb 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -1739,6 +1739,7 @@ DEFPY (show_route, "Nexthop Group Information\n") { afi_t afi = ipv4 ? AFI_IP : AFI_IP6; + bool first_vrf_json = true; struct vrf *vrf; int type = 0; struct zebra_vrf *zvrf; @@ -1770,7 +1771,9 @@ DEFPY (show_route, if ((zvrf = vrf->info) == NULL || (zvrf->table[afi][SAFI_UNICAST] == NULL)) continue; - + if (json) + vty_json_key(vty, zvrf_name(zvrf), + &first_vrf_json); if (table_all) do_show_ip_route_all(vty, zvrf, afi, !!fib, !!json, tag, @@ -1786,6 +1789,8 @@ DEFPY (show_route, ospf_instance_id, table, !!ng, &ctx); } + if (json) + vty_json_close(vty, first_vrf_json); } else { vrf_id_t vrf_id = VRF_DEFAULT; From 85eb60ffd6ce40428c3a99aeddf46b1b60d2e0a5 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 24 May 2024 16:34:23 +0200 Subject: [PATCH 226/472] zebra: fix show route memory consumption When displaying a route table in JSON, a table JSON object is storing all the prefix JSON objects containing the prefix information. This results in excessive memory allocation for JSON objects, potentially leading to an out-of-memory error on the machine with large routing tables. To Fix the memory consumption issue for the "show ip[v6] route [vrf XX] json" command, display the prefixes one by one and free the memory of each JSON object after it has been displayed. Signed-off-by: Louis Scalbert --- zebra/zebra_vty.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 97245d55b9eb..c31218a7c367 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -869,9 +869,9 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, { struct route_node *rn; struct route_entry *re; + bool first_json = true; int first = 1; rib_dest_t *dest; - json_object *json = NULL; json_object *json_prefix = NULL; uint32_t addr; char buf[BUFSIZ]; @@ -887,9 +887,6 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, * => display the VRF and table if specific */ - if (use_json) - json = json_object_new_object(); - /* Show all routes. */ for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) { dest = rib_dest_from_rnode(rn); @@ -962,17 +959,15 @@ static void do_show_route_helper(struct vty *vty, struct zebra_vrf *zvrf, if (json_prefix) { prefix2str(&rn->p, buf, sizeof(buf)); - json_object_object_add(json, buf, json_prefix); + vty_json_key(vty, buf, &first_json); + vty_json_no_pretty(vty, json_prefix); + json_prefix = NULL; } } - /* - * This is an extremely expensive operation at scale - * and non-pretty reduces memory footprint significantly. - */ if (use_json) - vty_json_no_pretty(vty, json); + vty_json_close(vty, first_json); } static void do_show_ip_route_all(struct vty *vty, struct zebra_vrf *zvrf, From 2d6dcc0c57ecb4a8d28bf8671e67c3e292f7adad Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 27 May 2024 10:35:26 +0200 Subject: [PATCH 227/472] tests: check show route vrf all json output Check that "show ip route vrf XXX json" and the JSON at key "XXX" of "show ip route vrf all json" gives the same output. Signed-off-by: Louis Scalbert --- .../test_bgp-vrf-route-leak-basic.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py index 3938a966eea2..6d4b436bccf9 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py +++ b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py @@ -338,6 +338,21 @@ def test_vrf_route_leak_donna_after_eva_down(): result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + """ + Check that "show ip route vrf DONNA json" and the JSON at key "DONNA" of + "show ip route vrf all json" gives the same result. + """ + + def check_vrf_table(router, vrf, expect): + output = router.vtysh_cmd("show ip route vrf all json", isjson=True) + vrf_table = output.get(vrf, {}) + + return topotest.json_cmp(vrf_table, expect) + + test_func = partial(check_vrf_table, r1, "DONNA", expect) + result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + def test_vrf_route_leak_donna_after_eva_up(): logger.info("Ensure that route states change after EVA interface goes up") From a1dd57b64984ea64cb1f03d85b74229d6d2257db Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Thu, 6 Jun 2024 14:08:00 -0400 Subject: [PATCH 228/472] mgmtd: add empty notif xpath map for completeness New back-end clients may need to add notification static allocations so we should have it available for those users, rather than requiring the new user delve into the mgmtd infra and modify it themselves. Signed-off-by: Christian Hopps --- mgmtd/mgmt_be_adapter.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index 81574d1a56cf..c7f4fb9d844d 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -155,6 +155,9 @@ static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { [MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths, }; +static const char *const *be_client_notif_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { +}; + static const char *const *be_client_rpc_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { #ifdef HAVE_RIPD [MGMTD_BE_CLIENT_ID_RIPD] = ripd_rpc_xpaths, @@ -298,6 +301,13 @@ static void mgmt_be_xpath_map_init(void) MGMT_BE_XPATH_SUBSCR_TYPE_OPER); } + /* Initialize the common NOTIF init map */ + for (init = be_client_notif_xpaths[id]; init && *init; init++) { + __dbg(" - NOTIF XPATH: '%s'", *init); + mgmt_register_client_xpath(id, *init, + MGMT_BE_XPATH_SUBSCR_TYPE_NOTIF); + } + /* Initialize the common RPC init map */ for (init = be_client_rpc_xpaths[id]; init && *init; init++) { __dbg(" - RPC XPATH: '%s'", *init); @@ -308,6 +318,7 @@ static void mgmt_be_xpath_map_init(void) __dbg("Total Cfg XPath Maps: %u", darr_len(be_cfg_xpath_map)); __dbg("Total Oper XPath Maps: %u", darr_len(be_oper_xpath_map)); + __dbg("Total Noitf XPath Maps: %u", darr_len(be_notif_xpath_map)); __dbg("Total RPC XPath Maps: %u", darr_len(be_rpc_xpath_map)); } From 491e608c557310295fbefef99f813259c422ff7d Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Thu, 6 Jun 2024 19:49:40 -0400 Subject: [PATCH 229/472] doc: add some text on native message API and notif xpath array Signed-off-by: Christian Hopps --- doc/developer/mgmtd-dev.rst | 53 +++++++++++++++++++++++++++++++++---- doc/user/mgmtd.rst | 31 +++++++++++++++++++--- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/doc/developer/mgmtd-dev.rst b/doc/developer/mgmtd-dev.rst index 2404ffe2a73b..b979af06fa0d 100644 --- a/doc/developer/mgmtd-dev.rst +++ b/doc/developer/mgmtd-dev.rst @@ -317,12 +317,25 @@ Likewise the client should be cleaned up in the daemon cleanup routine. Back-End XPATH mappings ^^^^^^^^^^^^^^^^^^^^^^^ -In order for ``mgmtd`` to direct configuration to your daemon you need to add +In order for ``mgmtd`` to direct YANG modeled data to your daemon you should add some XPATH mappings to ``mgmtd/mgmt_be_adapter.c``. These XPATHs determine which -configuration changes get sent over the *back-end* interface to your daemon. -There are 2 arrays to update the first for config support and the second for -operational state. - +YANG modeled data (e.g., config changes) get sent over the *back-end* interface +to your daemon. There are 4 arrays to possibly update: configuration, +operational, notification, and RPC. You only need to add entries to the array +that you require mapping for. + +Additionally the back-end client can specify these XPATH mappings when it +first connects to mgmtd using it's initial ``SUBSCRIBE`` message. + +NOTE: the notif array (``be_client_notif_xpaths``), is a slightly different from +the other 3 types (config, oper and rpc) in that it maps xpaths the back-end +client wishes to *receive* notifications for, not the ones it may generate. +Normally a back-end client is generating notifications; however, mgmtd supports +back-end clients also "subscribing" to receive these notifications as well from +other back-end clients through notif_xpath maps. + +Config Map Example +"""""""""""""""""" Below are the strings added for staticd config support: .. code-block:: c @@ -342,6 +355,9 @@ Below are the strings added for staticd config support: #endif }; + +Operational Map Example +""""""""""""""""""""""" Below are the strings added for zebra operational state support (note zebra is not conditionalized b/c it should always be present): @@ -358,6 +374,33 @@ not conditionalized b/c it should always be present): [MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths, }; + +RPC Map Example +""""""""""""""" +Below is the string added for ripd RPC support: + +.. code-block:: c + + static const char *const ripd_rpc_xpaths[] = { + "/frr-ripd", + NULL, + }; + + static const char *const *be_client_rpc_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { + #ifdef HAVE_RIPD + [MGMTD_BE_CLIENT_ID_RIPD] = ripd_rpc_xpaths, + #endif + }; + + +Notification Map Example +"""""""""""""""""""""""" +There are no current back-end daemons that wish to receive other back-end +notifications so the array is empty. This may change in the future, and of +course any back-end daemon can utilize the connect (``BeSubscribeReq``) messages +as well. + + MGMTD Internals --------------- diff --git a/doc/user/mgmtd.rst b/doc/user/mgmtd.rst index aa7ccaac3a65..8b197bb99bdd 100644 --- a/doc/user/mgmtd.rst +++ b/doc/user/mgmtd.rst @@ -97,6 +97,8 @@ Following are some of the management operations supported: - Currently committing configurations from Candidate to Running database is only allowed, and not vice versa. +Front-End Native Protobuf API +""""""""""""""""""""""""""""" The exact set of message-based APIs are represented as Google Protobuf messages and can be found in the following file distributed with FRR codebase. @@ -104,6 +106,14 @@ messages and can be found in the following file distributed with FRR codebase. lib/mgmt.proto +Front-End Native (non-protobuf) API +""""""""""""""""""""""""""""""""""" +Additionally there exists a "native" API that does not utilize ``protobuf``s +this native API and the front-end messages and structures it supports are +documented in the header file ``lib/mgmt_msg_native.h``. + +Connecting to MGMTd +""""""""""""""""""" The MGMT daemon implements a MGMT Frontend Server that opens a UNIX socket-based IPC channel on the following path to listen for incoming connections from all possible Frontend clients: @@ -124,7 +134,9 @@ specification of this library can be found at: lib/mgmt_fe_client.h -Following is a list of message types supported on the MGMT Frontend Interface: +Following is a list of protobuf message types supported on the MGMT Frontend +Interface: + - SESSION_REQ - SESSION_REPLY - LOCK_DB_REQ @@ -139,8 +151,21 @@ Following is a list of message types supported on the MGMT Frontend Interface: - COMMIT_CONFIG_REPLY - GET_DATA_REQ - GET_DATA_REPLY - - REGISTER_NOTIFY_REQ - - DATA_NOTIFY_REQ + +Following is a list of native messages types supported by the MGMTd Front-End +API: + + - ERROR (receive) - received in response to any sent native message. + - TREE_DATA (receive) - returned data from a datastore + - GET_DATA (send) - get a tree of data + - NOTIFY (receive) - a notification received from mgmtd + - EDIT (send) - edit configuration datastore + - EDIT_REPLY (receive) - reply for an edit operation + - RPC (send) - sending (invoking) an RPC. + - RPC_REPLY (receive) - reply from invoking an RPC + - NOTIFY_SELECT (send) - specify the sub-set of notifications the front-end + wishes to receive, rather than the default of receiving all. + Please refer to the MGMT Frontend Client Developers Reference and Guide (coming soon) for more details. From e973c1dd481b99171774a7dd127695864d5a7b09 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Sat, 8 Jun 2024 15:37:47 -0400 Subject: [PATCH 230/472] ci: do apt-get update before installing required modules - Use `uname -r` to also install specific module versions since with github runners the running kernel can become out-dated with the deployed packages. Signed-off-by: Christian Hopps --- .github/workflows/build-test-docker.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-test-docker.yml b/.github/workflows/build-test-docker.yml index de9f620c9d5f..3f53f32d3a8c 100644 --- a/.github/workflows/build-test-docker.yml +++ b/.github/workflows/build-test-docker.yml @@ -68,11 +68,13 @@ jobs: - name: Run topotests run: | uname -a - sudo apt-get install -y linux-modules-extra-azure || true - sudo apt-get install -y python3-xmltodict || true + MODPKGVER=$(uname -r) + sudo apt-get update -y + # Github is running old kernels but installing newer packages :( + sudo apt-get install -y linux-modules-extra-azure linux-modules-${MODPKGVER} linux-modules-extra-${MODPKGVER} python3-xmltodict sudo modprobe vrf || true - sudo modprobe mpls-iptunnel || true - sudo modprobe mpls-router || true + sudo modprobe mpls-iptunnel + sudo modprobe mpls-router docker load --input /tmp/frr-ubuntu22.tar if ! grep CONFIG_IP_MROUTE_MULTIPLE_TABLES=y /boot/config*; then From 49bc1b6c21e8da0da82746373a7257aeb2c9fa4a Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Sun, 17 Dec 2023 21:04:31 +0100 Subject: [PATCH 231/472] lib: fix copy srte_color from zapi_nexthop structure When switching from nexthop to zapi_nexthop, the srte color is copied. Do the same in reverse. Fixes: 31f937fb43f4 ("lib, zebra: Add SR-TE policy infrastructure to zebra") Signed-off-by: Philippe Guibert --- lib/zclient.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/zclient.c b/lib/zclient.c index c5b1e72380ca..1aab7b48ba8f 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2174,6 +2174,7 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh, znh->weight = nh->weight; znh->ifindex = nh->ifindex; znh->gate = nh->gate; + znh->srte_color = nh->srte_color; if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ONLINK)) SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_ONLINK); From 04655c5f74b11e517155e024bbb335736c2605b4 Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 7 Jun 2024 10:41:38 -0300 Subject: [PATCH 232/472] tests: rework isis_tilfa_topo1 to fix timing issues In this topotest, steps 10-15 were added to test the IS-IS switchover functionality. In short, two cases were tested: switchover after a link down event and switchover after a BFD down event. Both cases were tested in sequence on the same router, rt6. This involved the following steps: - Setting the SPF delay timer to 15 seconds - Shutting down the eth-rt5 interface from the switch side - Testing the post-switchover RIB and LIB (triggered by the link down event) - Testing the post-SPF RIB and LIB - Bringing the eth-rt5 interface back up - Configuring a BFD session between rt6 and rt5 - Shutting down the eth-rt5 interface from the switch side once again - Testing the post-switchover RIB and LIB (triggered by the BFD down event) - Testing the post-SPF RIB and LIB Since the time window to test the post-switchover RIB and LIB was too narrow (10 seconds), these tests were having sporadic failures. To resolve this problem, we can simplify the switchover test as follows: - Setting the SPF delay timer to 60 seconds (not 15) - Disabling "link-detect" on rt6's eth-rt5 interface - Shutting down the eth-rt5 interface from the switch side - On rt6, testing the post-switchover RIB and LIB (triggered by the BFD down event) - On rt5, testing the post-switchover RIB and LIB (triggered by the link down event) Notice how we can test both post-link-down and post-BFD-down switchover cases simultaneously by having different "link-detect" configurations on rt5 and rt6. Additionally, by using a larger SPF delay timer, the time window to test the post-switchover RIB and LIB is much larger and less prone to sporadic failures. Signed-off-by: Renato Westphal --- .../rt1/step10/show_ip_route.ref.diff | 0 .../rt1/step10/show_ipv6_route.ref.diff | 0 .../rt1/step10/show_mpls_table.ref.diff | 0 .../rt1/step11/show_ip_route.ref.diff | 0 .../rt1/step11/show_ipv6_route.ref.diff | 0 .../rt1/step11/show_mpls_table.ref.diff | 0 .../rt1/step12/show_ip_route.ref.diff | 19 - .../rt1/step12/show_ipv6_route.ref.diff | 18 - .../rt1/step12/show_mpls_table.ref.diff | 28 - .../rt2/step10/show_ip_route.ref.diff | 0 .../rt2/step10/show_ipv6_route.ref.diff | 0 .../rt2/step10/show_mpls_table.ref.diff | 0 .../rt2/step11/show_ip_route.ref.diff | 0 .../rt2/step11/show_ipv6_route.ref.diff | 0 .../rt2/step11/show_mpls_table.ref.diff | 0 .../rt2/step12/show_ip_route.ref.diff | 0 .../rt2/step12/show_ipv6_route.ref.diff | 0 .../rt2/step12/show_mpls_table.ref.diff | 20 - .../rt3/step10/show_ip_route.ref.diff | 0 .../rt3/step10/show_ipv6_route.ref.diff | 0 .../rt3/step10/show_mpls_table.ref.diff | 0 .../rt3/step11/show_ip_route.ref.diff | 0 .../rt3/step11/show_ipv6_route.ref.diff | 0 .../rt3/step11/show_mpls_table.ref.diff | 0 .../rt3/step12/show_ip_route.ref.diff | 58 --- .../rt3/step12/show_ipv6_route.ref.diff | 45 -- .../rt3/step12/show_mpls_table.ref.diff | 60 --- .../rt4/step10/show_ip_route.ref.diff | 0 .../rt4/step10/show_ipv6_route.ref.diff | 0 .../rt4/step10/show_mpls_table.ref.diff | 0 .../rt4/step11/show_ip_route.ref.diff | 0 .../rt4/step11/show_ipv6_route.ref.diff | 0 .../rt4/step11/show_mpls_table.ref.diff | 0 .../rt4/step12/show_ip_route.ref.diff | 144 ------ .../rt4/step12/show_ipv6_route.ref.diff | 50 -- .../rt4/step12/show_mpls_table.ref.diff | 78 --- .../rt5/step10/show_ip_route.ref | 482 ++++++++++++++++++ .../rt5/step10/show_ip_route.ref.diff | 0 .../rt5/step10/show_ipv6_route.ref | 229 +++++++++ .../rt5/step10/show_ipv6_route.ref.diff | 0 .../rt5/step10/show_mpls_table.ref | 301 +++++++++++ .../rt5/step10/show_mpls_table.ref.diff | 0 .../rt5/step11/show_ip_route.ref.diff | 0 .../rt5/step11/show_ipv6_route.ref.diff | 0 .../rt5/step11/show_mpls_table.ref.diff | 0 .../rt5/step12/show_ip_route.ref.diff | 151 ------ .../rt5/step12/show_ipv6_route.ref.diff | 53 -- .../rt5/step12/show_mpls_table.ref.diff | 80 --- .../rt6/step10/show_bfd_peer_down.ref | 6 + .../rt6/step10/show_bfd_peer_up.ref | 6 + .../rt6/step10/show_ip_route.ref | 354 +++++++++++++ .../rt6/step10/show_ip_route.ref.diff | 0 .../rt6/step10/show_ipv6_route.ref | 112 ++++ .../rt6/step10/show_ipv6_route.ref.diff | 0 .../rt6/step10/show_mpls_table.ref | 127 +++++ .../rt6/step10/show_mpls_table.ref.diff | 0 .../rt6/step11/show_ip_route.ref.diff | 125 ----- .../rt6/step11/show_ipv6_route.ref.diff | 56 -- .../rt6/step11/show_mpls_table.ref.diff | 106 ---- .../rt6/step12/show_ip_route.ref.diff | 153 ------ .../rt6/step12/show_ipv6_route.ref.diff | 66 --- .../rt6/step12/show_mpls_table.ref.diff | 78 --- .../topotests/isis_tilfa_topo1/rt6/zebra.conf | 1 + .../isis_tilfa_topo1/test_isis_tilfa_topo1.py | 358 ++----------- 64 files changed, 1665 insertions(+), 1699 deletions(-) delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step10/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step10/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step10/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step11/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step11/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step11/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step10/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step10/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step10/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step11/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step11/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step11/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step12/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step12/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step10/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step10/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step10/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step11/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step11/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step11/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step10/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step10/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step10/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step11/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step11/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step11/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step11/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step11/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step11/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_down.ref create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_up.ref create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step10/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step11/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff deleted file mode 100644 index a8d6e6c65ee1..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ip_route.ref.diff +++ /dev/null @@ -1,19 +0,0 @@ ---- a/rt1/step11/show_ip_route.ref -+++ b/rt1/step12/show_ip_route.ref -@@ -110,16 +110,6 @@ - "labels":[ - 16060 - ] -- }, -- { -- "fib":true, -- "ip":"10.0.1.3", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16060 -- ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff deleted file mode 100644 index 637c59f6ef6c..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_ipv6_route.ref.diff +++ /dev/null @@ -1,18 +0,0 @@ ---- a/rt1/step11/show_ipv6_route.ref -+++ b/rt1/step12/show_ipv6_route.ref -@@ -105,15 +105,6 @@ - "labels":[ - 16061 - ] -- }, -- { -- "fib":true, -- "afi":"ipv6", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16061 -- ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff deleted file mode 100644 index e110bf48eb87..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step12/show_mpls_table.ref.diff +++ /dev/null @@ -1,28 +0,0 @@ ---- a/rt1/step11/show_mpls_table.ref -+++ b/rt1/step12/show_mpls_table.ref -@@ -79,12 +79,6 @@ - "type":"SR (IS-IS)", - "outLabel":16060, - "installed":true, -- "nexthop":"10.0.1.3" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16060, -- "installed":true, - "nexthop":"10.0.1.2" - } - ] -@@ -96,12 +90,6 @@ - { - "type":"SR (IS-IS)", - "outLabel":16061, -- "installed":true, -- "interface":"eth-sw1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16061, - "installed":true, - "interface":"eth-sw1" - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step10/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step11/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff deleted file mode 100644 index 84a36442d35e..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step12/show_mpls_table.ref.diff +++ /dev/null @@ -1,20 +0,0 @@ ---- a/rt2/step11/show_mpls_table.ref -+++ b/rt2/step12/show_mpls_table.ref -@@ -199,7 +199,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16060, -+ "outLabel":16500, - "nexthop":"10.0.1.3" - } - ] -@@ -230,7 +230,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16061, -+ "outLabel":16501, - "interface":"eth-sw1" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step10/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step11/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff deleted file mode 100644 index 8695cf848f88..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ip_route.ref.diff +++ /dev/null @@ -1,58 +0,0 @@ ---- a/rt3/step11/show_ip_route.ref -+++ b/rt3/step12/show_ip_route.ref -@@ -198,44 +198,37 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":30, -+ "metric":40, - "installed":true, - "nexthops":[ - { - "fib":true, -- "ip":"10.0.4.5", -+ "ip":"10.0.1.2", - "afi":"ipv4", -- "interfaceName":"eth-rt5-1", -+ "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ -- 30060 -+ 16060 - ] - }, - { - "fib":true, -- "ip":"10.0.5.5", -+ "ip":"10.0.4.5", - "afi":"ipv4", -- "interfaceName":"eth-rt5-2", -+ "interfaceName":"eth-rt5-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 30060 - ] -- } -- ], -- "backupNexthops":[ -+ }, - { -- "ip":"10.0.1.2", -+ "fib":true, -+ "ip":"10.0.5.5", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -+ "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16060 -+ 30060 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff deleted file mode 100644 index 661d0fe75de3..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_ipv6_route.ref.diff +++ /dev/null @@ -1,45 +0,0 @@ ---- a/rt3/step11/show_ipv6_route.ref -+++ b/rt3/step12/show_ipv6_route.ref -@@ -186,7 +186,7 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":30, -+ "metric":40, - "installed":true, - "nexthops":[ - { -@@ -194,9 +194,6 @@ - "afi":"ipv6", - "interfaceName":"eth-rt5-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 30061 - ] -@@ -206,23 +203,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt5-2", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 30061 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16061 -- ] -- } - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff deleted file mode 100644 index 30941b398b7e..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step12/show_mpls_table.ref.diff +++ /dev/null @@ -1,60 +0,0 @@ ---- a/rt3/step11/show_mpls_table.ref -+++ b/rt3/step12/show_mpls_table.ref -@@ -165,27 +165,8 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30060, -- "installed":true, -- "nexthop":"10.0.5.5", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":30060, -- "installed":true, -- "nexthop":"10.0.4.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16060, -+ "installed":true, - "nexthop":"10.0.1.2" - } - ] -@@ -196,27 +177,8 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30061, -- "installed":true, -- "interface":"eth-rt5-2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":30061, -- "installed":true, -- "interface":"eth-rt5-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16061, -+ "installed":true, - "interface":"eth-sw1" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step10/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step11/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff deleted file mode 100644 index 2645c5945b51..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ip_route.ref.diff +++ /dev/null @@ -1,144 +0,0 @@ ---- a/rt4/step11/show_ip_route.ref -+++ b/rt4/step12/show_ip_route.ref -@@ -160,23 +160,13 @@ - "interfaceName":"eth-rt5", - "active":true, - "backupIndex":[ -- 0 -+ 0, -+ 1 - ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16500 -- ] -- } - ] - } - ], -@@ -196,24 +186,10 @@ - "afi":"ipv4", - "interfaceName":"eth-rt6", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30060 -- ] -- } - ] - } - ], -@@ -352,19 +328,12 @@ - "active":true, - "backupIndex":[ - 0, -- 1, -- 2 -+ 1 - ] - } - ], - "backupNexthops":[ - { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- }, -- { - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -@@ -397,19 +366,12 @@ - "active":true, - "backupIndex":[ - 0, -- 1, -- 2 -+ 1 - ] - } - ], - "backupNexthops":[ - { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- }, -- { - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -@@ -439,14 +401,6 @@ - 0 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- } - ] - } - ], -@@ -460,18 +414,7 @@ - { - "ip":"10.0.7.6", - "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true -+ "interfaceName":"eth-rt6" - } - ] - } -@@ -492,13 +435,6 @@ - "afi":"ipv4", - "interfaceName":"eth-rt5", - "active":true -- }, -- { -- "fib":true, -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff deleted file mode 100644 index 37e3185ae034..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_ipv6_route.ref.diff +++ /dev/null @@ -1,50 +0,0 @@ ---- a/rt4/step11/show_ipv6_route.ref -+++ b/rt4/step12/show_ipv6_route.ref -@@ -149,23 +149,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt5", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16501 -- ] -- } - ] - } - ], -@@ -184,23 +171,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt6", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30061 -- ] -- } - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff deleted file mode 100644 index 186291adac06..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step12/show_mpls_table.ref.diff +++ /dev/null @@ -1,78 +0,0 @@ ---- a/rt4/step11/show_mpls_table.ref -+++ b/rt4/step12/show_mpls_table.ref -@@ -179,17 +179,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.7.6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":30060, -- "nexthop":"10.0.6.5" -+ "nexthop":"10.0.7.6" - } - ] - }, -@@ -201,17 +191,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":30061, -- "interface":"eth-rt5" -+ "interface":"eth-rt6" - } - ] - }, -@@ -223,17 +203,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.6.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16500, -- "nexthop":"10.0.7.6" -+ "nexthop":"10.0.6.5" - } - ] - }, -@@ -245,17 +215,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16501, -- "interface":"eth-rt6" -+ "interface":"eth-rt5" - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref new file mode 100644 index 000000000000..fcaf5e6d6086 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref @@ -0,0 +1,482 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref new file mode 100644 index 000000000000..d193e1e86b0d --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021, + 16041 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021, + 16061 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021, + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref new file mode 100644 index 000000000000..8a339e6e9a2a --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "30010":{ + "inLabel":30010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30011":{ + "inLabel":30011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "30020":{ + "inLabel":30020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30021":{ + "inLabel":30021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "30030":{ + "inLabel":30030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30031":{ + "inLabel":30031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "30040":{ + "inLabel":30040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + } + ] + }, + "30041":{ + "inLabel":30041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt3-2" + } + ] + }, + "30060":{ + "inLabel":30060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + } + ] + }, + "30061":{ + "inLabel":30061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt3-2" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step11/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff deleted file mode 100644 index 3d21c04297bb..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ip_route.ref.diff +++ /dev/null @@ -1,151 +0,0 @@ ---- a/rt5/step11/show_ip_route.ref -+++ b/rt5/step12/show_ip_route.ref -@@ -159,24 +159,10 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.8.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16040 -- ] -- } - ] - } - ], -@@ -187,25 +173,11 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":20, -+ "metric":30, - "installed":true, - "nexthops":[ - { - "fib":true, -- "ip":"10.0.8.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -@@ -276,19 +248,12 @@ - "active":true, - "backupIndex":[ - 0, -- 1, -- 2 -+ 1 - ] - } - ], - "backupNexthops":[ - { -- "ip":"10.0.8.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- }, -- { - "ip":"10.0.4.3", - "afi":"ipv4", - "interfaceName":"eth-rt3-1", -@@ -321,19 +286,12 @@ - "active":true, - "backupIndex":[ - 0, -- 1, -- 2 -+ 1 - ] - } - ], - "backupNexthops":[ - { -- "ip":"10.0.8.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- }, -- { - "ip":"10.0.4.3", - "afi":"ipv4", - "interfaceName":"eth-rt3-1", -@@ -439,14 +397,6 @@ - 0 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.8.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- } - ] - } - ], -@@ -465,39 +415,6 @@ - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -- }, -- { -- "fib":true, -- "ip":"10.0.8.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- } -- ] -- } -- ], -- "10.0.8.0\/24":[ -- { -- "prefix":"10.0.8.0\/24", -- "protocol":"isis", -- "distance":115, -- "metric":20, -- "nexthops":[ -- { -- "ip":"10.0.8.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4", - "active":true - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff deleted file mode 100644 index 66a9dace8b0b..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_ipv6_route.ref.diff +++ /dev/null @@ -1,53 +0,0 @@ ---- a/rt5/step11/show_ipv6_route.ref -+++ b/rt5/step12/show_ipv6_route.ref -@@ -149,23 +149,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt4", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16041 -- ] -- } - ] - } - ], -@@ -176,25 +163,12 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":20, -+ "metric":30, - "installed":true, - "nexthops":[ - { - "fib":true, - "afi":"ipv6", -- "interfaceName":"eth-rt6", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", - "interfaceName":"eth-rt4", - "active":true, - "labels":[ diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff deleted file mode 100644 index cdfc407f938b..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step12/show_mpls_table.ref.diff +++ /dev/null @@ -1,80 +0,0 @@ ---- a/rt5/step11/show_mpls_table.ref -+++ b/rt5/step12/show_mpls_table.ref -@@ -179,17 +179,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.6.4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.8.6" -+ "nexthop":"10.0.6.4" - } - ] - }, -@@ -201,17 +191,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-rt6" -+ "interface":"eth-rt4" - } - ] - }, -@@ -221,18 +201,8 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.8.6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16060, -+ "installed":true, - "nexthop":"10.0.6.4" - } - ] -@@ -243,18 +213,8 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16061, -+ "installed":true, - "interface":"eth-rt4" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_down.ref b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_down.ref new file mode 100644 index 000000000000..2b573d077f62 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_down.ref @@ -0,0 +1,6 @@ +{ + "multihop":false, + "peer":"10.0.8.5", + "interface":"eth-rt5", + "status":"down" +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_up.ref b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_up.ref new file mode 100644 index 000000000000..f536b36f15bd --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_bfd_peer_up.ref @@ -0,0 +1,6 @@ +{ + "multihop":false, + "peer":"10.0.8.5", + "interface":"eth-rt5", + "status":"up" +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref new file mode 100644 index 000000000000..822e24b3b0ca --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref @@ -0,0 +1,354 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":30, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref new file mode 100644 index 000000000000..c7e79852fbeb --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref @@ -0,0 +1,112 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16501 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref new file mode 100644 index 000000000000..6e4a783a6c57 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref @@ -0,0 +1,127 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16500":{ + "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16501":{ + "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "installed":true, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff deleted file mode 100644 index e477e87d1ed3..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ip_route.ref.diff +++ /dev/null @@ -1,125 +0,0 @@ ---- a/rt6/step10/show_ip_route.ref -+++ b/rt6/step11/show_ip_route.ref -@@ -76,25 +76,11 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":30, -+ "metric":40, - "installed":true, - "nexthops":[ - { - "fib":true, -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 30030 -- ] -- } -- ], -- "backupNexthops":[ -- { - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -@@ -150,25 +136,11 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":20, -+ "metric":30, - "installed":true, - "nexthops":[ - { - "fib":true, -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -@@ -276,22 +248,11 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":20, -+ "metric":30, - "installed":true, - "nexthops":[ - { - "fib":true, -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -@@ -307,22 +268,11 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":20, -+ "metric":30, - "installed":true, - "nexthops":[ - { - "fib":true, -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -@@ -389,19 +339,9 @@ - "prefix":"10.0.8.0\/24", - "protocol":"isis", - "distance":115, -- "metric":20, -+ "metric":30, - "nexthops":[ - { -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff deleted file mode 100644 index 12e0b591d290..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_ipv6_route.ref.diff +++ /dev/null @@ -1,56 +0,0 @@ ---- a/rt6/step10/show_ipv6_route.ref -+++ b/rt6/step11/show_ipv6_route.ref -@@ -72,25 +72,12 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":30, -+ "metric":40, - "installed":true, - "nexthops":[ - { - "fib":true, - "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 30031 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", - "interfaceName":"eth-rt4", - "active":true, - "labels":[ -@@ -142,25 +129,12 @@ - "selected":true, - "destSelected":true, - "distance":115, -- "metric":20, -+ "metric":30, - "installed":true, - "nexthops":[ - { - "fib":true, - "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", - "interfaceName":"eth-rt4", - "active":true, - "labels":[ diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff deleted file mode 100644 index 387dcca3fe66..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step11/show_mpls_table.ref.diff +++ /dev/null @@ -1,106 +0,0 @@ ---- a/rt6/step10/show_mpls_table.ref -+++ b/rt6/step11/show_mpls_table.ref -@@ -8,12 +8,6 @@ - "outLabel":16010, - "installed":true, - "nexthop":"10.0.7.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":30010, -- "installed":true, -- "nexthop":"10.0.8.5" - } - ] - }, -@@ -26,12 +20,6 @@ - "outLabel":16011, - "installed":true, - "interface":"eth-rt4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":30011, -- "installed":true, -- "interface":"eth-rt5" - } - ] - }, -@@ -85,18 +73,8 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30030, -- "installed":true, -- "nexthop":"10.0.8.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16030, -+ "installed":true, - "nexthop":"10.0.7.4" - } - ] -@@ -107,17 +85,6 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30031, -- "installed":true, -- "interface":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16031, - "interface":"eth-rt4" - } -@@ -173,18 +140,8 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.8.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16500, -+ "installed":true, - "nexthop":"10.0.7.4" - } - ] -@@ -195,18 +152,8 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":16501, -+ "installed":true, - "interface":"eth-rt4" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff deleted file mode 100644 index 1086b6e7060c..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ip_route.ref.diff +++ /dev/null @@ -1,153 +0,0 @@ ---- a/rt6/step12/show_ip_route.ref -+++ b/rt6/step12/show_ip_route.ref -@@ -18,16 +18,6 @@ - "labels":[ - 16010 - ] -- }, -- { -- "fib":true, -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30010 -- ] - } - ] - } -@@ -48,24 +38,10 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 16020 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30020 -- ] -- } - ] - } - ], -@@ -108,24 +84,10 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30040 -- ] -- } - ] - } - ], -@@ -168,13 +130,6 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4", - "active":true -- }, -- { -- "fib":true, -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true - } - ] - } -@@ -194,17 +149,6 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", - "active":true - } - ] -@@ -225,17 +169,6 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", - "active":true - } - ] -@@ -297,13 +230,6 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4", - "active":true -- }, -- { -- "fib":true, -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true - } - ] - } -@@ -318,18 +244,7 @@ - { - "ip":"10.0.7.4", - "afi":"ipv4", -- "interfaceName":"eth-rt4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.8.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true -+ "interfaceName":"eth-rt4" - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff deleted file mode 100644 index 571c66fb6503..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_ipv6_route.ref.diff +++ /dev/null @@ -1,66 +0,0 @@ ---- a/rt6/step12/show_ipv6_route.ref -+++ b/rt6/step12/show_ipv6_route.ref -@@ -17,15 +17,6 @@ - "labels":[ - 16011 - ] -- }, -- { -- "fib":true, -- "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30011 -- ] - } - ] - } -@@ -45,23 +36,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt4", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 16021 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30021 -- ] -- } - ] - } - ], -@@ -102,23 +80,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt4", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 30041 -- ] -- } - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff deleted file mode 100644 index 18322f18a1ed..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step12/show_mpls_table.ref.diff +++ /dev/null @@ -1,78 +0,0 @@ ---- a/rt6/step12/show_mpls_table.ref -+++ b/rt6/step12/show_mpls_table.ref -@@ -31,17 +31,7 @@ - "type":"SR (IS-IS)", - "outLabel":16020, - "installed":true, -- "nexthop":"10.0.7.4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":30020, -- "nexthop":"10.0.8.5" -+ "nexthop":"10.0.7.4" - } - ] - }, -@@ -53,17 +43,7 @@ - "type":"SR (IS-IS)", - "outLabel":16021, - "installed":true, -- "interface":"eth-rt4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":30021, -- "interface":"eth-rt5" -+ "interface":"eth-rt4" - } - ] - }, -@@ -98,17 +78,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.7.4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":30040, -- "nexthop":"10.0.8.5" -+ "nexthop":"10.0.7.4" - } - ] - }, -@@ -120,17 +90,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":30041, -- "interface":"eth-rt5" -+ "interface":"eth-rt4" - } - ] - }, \ No newline at end of file diff --git a/tests/topotests/isis_tilfa_topo1/rt6/zebra.conf b/tests/topotests/isis_tilfa_topo1/rt6/zebra.conf index 94fed46cca19..c765996237ec 100644 --- a/tests/topotests/isis_tilfa_topo1/rt6/zebra.conf +++ b/tests/topotests/isis_tilfa_topo1/rt6/zebra.conf @@ -16,6 +16,7 @@ interface eth-rt4 ! interface eth-rt5 ip address 10.0.8.6/24 + no link-detect ! ip forwarding ! diff --git a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py index e2bbf4588c39..2f5a5898afdd 100755 --- a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py +++ b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py @@ -131,7 +131,7 @@ def build_topo(tgen): ] for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: outputs[rname] = {} - for step in range(1, 12 + 1): + for step in range(1, 9 + 1): outputs[rname][step] = {} for file in files: if step == 1: @@ -158,6 +158,15 @@ def build_topo(tgen): outputs[rname][step][file] = open(f_out.name).read() f_in.close() f_out.close() + # HACK: use full snapshots for step 10 + step = 10 + for rname in ["rt5", "rt6"]: + outputs[rname][step] = {} + for file in files: + if file == "show_yang_interface_isis_adjacencies.ref": + continue + filename = "{}/{}/step{}/{}".format(CWD, rname, step, file) + outputs[rname][step][file] = open(filename).read() def setup_module(mod): @@ -176,7 +185,7 @@ def setup_module(mod): TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) ) router.load_config( - TopoRouter.RD_BFD, os.path.join(CWD, "/dev/null".format(rname)) + TopoRouter.RD_BFD, os.path.join(CWD, "{}/bfdd.conf".format(rname)) ) tgen.start_router() @@ -734,11 +743,17 @@ def test_mpls_lib_step9(): # Step 10 # # Action(s): -# - Setting spf-delay-ietf init-delay of 15s +# - Enable ISIS BFD between rt5 and rt6 +# - Verify that the BFD session is up +# - Configure an SPF delay-ietf initial delay of 60 seconds on both rt5 and rt6 +# - Shut down the eth-rt5 interface on rt6 from the switch side to test fast-reroute # # Expected changes: -# - No routing table change -# - At the end of test, SPF reacts to a failure in 15s +# - Verify that the BFD session is down +# - Routes should switch over to use alternate paths +# - On rt5, the switchover should be triggered by the link down event +# - On rt6, the switchover should be triggered by the BFD down event, since it has +# link-detect disabled on the eth-rt5 interface # def test_rib_ipv4_step10(): logger.info("Test (step 10): verify IPv4 RIB") @@ -748,353 +763,74 @@ def test_rib_ipv4_step10(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - logger.info("Setting spf-delay-ietf init-delay of 15s") - tgen.net["rt6"].cmd( - 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"' - ) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"] - ) - - -def test_rib_ipv6_step10(): - logger.info("Test (step 10): verify IPv6 RIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, - "show ipv6 route isis json", - outputs[rname][10]["show_ipv6_route.ref"], - ) - - -def test_mpls_lib_step10(): - logger.info("Test (step 10): verify MPLS LIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, "show mpls table json", outputs[rname][10]["show_mpls_table.ref"] - ) - - -# -# Step 11 -# -# Action(s): -# - shut the eth-rt5 interface on rt6 -# -# Expected changes: -# - Route switchover of routes via eth-rt5 -# -def test_rt6_step11(): - logger.info( - "Test (step 11): Check IPv4/6 RIB and MPLS table after a LFA switchover" - ) - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - logger.info( - "Shut a rt6 interface to rt5 from the switch side and check fast-reroute" - ) - tgen.net.cmd_raises("ip link set %s down" % tgen.net["s8"].intfs[1]) - - rname = "rt6" - router_compare_json_output( - rname, - "show ip route isis json", - outputs[rname][11]["show_ip_route.ref"], - count=20, - ) - router_compare_json_output( - rname, - "show ipv6 route isis json", - outputs[rname][11]["show_ipv6_route.ref"], - count=20, - ) - router_compare_json_output( - rname, - "show mpls table json", - outputs[rname][11]["show_mpls_table.ref"], - count=20, - ) - - -# -# Step 12 -# -# Action(s): wait for the convergence and SPF computation on rt6 -# -# Expected changes: -# - convergence of IPv4/6 RIB and MPLS table -# -def test_rib_ipv4_step12(): - logger.info("Test (step 12): verify IPv4 RIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - logger.info("Check SPF convergence") - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, - "show ip route isis json", - outputs[rname][12]["show_ip_route.ref"], - ) - - -def test_rib_ipv6_step12(): - logger.info("Test (step 12): verify IPv6 RIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, - "show ipv6 route isis json", - outputs[rname][12]["show_ipv6_route.ref"], - ) - - -def test_mpls_lib_step12(): - logger.info("Test (step 12): verify MPLS LIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, - "show mpls table json", - outputs[rname][12]["show_mpls_table.ref"], - ) - - -# -# Step 13 -# -# Action(s): -# - unshut the rt6 to rt5 interface -# - Setup BFD -# -# Expected changes: -# - All route tables go back to previous state situation -# - At the end of test, next SPF is scheduled in approximatively 15s -# -def test_rib_ipv4_step13(): - logger.info("Test (step 13): verify IPv4 RIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - logger.info("Unsetting spf-delay-ietf init-delay of 15s") - tgen.net["rt6"].cmd('vtysh -c "conf t" -c "router isis 1" -c "no spf-delay-ietf"') - - logger.info( - "Unshut the rt6 interface to rt5 from the switch side and check fast-reroute" - ) - tgen.net.cmd_raises("ip link set %s up" % tgen.net["s8"].intfs[1]) - - logger.info("Setup BFD on rt5 and rt6") - for rname in ["rt5", "rt6"]: - conf_file = os.path.join(CWD, "{}/bfdd.conf".format(rname)) - tgen.net[rname].cmd("vtysh -f {}".format(conf_file)) - - expect = ( - '[{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"up"}]' - ) - router_compare_json_output("rt6", "show bfd peers json", expect) - - # Unset link detection. We want zebra to consider linkdow as operationaly up - # in order that BFD triggers LFA instead of the interface down - - # reset spf-interval - logger.info("Set spf-interval to 15s") - tgen.net["rt6"].cmd( - 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 15000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"' - ) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"] - ) - - logger.info("Set ISIS BFD") + logger.info("Enabling ISIS BFD between rt5 and rt6") tgen.net["rt5"].cmd('vtysh -c "conf t" -c "int eth-rt6" -c "isis bfd"') tgen.net["rt6"].cmd('vtysh -c "conf t" -c "int eth-rt5" -c "isis bfd"') + logger.info("Checking if the BFD session is up") expect = ( - '[{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"up"}]' + '{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"up"}' ) router_compare_json_output( - rname, - "show bfd peers json", + "rt6", + "show bfd peer 10.0.8.5 json", expect, ) - -def test_rib_ipv6_step13(): - logger.info("Test (step 13): verify IPv6 RIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, - "show ipv6 route isis json", - outputs[rname][10]["show_ipv6_route.ref"], - ) - - -def test_mpls_lib_step13(): - logger.info("Test (step 13): verify MPLS LIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - router_compare_json_output( - rname, "show mpls table json", outputs[rname][10]["show_mpls_table.ref"] + logger.info("Setting SPF delay-ietf initial delay to 60 seconds") + for rname in ["rt5", "rt6"]: + tgen.net[rname].cmd( + 'vtysh -c "conf t" -c "router isis 1" -c "spf-delay-ietf init-delay 60000 short-delay 0 long-delay 0 holddown 0 time-to-learn 0"' ) + logger.info( + "Shutting down rt5 interface to rt6 from the switch side to test fast-reroute" + ) + tgen.net.cmd_raises("ip link set %s down" % tgen.net["s8"].intfs[0]) -# -# Step 14 -# -# Action(s): -# - drop traffic between rt5 and rt6 by shutting down the bridge between -# the routers. Interfaces on rt5 and rt6 stay up. -# -# Expected changes: -# - Route switchover of routes via eth-rt5 -# -def test_rt6_step14(): - logger.info("Test (step 14): verify IPv4/6 RIB and MPLS table") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - logger.info("Drop traffic between rt5 and rt6") - tgen.net.cmd_raises("ip link set s8 down") - - rname = "rt6" - + logger.info("Verifying if the BFD session is down") expect = ( - '[{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"down"}]' + '{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"down"}' ) router_compare_json_output( - rname, - "show bfd peers json", + "rt6", + "show bfd peer 10.0.8.5 json", expect, - count=40, - wait=0.5, ) - router_compare_json_output( - rname, - "show ip route isis json", - outputs[rname][11]["show_ip_route.ref"], - count=20, - ) - router_compare_json_output( - rname, - "show ipv6 route isis json", - outputs[rname][11]["show_ipv6_route.ref"], - count=20, - wait=2, - ) - router_compare_json_output( - rname, - "show mpls table json", - outputs[rname][11]["show_mpls_table.ref"], - count=20, - ) - - -# -# Step 15 -# -# Action(s): wait for the convergence and SPF computation on rt6 -# -# Expected changes: -# - convergence of IPv4/6 RIB and MPLS table -# -def test_rib_ipv4_step15(): - logger.info("Test (step 15): verify IPv4 RIB") - tgen = get_topogen() - - # Skip if previous fatal error condition is raised - if tgen.routers_have_failure(): - pytest.skip(tgen.errors) - - logger.info("Check SPF convergence") - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + for rname in ["rt5", "rt6"]: router_compare_json_output( - rname, - "show ip route isis json", - outputs[rname][12]["show_ip_route.ref"], + rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"] ) -def test_rib_ipv6_step15(): - logger.info("Test (step 15): verify IPv6 RIB") +def test_rib_ipv6_step10(): + logger.info("Test (step 10): verify IPv6 RIB") tgen = get_topogen() # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + for rname in ["rt5", "rt6"]: router_compare_json_output( rname, "show ipv6 route isis json", - outputs[rname][12]["show_ipv6_route.ref"], + outputs[rname][10]["show_ipv6_route.ref"], ) -def test_mpls_lib_step15(): - logger.info("Test (step 15): verify MPLS LIB") +def test_mpls_lib_step10(): + logger.info("Test (step 10): verify MPLS LIB") tgen = get_topogen() # Skip if previous fatal error condition is raised if tgen.routers_have_failure(): pytest.skip(tgen.errors) - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: + for rname in ["rt5", "rt6"]: router_compare_json_output( - rname, - "show mpls table json", - outputs[rname][12]["show_mpls_table.ref"], + rname, "show mpls table json", outputs[rname][10]["show_mpls_table.ref"] ) From dc354cbfefb1288c6eaf90e01ac4f97e75f4a93b Mon Sep 17 00:00:00 2001 From: Renato Westphal Date: Fri, 7 Jun 2024 12:03:17 -0300 Subject: [PATCH 233/472] tests: introduce method to update reference data in isis_tilfa_topo1 The isis_tilfa_topo1 topotest is comprehensive and contains a large amount of reference data. One problem is that, when changes occur, updating this reference data can be difficult. To address this problem, this commit introduces a method to automatically regenerate the reference data by setting the `REGEN_DATA` environment variable. Usage: $ REGEN_DATA=true python3 ./test_isis_tilfa_topo1.py When `REGEN_DATA` is set, the topotest regenerates reference data from the current run instead of comparing against existing reference data. Note that regenerated data must be manually verified for correctness. This commit also simplifies the reference data by replacing all diff files with complete JSON snapshots. Signed-off-by: Renato Westphal --- .../rt1/step1/show_mpls_table.ref | 18 +- .../show_yang_interface_isis_adjacencies.ref | 4 +- .../rt1/step2/show_ip_route.ref | 294 +++++++++ .../rt1/step2/show_ip_route.ref.diff | 0 .../rt1/step2/show_ipv6_route.ref | 121 ++++ .../rt1/step2/show_ipv6_route.ref.diff | 0 .../rt1/step2/show_mpls_table.ref | 140 +++++ .../rt1/step2/show_mpls_table.ref.diff | 0 .../rt1/step3/show_ip_route.ref | 294 +++++++++ .../rt1/step3/show_ip_route.ref.diff | 0 .../rt1/step3/show_ipv6_route.ref | 121 ++++ .../rt1/step3/show_ipv6_route.ref.diff | 0 .../rt1/step3/show_mpls_table.ref | 140 +++++ .../rt1/step3/show_mpls_table.ref.diff | 0 .../rt1/step4/show_ip_route.ref | 291 +++++++++ .../rt1/step4/show_ip_route.ref.diff | 14 - .../rt1/step4/show_ipv6_route.ref | 118 ++++ .../rt1/step4/show_ipv6_route.ref.diff | 14 - .../rt1/step4/show_mpls_table.ref | 115 ++++ .../rt1/step4/show_mpls_table.ref.diff | 33 - .../rt1/step5/show_ip_route.ref | 294 +++++++++ .../rt1/step5/show_ip_route.ref.diff | 14 - .../rt1/step5/show_ipv6_route.ref | 121 ++++ .../rt1/step5/show_ipv6_route.ref.diff | 14 - .../rt1/step5/show_mpls_table.ref | 140 +++++ .../rt1/step5/show_mpls_table.ref.diff | 33 - .../rt1/step6/show_ip_route.ref | 294 +++++++++ .../rt1/step6/show_ip_route.ref.diff | 0 .../rt1/step6/show_ipv6_route.ref | 121 ++++ .../rt1/step6/show_ipv6_route.ref.diff | 0 .../rt1/step6/show_mpls_table.ref | 140 +++++ .../rt1/step6/show_mpls_table.ref.diff | 0 .../rt1/step7/show_ip_route.ref | 291 +++++++++ .../rt1/step7/show_ip_route.ref.diff | 14 - .../rt1/step7/show_ipv6_route.ref | 118 ++++ .../rt1/step7/show_ipv6_route.ref.diff | 14 - .../rt1/step7/show_mpls_table.ref | 115 ++++ .../rt1/step7/show_mpls_table.ref.diff | 33 - .../rt1/step8/show_ip_route.ref | 294 +++++++++ .../rt1/step8/show_ip_route.ref.diff | 14 - .../rt1/step8/show_ipv6_route.ref | 121 ++++ .../rt1/step8/show_ipv6_route.ref.diff | 14 - .../rt1/step8/show_mpls_table.ref | 140 +++++ .../rt1/step8/show_mpls_table.ref.diff | 33 - .../rt1/step9/show_ip_route.ref | 294 +++++++++ .../rt1/step9/show_ip_route.ref.diff | 11 - .../rt1/step9/show_ipv6_route.ref | 121 ++++ .../rt1/step9/show_ipv6_route.ref.diff | 11 - .../rt1/step9/show_mpls_table.ref | 140 +++++ .../rt1/step9/show_mpls_table.ref.diff | 64 -- .../rt2/step1/show_ipv6_route.ref | 4 +- .../rt2/step1/show_mpls_table.ref | 39 +- .../rt2/step2/show_ip_route.ref | 447 ++++++++++++++ .../rt2/step2/show_ip_route.ref.diff | 169 ------ .../rt2/step2/show_ipv6_route.ref | 181 ++++++ .../rt2/step2/show_ipv6_route.ref.diff | 72 --- .../rt2/step2/show_mpls_table.ref | 233 ++++++++ .../rt2/step2/show_mpls_table.ref.diff | 102 ---- .../rt2/step3/show_ip_route.ref | 563 ++++++++++++++++++ .../rt2/step3/show_ip_route.ref.diff | 169 ------ .../rt2/step3/show_ipv6_route.ref | 229 +++++++ .../rt2/step3/show_ipv6_route.ref.diff | 72 --- .../rt2/step3/show_mpls_table.ref | 301 ++++++++++ .../rt2/step3/show_mpls_table.ref.diff | 102 ---- .../rt2/step4/show_ip_route.ref | 464 +++++++++++++++ .../rt2/step4/show_ip_route.ref.diff | 192 ------ .../rt2/step4/show_ipv6_route.ref | 162 +++++ .../rt2/step4/show_ipv6_route.ref.diff | 146 ----- .../rt2/step4/show_mpls_table.ref | 142 +++++ .../rt2/step4/show_mpls_table.ref.diff | 200 ------- .../rt2/step5/show_ip_route.ref | 563 ++++++++++++++++++ .../rt2/step5/show_ip_route.ref.diff | 192 ------ .../rt2/step5/show_ipv6_route.ref | 229 +++++++ .../rt2/step5/show_ipv6_route.ref.diff | 146 ----- .../rt2/step5/show_mpls_table.ref | 301 ++++++++++ .../rt2/step5/show_mpls_table.ref.diff | 200 ------- .../rt2/step6/show_ip_route.ref | 563 ++++++++++++++++++ .../rt2/step6/show_ip_route.ref.diff | 0 .../rt2/step6/show_ipv6_route.ref | 229 +++++++ .../rt2/step6/show_ipv6_route.ref.diff | 0 .../rt2/step6/show_mpls_table.ref | 301 ++++++++++ .../rt2/step6/show_mpls_table.ref.diff | 0 .../rt2/step7/show_ip_route.ref | 405 +++++++++++++ .../rt2/step7/show_ip_route.ref.diff | 288 --------- .../rt2/step7/show_ipv6_route.ref | 155 +++++ .../rt2/step7/show_ipv6_route.ref.diff | 139 ----- .../rt2/step7/show_mpls_table.ref | 155 +++++ .../rt2/step7/show_mpls_table.ref.diff | 207 ------- .../rt2/step8/show_ip_route.ref | 563 ++++++++++++++++++ .../rt2/step8/show_ip_route.ref.diff | 288 --------- .../rt2/step8/show_ipv6_route.ref | 229 +++++++ .../rt2/step8/show_ipv6_route.ref.diff | 139 ----- .../rt2/step8/show_mpls_table.ref | 301 ++++++++++ .../rt2/step8/show_mpls_table.ref.diff | 207 ------- .../rt2/step9/show_ip_route.ref | 563 ++++++++++++++++++ .../rt2/step9/show_ip_route.ref.diff | 119 ---- .../rt2/step9/show_ipv6_route.ref | 229 +++++++ .../rt2/step9/show_ipv6_route.ref.diff | 74 --- .../rt2/step9/show_mpls_table.ref | 301 ++++++++++ .../rt2/step9/show_mpls_table.ref.diff | 182 ------ .../rt3/step1/show_ipv6_route.ref | 14 +- .../rt3/step1/show_mpls_table.ref | 39 +- .../show_yang_interface_isis_adjacencies.ref | 8 +- .../rt3/step2/show_ip_route.ref | 563 ++++++++++++++++++ .../rt3/step2/show_ip_route.ref.diff | 0 .../rt3/step2/show_ipv6_route.ref | 229 +++++++ .../rt3/step2/show_ipv6_route.ref.diff | 0 .../rt3/step2/show_mpls_table.ref | 301 ++++++++++ .../rt3/step2/show_mpls_table.ref.diff | 0 .../rt3/step3/show_ip_route.ref | 563 ++++++++++++++++++ .../rt3/step3/show_ip_route.ref.diff | 0 .../rt3/step3/show_ipv6_route.ref | 229 +++++++ .../rt3/step3/show_ipv6_route.ref.diff | 0 .../rt3/step3/show_mpls_table.ref | 301 ++++++++++ .../rt3/step3/show_mpls_table.ref.diff | 0 .../rt3/step4/show_ip_route.ref | 405 +++++++++++++ .../rt3/step4/show_ip_route.ref.diff | 288 --------- .../rt3/step4/show_ipv6_route.ref | 155 +++++ .../rt3/step4/show_ipv6_route.ref.diff | 139 ----- .../rt3/step4/show_mpls_table.ref | 155 +++++ .../rt3/step4/show_mpls_table.ref.diff | 206 ------- .../rt3/step5/show_ip_route.ref | 563 ++++++++++++++++++ .../rt3/step5/show_ip_route.ref.diff | 288 --------- .../rt3/step5/show_ipv6_route.ref | 229 +++++++ .../rt3/step5/show_ipv6_route.ref.diff | 139 ----- .../rt3/step5/show_mpls_table.ref | 301 ++++++++++ .../rt3/step5/show_mpls_table.ref.diff | 206 ------- .../rt3/step6/show_ip_route.ref | 563 ++++++++++++++++++ .../rt3/step6/show_ip_route.ref.diff | 101 ---- .../rt3/step6/show_ipv6_route.ref | 229 +++++++ .../rt3/step6/show_ipv6_route.ref.diff | 83 --- .../rt3/step6/show_mpls_table.ref | 301 ++++++++++ .../rt3/step6/show_mpls_table.ref.diff | 130 ---- .../rt3/step7/show_ip_route.ref | 556 +++++++++++++++++ .../rt3/step7/show_ip_route.ref.diff | 32 - .../rt3/step7/show_ipv6_route.ref | 222 +++++++ .../rt3/step7/show_ipv6_route.ref.diff | 32 - .../rt3/step7/show_mpls_table.ref | 236 ++++++++ .../rt3/step7/show_mpls_table.ref.diff | 71 --- .../rt3/step8/show_ip_route.ref | 563 ++++++++++++++++++ .../rt3/step8/show_ip_route.ref.diff | 32 - .../rt3/step8/show_ipv6_route.ref | 229 +++++++ .../rt3/step8/show_ipv6_route.ref.diff | 32 - .../rt3/step8/show_mpls_table.ref | 301 ++++++++++ .../rt3/step8/show_mpls_table.ref.diff | 71 --- .../rt3/step9/show_ip_route.ref | 563 ++++++++++++++++++ .../rt3/step9/show_ip_route.ref.diff | 11 - .../rt3/step9/show_ipv6_route.ref | 229 +++++++ .../rt3/step9/show_ipv6_route.ref.diff | 11 - .../rt3/step9/show_mpls_table.ref | 301 ++++++++++ .../rt3/step9/show_mpls_table.ref.diff | 133 ----- .../rt4/step1/show_ipv6_route.ref | 12 +- .../rt4/step1/show_mpls_table.ref | 27 +- .../rt4/step2/show_ip_route.ref | 506 ++++++++++++++++ .../rt4/step2/show_ip_route.ref.diff | 0 .../rt4/step2/show_ipv6_route.ref | 207 +++++++ .../rt4/step2/show_ipv6_route.ref.diff | 0 .../rt4/step2/show_mpls_table.ref | 275 +++++++++ .../rt4/step2/show_mpls_table.ref.diff | 0 .../rt4/step3/show_ip_route.ref | 506 ++++++++++++++++ .../rt4/step3/show_ip_route.ref.diff | 0 .../rt4/step3/show_ipv6_route.ref | 207 +++++++ .../rt4/step3/show_ipv6_route.ref.diff | 0 .../rt4/step3/show_mpls_table.ref | 275 +++++++++ .../rt4/step3/show_mpls_table.ref.diff | 0 .../rt4/step4/show_ip_route.ref | 296 +++++++++ .../rt4/step4/show_ip_route.ref.diff | 367 ------------ .../rt4/step4/show_ipv6_route.ref | 121 ++++ .../rt4/step4/show_ipv6_route.ref.diff | 161 ----- .../rt4/step4/show_mpls_table.ref | 1 + .../rt4/step4/show_mpls_table.ref.diff | 265 --------- .../rt4/step5/show_ip_route.ref | 506 ++++++++++++++++ .../rt4/step5/show_ip_route.ref.diff | 367 ------------ .../rt4/step5/show_ipv6_route.ref | 207 +++++++ .../rt4/step5/show_ipv6_route.ref.diff | 161 ----- .../rt4/step5/show_mpls_table.ref | 275 +++++++++ .../rt4/step5/show_mpls_table.ref.diff | 265 --------- .../rt4/step6/show_ip_route.ref | 506 ++++++++++++++++ .../rt4/step6/show_ip_route.ref.diff | 56 -- .../rt4/step6/show_ipv6_route.ref | 207 +++++++ .../rt4/step6/show_ipv6_route.ref.diff | 38 -- .../rt4/step6/show_mpls_table.ref | 275 +++++++++ .../rt4/step6/show_mpls_table.ref.diff | 74 --- .../rt4/step7/show_ip_route.ref | 500 ++++++++++++++++ .../rt4/step7/show_ip_route.ref.diff | 24 - .../rt4/step7/show_ipv6_route.ref | 201 +++++++ .../rt4/step7/show_ipv6_route.ref.diff | 24 - .../rt4/step7/show_mpls_table.ref | 229 +++++++ .../rt4/step7/show_mpls_table.ref.diff | 53 -- .../rt4/step8/show_ip_route.ref | 506 ++++++++++++++++ .../rt4/step8/show_ip_route.ref.diff | 24 - .../rt4/step8/show_ipv6_route.ref | 207 +++++++ .../rt4/step8/show_ipv6_route.ref.diff | 24 - .../rt4/step8/show_mpls_table.ref | 275 +++++++++ .../rt4/step8/show_mpls_table.ref.diff | 53 -- .../rt4/step9/show_ip_route.ref | 506 ++++++++++++++++ .../rt4/step9/show_ip_route.ref.diff | 11 - .../rt4/step9/show_ipv6_route.ref | 207 +++++++ .../rt4/step9/show_ipv6_route.ref.diff | 11 - .../rt4/step9/show_mpls_table.ref | 275 +++++++++ .../rt4/step9/show_mpls_table.ref.diff | 110 ---- .../rt5/step1/show_ipv6_route.ref | 12 +- .../rt5/step1/show_mpls_table.ref | 27 +- .../rt5/step10/show_ip_route.ref | 4 + .../rt5/step10/show_ipv6_route.ref | 39 +- .../rt5/step2/show_ip_route.ref | 506 ++++++++++++++++ .../rt5/step2/show_ip_route.ref.diff | 0 .../rt5/step2/show_ipv6_route.ref | 207 +++++++ .../rt5/step2/show_ipv6_route.ref.diff | 0 .../rt5/step2/show_mpls_table.ref | 275 +++++++++ .../rt5/step2/show_mpls_table.ref.diff | 0 .../rt5/step3/show_ip_route.ref | 506 ++++++++++++++++ .../rt5/step3/show_ip_route.ref.diff | 0 .../rt5/step3/show_ipv6_route.ref | 207 +++++++ .../rt5/step3/show_ipv6_route.ref.diff | 0 .../rt5/step3/show_mpls_table.ref | 275 +++++++++ .../rt5/step3/show_mpls_table.ref.diff | 0 .../rt5/step4/show_ip_route.ref | 439 ++++++++++++++ .../rt5/step4/show_ip_route.ref.diff | 161 ----- .../rt5/step4/show_ipv6_route.ref | 175 ++++++ .../rt5/step4/show_ipv6_route.ref.diff | 95 --- .../rt5/step4/show_mpls_table.ref | 189 ++++++ .../rt5/step4/show_mpls_table.ref.diff | 166 ------ .../rt5/step5/show_ip_route.ref | 506 ++++++++++++++++ .../rt5/step5/show_ip_route.ref.diff | 161 ----- .../rt5/step5/show_ipv6_route.ref | 207 +++++++ .../rt5/step5/show_ipv6_route.ref.diff | 95 --- .../rt5/step5/show_mpls_table.ref | 275 +++++++++ .../rt5/step5/show_mpls_table.ref.diff | 166 ------ .../rt5/step6/show_ip_route.ref | 506 ++++++++++++++++ .../rt5/step6/show_ip_route.ref.diff | 0 .../rt5/step6/show_ipv6_route.ref | 207 +++++++ .../rt5/step6/show_ipv6_route.ref.diff | 0 .../rt5/step6/show_mpls_table.ref | 275 +++++++++ .../rt5/step6/show_mpls_table.ref.diff | 146 ----- .../rt5/step7/show_ip_route.ref | 506 ++++++++++++++++ .../rt5/step7/show_ip_route.ref.diff | 0 .../rt5/step7/show_ipv6_route.ref | 207 +++++++ .../rt5/step7/show_ipv6_route.ref.diff | 0 .../rt5/step7/show_mpls_table.ref | 275 +++++++++ .../rt5/step7/show_mpls_table.ref.diff | 0 .../rt5/step8/show_ip_route.ref | 506 ++++++++++++++++ .../rt5/step8/show_ip_route.ref.diff | 0 .../rt5/step8/show_ipv6_route.ref | 207 +++++++ .../rt5/step8/show_ipv6_route.ref.diff | 0 .../rt5/step8/show_mpls_table.ref | 275 +++++++++ .../rt5/step8/show_mpls_table.ref.diff | 0 .../rt5/step9/show_ip_route.ref | 506 ++++++++++++++++ .../rt5/step9/show_ip_route.ref.diff | 0 .../rt5/step9/show_ipv6_route.ref | 207 +++++++ .../rt5/step9/show_ipv6_route.ref.diff | 0 .../rt5/step9/show_mpls_table.ref | 275 +++++++++ .../rt5/step9/show_mpls_table.ref.diff | 0 .../rt6/step1/show_ipv6_route.ref | 4 +- .../rt6/step1/show_mpls_table.ref | 22 +- .../rt6/step10/show_ipv6_route.ref | 35 ++ .../rt6/step2/show_ip_route.ref | 413 +++++++++++++ .../rt6/step2/show_ip_route.ref.diff | 0 .../rt6/step2/show_ipv6_route.ref | 173 ++++++ .../rt6/step2/show_ipv6_route.ref.diff | 0 .../rt6/step2/show_mpls_table.ref | 224 +++++++ .../rt6/step2/show_mpls_table.ref.diff | 0 .../rt6/step3/show_ip_route.ref | 413 +++++++++++++ .../rt6/step3/show_ip_route.ref.diff | 0 .../rt6/step3/show_ipv6_route.ref | 173 ++++++ .../rt6/step3/show_ipv6_route.ref.diff | 0 .../rt6/step3/show_mpls_table.ref | 224 +++++++ .../rt6/step3/show_mpls_table.ref.diff | 0 .../rt6/step4/show_ip_route.ref | 395 ++++++++++++ .../rt6/step4/show_ip_route.ref.diff | 70 --- .../rt6/step4/show_ipv6_route.ref | 155 +++++ .../rt6/step4/show_ipv6_route.ref.diff | 70 --- .../rt6/step4/show_mpls_table.ref | 165 +++++ .../rt6/step4/show_mpls_table.ref.diff | 109 ---- .../rt6/step5/show_ip_route.ref | 413 +++++++++++++ .../rt6/step5/show_ip_route.ref.diff | 70 --- .../rt6/step5/show_ipv6_route.ref | 173 ++++++ .../rt6/step5/show_ipv6_route.ref.diff | 70 --- .../rt6/step5/show_mpls_table.ref | 224 +++++++ .../rt6/step5/show_mpls_table.ref.diff | 112 ---- .../rt6/step6/show_ip_route.ref | 413 +++++++++++++ .../rt6/step6/show_ip_route.ref.diff | 38 -- .../rt6/step6/show_ipv6_route.ref | 173 ++++++ .../rt6/step6/show_ipv6_route.ref.diff | 38 -- .../rt6/step6/show_mpls_table.ref | 224 +++++++ .../rt6/step6/show_mpls_table.ref.diff | 74 --- .../rt6/step7/show_ip_route.ref | 407 +++++++++++++ .../rt6/step7/show_ip_route.ref.diff | 24 - .../rt6/step7/show_ipv6_route.ref | 167 ++++++ .../rt6/step7/show_ipv6_route.ref.diff | 24 - .../rt6/step7/show_mpls_table.ref | 178 ++++++ .../rt6/step7/show_mpls_table.ref.diff | 52 -- .../rt6/step8/show_ip_route.ref | 413 +++++++++++++ .../rt6/step8/show_ip_route.ref.diff | 24 - .../rt6/step8/show_ipv6_route.ref | 173 ++++++ .../rt6/step8/show_ipv6_route.ref.diff | 24 - .../rt6/step8/show_mpls_table.ref | 224 +++++++ .../rt6/step8/show_mpls_table.ref.diff | 52 -- .../rt6/step9/show_ip_route.ref | 413 +++++++++++++ .../rt6/step9/show_ip_route.ref.diff | 11 - .../rt6/step9/show_ipv6_route.ref | 173 ++++++ .../rt6/step9/show_ipv6_route.ref.diff | 11 - .../rt6/step9/show_mpls_table.ref | 224 +++++++ .../rt6/step9/show_mpls_table.ref.diff | 39 -- .../isis_tilfa_topo1/test_isis_tilfa_topo1.py | 291 ++++++--- 305 files changed, 42189 insertions(+), 9936 deletions(-) create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step2/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step2/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step2/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step2/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step2/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step2/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step3/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step3/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step3/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step3/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step3/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step3/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step6/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step6/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step6/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step6/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step6/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step6/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step6/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step6/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step6/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step6/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step6/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step6/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step2/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step2/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step2/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step2/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step2/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step2/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step3/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step3/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step3/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step3/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step3/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step3/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step2/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step2/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step2/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step2/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step2/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step2/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step3/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step3/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step3/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step3/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step3/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step3/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step2/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step2/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step2/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step2/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step2/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step2/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step3/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step3/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step3/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step3/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step3/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step3/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step6/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step6/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step6/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step6/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step7/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step7/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step7/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step7/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step7/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step7/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step8/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step8/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step8/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step8/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step8/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step8/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step9/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step9/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step9/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step9/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step9/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt5/step9/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step2/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step2/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step2/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step2/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step2/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step2/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step3/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step3/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step3/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step3/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step3/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step3/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref.diff create mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref delete mode 100644 tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref.diff diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step1/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step1/show_mpls_table.ref index aa0357d75000..f73b22d9d035 100644 --- a/tests/topotests/isis_tilfa_topo1/rt1/step1/show_mpls_table.ref +++ b/tests/topotests/isis_tilfa_topo1/rt1/step1/show_mpls_table.ref @@ -7,7 +7,8 @@ "type":"SR (IS-IS)", "outLabel":3, "installed":true, - "nexthop":"10.0.1.2" + "nexthop":"10.0.1.2", + "interface":"eth-sw1" } ] }, @@ -31,7 +32,8 @@ "type":"SR (IS-IS)", "outLabel":3, "installed":true, - "nexthop":"10.0.1.3" + "nexthop":"10.0.1.3", + "interface":"eth-sw1" } ] }, @@ -55,7 +57,8 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.1.2" + "nexthop":"10.0.1.2", + "interface":"eth-sw1" } ] }, @@ -79,7 +82,8 @@ "type":"SR (IS-IS)", "outLabel":16050, "installed":true, - "nexthop":"10.0.1.3" + "nexthop":"10.0.1.3", + "interface":"eth-sw1" } ] }, @@ -103,13 +107,15 @@ "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.1.3" + "nexthop":"10.0.1.3", + "interface":"eth-sw1" }, { "type":"SR (IS-IS)", "outLabel":16060, "installed":true, - "nexthop":"10.0.1.2" + "nexthop":"10.0.1.2", + "interface":"eth-sw1" } ] }, diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis_tilfa_topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref index 9c5901b90ff1..fcef68cfe3df 100644 --- a/tests/topotests/isis_tilfa_topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis_tilfa_topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref @@ -10,14 +10,14 @@ "adjacency": [ { "neighbor-sys-type": "level-1", - "neighbor-sysid": "0000.0000.0003", + "neighbor-sysid": "0000.0000.0002", "hold-timer": 10, "neighbor-priority": 64, "state": "up" }, { "neighbor-sys-type": "level-1", - "neighbor-sysid": "0000.0000.0002", + "neighbor-sysid": "0000.0000.0003", "hold-timer": 10, "neighbor-priority": 64, "state": "up" diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ip_route.ref new file mode 100644 index 000000000000..92b7437324a6 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ip_route.ref @@ -0,0 +1,294 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ipv6_route.ref new file mode 100644 index 000000000000..3232121a0fce --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step2/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_mpls_table.ref new file mode 100644 index 000000000000..f73b22d9d035 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_mpls_table.ref @@ -0,0 +1,140 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step2/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step2/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ip_route.ref new file mode 100644 index 000000000000..92b7437324a6 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ip_route.ref @@ -0,0 +1,294 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ipv6_route.ref new file mode 100644 index 000000000000..3232121a0fce --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step3/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_mpls_table.ref new file mode 100644 index 000000000000..f73b22d9d035 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_mpls_table.ref @@ -0,0 +1,140 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step3/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step3/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref new file mode 100644 index 000000000000..89e0b166b1e1 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref @@ -0,0 +1,291 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref.diff deleted file mode 100644 index 10b336f5b812..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ip_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step3/show_ip_route.ref -+++ b/rt1/step4/show_ip_route.ref -@@ -60,10 +60,7 @@ - "ip":"10.0.1.2", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref new file mode 100644 index 000000000000..0358d5d6fcfc --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref @@ -0,0 +1,118 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref.diff deleted file mode 100644 index 904aaa1ce2a1..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_ipv6_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step3/show_ipv6_route.ref -+++ b/rt1/step4/show_ipv6_route.ref -@@ -57,10 +57,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16041 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref new file mode 100644 index 000000000000..d587d4203d55 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref @@ -0,0 +1,115 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref.diff deleted file mode 100644 index d7d875313105..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step4/show_mpls_table.ref.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- a/rt1/step3/show_mpls_table.ref -+++ b/rt1/step4/show_mpls_table.ref -@@ -47,30 +47,6 @@ - } - ] - }, -- "16040":{ -- "inLabel":16040, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "installed":true, -- "nexthop":"10.0.1.2" -- } -- ] -- }, -- "16041":{ -- "inLabel":16041, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "installed":true, -- "interface":"eth-sw1" -- } -- ] -- }, - "16050":{ - "inLabel":16050, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref new file mode 100644 index 000000000000..92b7437324a6 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref @@ -0,0 +1,294 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref.diff deleted file mode 100644 index b583fa97bde2..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ip_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step4/show_ip_route.ref -+++ b/rt1/step5/show_ip_route.ref -@@ -60,7 +60,10 @@ - "ip":"10.0.1.2", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref new file mode 100644 index 000000000000..3232121a0fce --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref.diff deleted file mode 100644 index d608abec9820..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_ipv6_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step4/show_ipv6_route.ref -+++ b/rt1/step5/show_ipv6_route.ref -@@ -57,7 +57,10 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16041 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref new file mode 100644 index 000000000000..f73b22d9d035 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref @@ -0,0 +1,140 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref.diff deleted file mode 100644 index b5161fcd55ba..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step5/show_mpls_table.ref.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- a/rt1/step4/show_mpls_table.ref -+++ b/rt1/step5/show_mpls_table.ref -@@ -47,6 +47,30 @@ - } - ] - }, -+ "16040":{ -+ "inLabel":16040, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "installed":true, -+ "nexthop":"10.0.1.2" -+ } -+ ] -+ }, -+ "16041":{ -+ "inLabel":16041, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "installed":true, -+ "interface":"eth-sw1" -+ } -+ ] -+ }, - "16050":{ - "inLabel":16050, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ip_route.ref new file mode 100644 index 000000000000..92b7437324a6 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ip_route.ref @@ -0,0 +1,294 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ipv6_route.ref new file mode 100644 index 000000000000..3232121a0fce --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step6/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_mpls_table.ref new file mode 100644 index 000000000000..f73b22d9d035 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_mpls_table.ref @@ -0,0 +1,140 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step6/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step6/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref new file mode 100644 index 000000000000..270fcef5d60d --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref @@ -0,0 +1,291 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref.diff deleted file mode 100644 index 726aed514fe2..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ip_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step6/show_ip_route.ref -+++ b/rt1/step7/show_ip_route.ref -@@ -83,10 +83,7 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref new file mode 100644 index 000000000000..7ded014425c3 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref @@ -0,0 +1,118 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref.diff deleted file mode 100644 index 2049f6fa190a..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_ipv6_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step6/show_ipv6_route.ref -+++ b/rt1/step7/show_ipv6_route.ref -@@ -79,10 +79,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref new file mode 100644 index 000000000000..b4ba438bf737 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref @@ -0,0 +1,115 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref.diff deleted file mode 100644 index 22301ba1ff87..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step7/show_mpls_table.ref.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- a/rt1/step6/show_mpls_table.ref -+++ b/rt1/step7/show_mpls_table.ref -@@ -71,30 +71,6 @@ - } - ] - }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.1.3" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, -- "interface":"eth-sw1" -- } -- ] -- }, - "16060":{ - "inLabel":16060, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref new file mode 100644 index 000000000000..92b7437324a6 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref @@ -0,0 +1,294 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref.diff deleted file mode 100644 index 4a1d4805a4e7..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ip_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step7/show_ip_route.ref -+++ b/rt1/step8/show_ip_route.ref -@@ -83,7 +83,10 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref new file mode 100644 index 000000000000..3232121a0fce --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref.diff deleted file mode 100644 index eaece74e48b6..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_ipv6_route.ref.diff +++ /dev/null @@ -1,14 +0,0 @@ ---- a/rt1/step7/show_ipv6_route.ref -+++ b/rt1/step8/show_ipv6_route.ref -@@ -79,7 +79,10 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref new file mode 100644 index 000000000000..f73b22d9d035 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref @@ -0,0 +1,140 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref.diff deleted file mode 100644 index 46c17de01915..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step8/show_mpls_table.ref.diff +++ /dev/null @@ -1,33 +0,0 @@ ---- a/rt1/step7/show_mpls_table.ref -+++ b/rt1/step8/show_mpls_table.ref -@@ -71,6 +71,30 @@ - } - ] - }, -+ "16050":{ -+ "inLabel":16050, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "installed":true, -+ "nexthop":"10.0.1.3" -+ } -+ ] -+ }, -+ "16051":{ -+ "inLabel":16051, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "installed":true, -+ "interface":"eth-sw1" -+ } -+ ] -+ }, - "16060":{ - "inLabel":16060, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref new file mode 100644 index 000000000000..841c902a37df --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref @@ -0,0 +1,294 @@ +{ + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref.diff deleted file mode 100644 index 06efdc96ce59..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ip_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt1/step8/show_ip_route.ref -+++ b/rt1/step9/show_ip_route.ref -@@ -85,7 +85,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref new file mode 100644 index 000000000000..4d35cf1d9ee3 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16501 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref.diff deleted file mode 100644 index a58f2d447cd6..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_ipv6_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt1/step8/show_ipv6_route.ref -+++ b/rt1/step9/show_ipv6_route.ref -@@ -81,7 +81,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16051 -+ 16501 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref new file mode 100644 index 000000000000..dc64494aa289 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref @@ -0,0 +1,140 @@ +{ + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16500":{ + "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16501":{ + "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "installed":true, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref.diff deleted file mode 100644 index c0a1ac592b51..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt1/step9/show_mpls_table.ref.diff +++ /dev/null @@ -1,64 +0,0 @@ ---- a/rt1/step8/show_mpls_table.ref -+++ b/rt1/step9/show_mpls_table.ref -@@ -71,30 +71,6 @@ - } - ] - }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.1.3" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, -- "interface":"eth-sw1" -- } -- ] -- }, - "16060":{ - "inLabel":16060, - "installed":true, -@@ -129,6 +105,30 @@ - "installed":true, - "interface":"eth-sw1" - } -+ ] -+ }, -+ "16500":{ -+ "inLabel":16500, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16500, -+ "installed":true, -+ "nexthop":"10.0.1.3" -+ } -+ ] -+ }, -+ "16501":{ -+ "inLabel":16501, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16501, -+ "installed":true, -+ "interface":"eth-sw1" -+ } - ] - } - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step1/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step1/show_ipv6_route.ref index 6d31f6f26b8b..95432310fd4c 100644 --- a/tests/topotests/isis_tilfa_topo1/rt2/step1/show_ipv6_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt2/step1/show_ipv6_route.ref @@ -152,7 +152,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4-1", + "interfaceName":"eth-sw1", "active":true, "labels":[ 16051 @@ -161,7 +161,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-sw1", + "interfaceName":"eth-rt4-1", "active":true, "labels":[ 16051 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step1/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step1/show_mpls_table.ref index b9b906a31d9c..8580cb0e7c0c 100644 --- a/tests/topotests/isis_tilfa_topo1/rt2/step1/show_mpls_table.ref +++ b/tests/topotests/isis_tilfa_topo1/rt2/step1/show_mpls_table.ref @@ -8,6 +8,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.1.1", + "interface":"eth-sw1", "backupIndex":[ 0, 1 @@ -18,12 +19,14 @@ { "type":"SR (IS-IS)", "outLabel":16050, - "nexthop":"10.0.2.4" + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16050, - "nexthop":"10.0.3.4" + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" } ] }, @@ -64,6 +67,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.1.3", + "interface":"eth-sw1", "backupIndex":[ 0, 1 @@ -74,12 +78,14 @@ { "type":"SR (IS-IS)", "outLabel":16050, - "nexthop":"10.0.2.4" + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" }, { "type":"SR (IS-IS)", "outLabel":16050, - "nexthop":"10.0.3.4" + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" } ] }, @@ -120,6 +126,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", "backupIndex":[ 0 ] @@ -129,6 +136,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", "backupIndex":[ 0 ] @@ -138,7 +146,8 @@ { "type":"SR (IS-IS)", "outLabel":16050, - "nexthop":"10.0.1.3" + "nexthop":"10.0.1.3", + "interface":"eth-sw1" } ] }, @@ -181,19 +190,22 @@ "type":"SR (IS-IS)", "outLabel":16050, "installed":true, - "nexthop":"10.0.3.4" + "nexthop":"10.0.1.3", + "interface":"eth-sw1" }, { "type":"SR (IS-IS)", "outLabel":16050, "installed":true, - "nexthop":"10.0.2.4" + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" }, { "type":"SR (IS-IS)", "outLabel":16050, "installed":true, - "nexthop":"10.0.1.3" + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" } ] }, @@ -205,19 +217,19 @@ "type":"SR (IS-IS)", "outLabel":16051, "installed":true, - "interface":"eth-rt4-2" + "interface":"eth-sw1" }, { "type":"SR (IS-IS)", "outLabel":16051, "installed":true, - "interface":"eth-rt4-1" + "interface":"eth-rt4-2" }, { "type":"SR (IS-IS)", "outLabel":16051, "installed":true, - "interface":"eth-sw1" + "interface":"eth-rt4-1" } ] }, @@ -230,6 +242,7 @@ "outLabel":16060, "installed":true, "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", "backupIndex":[ 0 ] @@ -239,6 +252,7 @@ "outLabel":16060, "installed":true, "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", "backupIndex":[ 0 ] @@ -248,7 +262,8 @@ { "type":"SR (IS-IS)", "outLabel":16060, - "nexthop":"10.0.1.3" + "nexthop":"10.0.1.3", + "interface":"eth-sw1" } ] }, diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref new file mode 100644 index 000000000000..374eec7d508a --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref @@ -0,0 +1,447 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050, + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref.diff deleted file mode 100644 index 90e0895639b2..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ip_route.ref.diff +++ /dev/null @@ -1,169 +0,0 @@ ---- a/rt2/step1/show_ip_route.ref -+++ b/rt2/step2/show_ip_route.ref -@@ -15,36 +15,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050, -- 16010 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050, -- 16010 -- ] -- } - ] - } - ], -@@ -64,36 +38,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050, -- 16030 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050, -- 16030 -- ] -- } - ] - } - ], -@@ -251,40 +199,12 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -+ "interfaceName":"eth-sw1" - }, - { - "ip":"10.0.1.3", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "interfaceName":"eth-sw1" - } - ] - } -@@ -380,24 +300,6 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true, -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", - "active":true - } - ] -@@ -418,24 +320,6 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true, -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", - "active":true - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref new file mode 100644 index 000000000000..ca4f96f0d043 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref @@ -0,0 +1,181 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref.diff deleted file mode 100644 index 2d19f20f633f..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_ipv6_route.ref.diff +++ /dev/null @@ -1,72 +0,0 @@ ---- a/rt2/step1/show_ipv6_route.ref -+++ b/rt2/step2/show_ipv6_route.ref -@@ -14,34 +14,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051, -- 16011 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051, -- 16011 -- ] -- } - ] - } - ], -@@ -60,34 +36,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051, -- 16031 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051, -- 16031 -- ] -- } - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref new file mode 100644 index 000000000000..7b48e861f076 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref @@ -0,0 +1,233 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref.diff deleted file mode 100644 index 01fc74a60b75..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step2/show_mpls_table.ref.diff +++ /dev/null @@ -1,102 +0,0 @@ ---- a/rt2/step1/show_mpls_table.ref -+++ b/rt2/step2/show_mpls_table.ref -@@ -7,23 +7,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.3.4" -+ "nexthop":"10.0.1.1" - } - ] - }, -@@ -35,23 +19,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-2" -+ "interface":"eth-sw1" - } - ] - }, -@@ -63,23 +31,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.3", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.3.4" -+ "nexthop":"10.0.1.3" - } - ] - }, -@@ -91,23 +43,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-2" -+ "interface":"eth-sw1" - } - ] - }, diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref new file mode 100644 index 000000000000..7e1ccd10a2b7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16010 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16010 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16030 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050, + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref.diff deleted file mode 100644 index d93f03622910..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ip_route.ref.diff +++ /dev/null @@ -1,169 +0,0 @@ ---- a/rt2/step2/show_ip_route.ref -+++ b/rt2/step3/show_ip_route.ref -@@ -15,10 +15,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16010 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16010 -+ ] -+ } - ] - } - ], -@@ -38,10 +64,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16030 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16030 -+ ] -+ } - ] - } - ], -@@ -199,12 +251,40 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] - }, - { - "ip":"10.0.1.3", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } -@@ -300,6 +380,24 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -+ "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", - "active":true - } - ] -@@ -320,6 +418,24 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -+ "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", - "active":true - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref new file mode 100644 index 000000000000..95432310fd4c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16031 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref.diff deleted file mode 100644 index 68b618e91db7..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_ipv6_route.ref.diff +++ /dev/null @@ -1,72 +0,0 @@ ---- a/rt2/step2/show_ipv6_route.ref -+++ b/rt2/step3/show_ipv6_route.ref -@@ -14,10 +14,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16011 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16011 -+ ] -+ } - ] - } - ], -@@ -36,10 +60,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16031 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16031 -+ ] -+ } - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref new file mode 100644 index 000000000000..8580cb0e7c0c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref.diff deleted file mode 100644 index 966e153a6b6a..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step3/show_mpls_table.ref.diff +++ /dev/null @@ -1,102 +0,0 @@ ---- a/rt2/step2/show_mpls_table.ref -+++ b/rt2/step3/show_mpls_table.ref -@@ -7,7 +7,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1" -+ "nexthop":"10.0.1.1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.3.4" - } - ] - }, -@@ -19,7 +35,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1" -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-2" - } - ] - }, -@@ -31,7 +63,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.3" -+ "nexthop":"10.0.1.3", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.3.4" - } - ] - }, -@@ -43,7 +91,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1" -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-2" - } - ] - }, diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref new file mode 100644 index 000000000000..c5fc51b8628a --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref @@ -0,0 +1,464 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref.diff deleted file mode 100644 index dd75d76b9bca..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ip_route.ref.diff +++ /dev/null @@ -1,192 +0,0 @@ ---- a/rt2/step3/show_ip_route.ref -+++ b/rt2/step4/show_ip_route.ref -@@ -15,36 +15,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050, -- 16010 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050, -- 16010 -- ] -- } - ] - } - ], -@@ -64,36 +38,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050, -- 16030 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050, -- 16030 -- ] -- } - ] - } - ], -@@ -115,9 +63,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - }, - { -@@ -128,9 +73,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -141,8 +83,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050, -- 16040 -+ 16050 - ] - } - ] -@@ -173,20 +114,14 @@ - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } -@@ -209,9 +144,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 16060 - ] - }, - { -@@ -222,9 +154,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 16060 - ] - } - ], -@@ -251,40 +180,12 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -+ "interfaceName":"eth-sw1" - }, - { - "ip":"10.0.1.3", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "interfaceName":"eth-sw1" - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref new file mode 100644 index 000000000000..22bec0fa8c17 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref @@ -0,0 +1,162 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref.diff deleted file mode 100644 index 63731237ecb6..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_ipv6_route.ref.diff +++ /dev/null @@ -1,146 +0,0 @@ ---- a/rt2/step3/show_ipv6_route.ref -+++ b/rt2/step4/show_ipv6_route.ref -@@ -14,34 +14,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051, -- 16011 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051, -- 16011 -- ] -- } - ] - } - ], -@@ -60,34 +36,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051, -- 16031 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051, -- 16031 -- ] -- } - ] - } - ], -@@ -108,9 +60,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - }, - { -@@ -120,9 +69,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -132,8 +78,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16051, -- 16041 -+ 16051 - ] - } - ] -@@ -153,10 +98,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - }, - { - "fib":true, -@@ -171,10 +113,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - } - ] - } -@@ -196,9 +135,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 16061 - ] - }, - { -@@ -208,9 +144,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 16061 - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref new file mode 100644 index 000000000000..67f2b532b532 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref @@ -0,0 +1,142 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref.diff deleted file mode 100644 index 3872ce4980de..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step4/show_mpls_table.ref.diff +++ /dev/null @@ -1,200 +0,0 @@ ---- a/rt2/step3/show_mpls_table.ref -+++ b/rt2/step4/show_mpls_table.ref -@@ -7,23 +7,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.3.4" -+ "nexthop":"10.0.1.1" - } - ] - }, -@@ -35,23 +19,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-2" -+ "interface":"eth-sw1" - } - ] - }, -@@ -63,23 +31,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.3", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.3.4" -+ "nexthop":"10.0.1.3" - } - ] - }, -@@ -91,84 +43,6 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-2" -- } -- ] -- }, -- "16040":{ -- "inLabel":16040, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.3.4", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.2.4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.1.3" -- } -- ] -- }, -- "16041":{ -- "inLabel":16041, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt4-2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt4-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, - "interface":"eth-sw1" - } - ] -@@ -181,18 +55,6 @@ - "type":"SR (IS-IS)", - "outLabel":16050, - "installed":true, -- "nexthop":"10.0.3.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, - "nexthop":"10.0.1.3" - } - ] -@@ -204,18 +66,6 @@ - { - "type":"SR (IS-IS)", - "outLabel":16051, -- "installed":true, -- "interface":"eth-rt4-2" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, - "installed":true, - "interface":"eth-sw1" - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref new file mode 100644 index 000000000000..7e1ccd10a2b7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16010 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16010 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16030 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050, + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref.diff deleted file mode 100644 index 4d5636436ca8..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ip_route.ref.diff +++ /dev/null @@ -1,192 +0,0 @@ ---- a/rt2/step4/show_ip_route.ref -+++ b/rt2/step5/show_ip_route.ref -@@ -15,10 +15,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16010 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16010 -+ ] -+ } - ] - } - ], -@@ -38,10 +64,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16030 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16030 -+ ] -+ } - ] - } - ], -@@ -63,6 +115,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - }, - { -@@ -73,6 +128,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -83,7 +141,8 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050 -+ 16050, -+ 16040 - ] - } - ] -@@ -114,14 +173,20 @@ - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - }, - { - "fib":true, - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } -@@ -144,6 +209,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 16060 - ] - }, - { -@@ -154,6 +222,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 16060 - ] - } - ], -@@ -180,12 +251,40 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] - }, - { - "ip":"10.0.1.3", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref new file mode 100644 index 000000000000..95432310fd4c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16031 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref.diff deleted file mode 100644 index f9e0276f85ae..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_ipv6_route.ref.diff +++ /dev/null @@ -1,146 +0,0 @@ ---- a/rt2/step4/show_ipv6_route.ref -+++ b/rt2/step5/show_ipv6_route.ref -@@ -14,10 +14,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16011 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16011 -+ ] -+ } - ] - } - ], -@@ -36,10 +60,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16031 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16031 -+ ] -+ } - ] - } - ], -@@ -60,6 +108,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - }, - { -@@ -69,6 +120,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -78,7 +132,8 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16051 -+ 16051, -+ 16041 - ] - } - ] -@@ -98,7 +153,10 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - }, - { - "fib":true, -@@ -113,7 +171,10 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - } - ] - } -@@ -135,6 +196,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 16061 - ] - }, - { -@@ -144,6 +208,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 16061 - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref new file mode 100644 index 000000000000..ecaaae18c031 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref.diff deleted file mode 100644 index 6aebbd6c82b6..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step5/show_mpls_table.ref.diff +++ /dev/null @@ -1,200 +0,0 @@ ---- a/rt2/step4/show_mpls_table.ref -+++ b/rt2/step5/show_mpls_table.ref -@@ -7,7 +7,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1" -+ "nexthop":"10.0.1.1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.3.4" - } - ] - }, -@@ -19,7 +35,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1" -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-2" - } - ] - }, -@@ -31,7 +63,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.3" -+ "nexthop":"10.0.1.3", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.3.4" - } - ] - }, -@@ -43,6 +91,84 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-2" -+ } -+ ] -+ }, -+ "16040":{ -+ "inLabel":16040, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.3.4", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.2.4", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.1.3" -+ } -+ ] -+ }, -+ "16041":{ -+ "inLabel":16041, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt4-2", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt4-1", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, - "interface":"eth-sw1" - } - ] -@@ -55,6 +181,18 @@ - "type":"SR (IS-IS)", - "outLabel":16050, - "installed":true, -+ "nexthop":"10.0.3.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "installed":true, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "installed":true, - "nexthop":"10.0.1.3" - } - ] -@@ -66,6 +204,18 @@ - { - "type":"SR (IS-IS)", - "outLabel":16051, -+ "installed":true, -+ "interface":"eth-rt4-2" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "installed":true, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, - "installed":true, - "interface":"eth-sw1" - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ip_route.ref new file mode 100644 index 000000000000..7e1ccd10a2b7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16010 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16010 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16030 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050, + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ipv6_route.ref new file mode 100644 index 000000000000..95432310fd4c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16031 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step6/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_mpls_table.ref new file mode 100644 index 000000000000..ecaaae18c031 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step6/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step6/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref new file mode 100644 index 000000000000..9459f2ebda17 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref @@ -0,0 +1,405 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1" + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2" + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref.diff deleted file mode 100644 index 5e73b978448d..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ip_route.ref.diff +++ /dev/null @@ -1,288 +0,0 @@ ---- a/rt2/step6/show_ip_route.ref -+++ b/rt2/step7/show_ip_route.ref -@@ -15,36 +15,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050, -- 16010 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050, -- 16010 -- ] -- } - ] - } - ], -@@ -64,36 +38,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050, -- 16030 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050, -- 16030 -- ] -- } - ] - } - ], -@@ -113,9 +61,6 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] -@@ -126,25 +71,10 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4-2", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.3", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16050, -- 16040 -- ] -- } - ] - } - ], -@@ -163,30 +93,21 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } -@@ -251,40 +172,12 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -+ "interfaceName":"eth-sw1" - }, - { - "ip":"10.0.1.3", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.2.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16050 -- ] -- }, -- { -- "ip":"10.0.3.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "interfaceName":"eth-sw1" - } - ] - } -@@ -299,30 +192,13 @@ - { - "ip":"10.0.2.4", - "afi":"ipv4", -- "interfaceName":"eth-rt4-1", -- "backupIndex":[ -- 0 -- ] -+ "interfaceName":"eth-rt4-1" - }, - { - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.3", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } -@@ -338,29 +214,12 @@ - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true, -- "backupIndex":[ -- 0 -- ] -+ "active":true - }, - { - "ip":"10.0.3.4", - "afi":"ipv4", -- "interfaceName":"eth-rt4-2", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.3", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "interfaceName":"eth-rt4-2" - } - ] - } -@@ -497,31 +356,14 @@ - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true, -- "backupIndex":[ -- 0 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.3", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref new file mode 100644 index 000000000000..a75e5850f0f9 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref @@ -0,0 +1,155 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref.diff deleted file mode 100644 index 5dc4e59151aa..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_ipv6_route.ref.diff +++ /dev/null @@ -1,139 +0,0 @@ ---- a/rt2/step6/show_ipv6_route.ref -+++ b/rt2/step7/show_ipv6_route.ref -@@ -14,34 +14,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051, -- 16011 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051, -- 16011 -- ] -- } - ] - } - ], -@@ -60,34 +36,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051, -- 16031 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051, -- 16031 -- ] -- } - ] - } - ], -@@ -106,9 +58,6 @@ - "afi":"ipv6", - "interfaceName":"eth-rt4-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] -@@ -118,24 +67,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt4-2", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16051, -- 16041 -- ] -- } - ] - } - ], -@@ -153,28 +88,19 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-1", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-2", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref new file mode 100644 index 000000000000..2c0139f8db32 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref @@ -0,0 +1,155 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref.diff deleted file mode 100644 index 6c0d7392f017..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step7/show_mpls_table.ref.diff +++ /dev/null @@ -1,207 +0,0 @@ ---- a/rt2/step6/show_mpls_table.ref -+++ b/rt2/step7/show_mpls_table.ref -@@ -7,23 +7,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.3.4" -+ "nexthop":"10.0.1.1" - } - ] - }, -@@ -35,23 +19,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-2" -+ "interface":"eth-sw1" - } - ] - }, -@@ -63,23 +31,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.3", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.3.4" -+ "nexthop":"10.0.1.3" - } - ] - }, -@@ -91,23 +43,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4-2" -+ "interface":"eth-sw1" - } - ] - }, -@@ -119,26 +55,13 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.3.4", -- "backupIndex":[ -- 0 -- ] -+ "nexthop":"10.0.3.4" - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.2.4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.1.3" -+ "nexthop":"10.0.2.4" - } - ] - }, -@@ -150,74 +73,13 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt4-2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt4-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-sw1" -- } -- ] -- }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.3.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.1.3" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, - "interface":"eth-rt4-2" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16051, -+ "outLabel":3, - "installed":true, - "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, -- "interface":"eth-sw1" - } - ] - }, diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref new file mode 100644 index 000000000000..7e1ccd10a2b7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16010 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16010 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050, + 16030 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050, + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16050 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref.diff deleted file mode 100644 index f5df607613ed..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ip_route.ref.diff +++ /dev/null @@ -1,288 +0,0 @@ ---- a/rt2/step7/show_ip_route.ref -+++ b/rt2/step8/show_ip_route.ref -@@ -15,10 +15,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16010 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16010 -+ ] -+ } - ] - } - ], -@@ -38,10 +64,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16030 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16030 -+ ] -+ } - ] - } - ], -@@ -61,6 +113,9 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4-1", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] -@@ -71,10 +126,25 @@ - "afi":"ipv4", - "interfaceName":"eth-rt4-2", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.3", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16050, -+ 16040 -+ ] -+ } - ] - } - ], -@@ -93,21 +163,30 @@ - "ip":"10.0.1.3", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - }, - { - "fib":true, - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - }, - { - "fib":true, - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } -@@ -172,12 +251,40 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] - }, - { - "ip":"10.0.1.3", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.2.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] -+ }, -+ { -+ "ip":"10.0.3.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } -@@ -192,13 +299,30 @@ - { - "ip":"10.0.2.4", - "afi":"ipv4", -- "interfaceName":"eth-rt4-1" -+ "interfaceName":"eth-rt4-1", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.3", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } -@@ -214,12 +338,29 @@ - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.3.4", - "afi":"ipv4", -- "interfaceName":"eth-rt4-2" -+ "interfaceName":"eth-rt4-2", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.3", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } -@@ -356,14 +497,31 @@ - "ip":"10.0.2.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "fib":true, - "ip":"10.0.3.4", - "afi":"ipv4", - "interfaceName":"eth-rt4-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.3", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref new file mode 100644 index 000000000000..95432310fd4c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051, + 16031 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16051 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref.diff deleted file mode 100644 index 125f36b1b449..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_ipv6_route.ref.diff +++ /dev/null @@ -1,139 +0,0 @@ ---- a/rt2/step7/show_ipv6_route.ref -+++ b/rt2/step8/show_ipv6_route.ref -@@ -14,10 +14,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16011 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16011 -+ ] -+ } - ] - } - ], -@@ -36,10 +60,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-1", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16031 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4-2", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16031 -+ ] -+ } - ] - } - ], -@@ -58,6 +106,9 @@ - "afi":"ipv6", - "interfaceName":"eth-rt4-1", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] -@@ -67,10 +118,24 @@ - "afi":"ipv6", - "interfaceName":"eth-rt4-2", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16051, -+ 16041 -+ ] -+ } - ] - } - ], -@@ -88,19 +153,28 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref new file mode 100644 index 000000000000..8580cb0e7c0c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16050, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16051, + "installed":true, + "interface":"eth-rt4-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref.diff deleted file mode 100644 index a1d5d795c552..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step8/show_mpls_table.ref.diff +++ /dev/null @@ -1,207 +0,0 @@ ---- a/rt2/step7/show_mpls_table.ref -+++ b/rt2/step8/show_mpls_table.ref -@@ -7,7 +7,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1" -+ "nexthop":"10.0.1.1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.3.4" - } - ] - }, -@@ -19,7 +35,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1" -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-2" - } - ] - }, -@@ -31,7 +63,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.3" -+ "nexthop":"10.0.1.3", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.3.4" - } - ] - }, -@@ -43,7 +91,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1" -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4-2" - } - ] - }, -@@ -55,13 +119,26 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.3.4" -+ "nexthop":"10.0.3.4", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.2.4" -+ "nexthop":"10.0.2.4", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.1.3" - } - ] - }, -@@ -73,13 +150,74 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt4-2" -+ "interface":"eth-rt4-2", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -+ "interface":"eth-rt4-1", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-sw1" -+ } -+ ] -+ }, -+ "16050":{ -+ "inLabel":16050, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "installed":true, -+ "nexthop":"10.0.3.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "installed":true, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "installed":true, -+ "nexthop":"10.0.1.3" -+ } -+ ] -+ }, -+ "16051":{ -+ "inLabel":16051, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "installed":true, -+ "interface":"eth-rt4-2" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "installed":true, - "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "installed":true, -+ "interface":"eth-sw1" - } - ] - }, diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref new file mode 100644 index 000000000000..509615583362 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16500, + 16010 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16500, + 16010 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16500, + 16030 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16500, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16500, + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16500 + ] + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16500 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16500 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.3", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.2.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.4", + "afi":"ipv4", + "interfaceName":"eth-rt4-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref.diff deleted file mode 100644 index 2475c639c19a..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ip_route.ref.diff +++ /dev/null @@ -1,119 +0,0 @@ ---- a/rt2/step8/show_ip_route.ref -+++ b/rt2/step9/show_ip_route.ref -@@ -31,7 +31,7 @@ - "interfaceName":"eth-rt4-1", - "active":true, - "labels":[ -- 16050, -+ 16500, - 16010 - ] - }, -@@ -41,7 +41,7 @@ - "interfaceName":"eth-rt4-2", - "active":true, - "labels":[ -- 16050, -+ 16500, - 16010 - ] - } -@@ -80,7 +80,7 @@ - "interfaceName":"eth-rt4-1", - "active":true, - "labels":[ -- 16050, -+ 16500, - 16030 - ] - }, -@@ -90,7 +90,7 @@ - "interfaceName":"eth-rt4-2", - "active":true, - "labels":[ -- 16050, -+ 16500, - 16030 - ] - } -@@ -141,7 +141,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050, -+ 16500, - 16040 - ] - } -@@ -165,7 +165,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - }, - { -@@ -175,7 +175,7 @@ - "interfaceName":"eth-rt4-1", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - }, - { -@@ -185,7 +185,7 @@ - "interfaceName":"eth-rt4-2", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] -@@ -274,7 +274,7 @@ - "interfaceName":"eth-rt4-1", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - }, - { -@@ -283,7 +283,7 @@ - "interfaceName":"eth-rt4-2", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] -@@ -321,7 +321,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] -@@ -359,7 +359,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] -@@ -520,7 +520,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref new file mode 100644 index 000000000000..50e6a0a9f271 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16501, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16501, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16501, + 16031 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16501, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16501, + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16501 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "labels":[ + 16501 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "labels":[ + 16501 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref.diff deleted file mode 100644 index 2d21fbcde260..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_ipv6_route.ref.diff +++ /dev/null @@ -1,74 +0,0 @@ ---- a/rt2/step8/show_ipv6_route.ref -+++ b/rt2/step9/show_ipv6_route.ref -@@ -29,7 +29,7 @@ - "interfaceName":"eth-rt4-1", - "active":true, - "labels":[ -- 16051, -+ 16501, - 16011 - ] - }, -@@ -38,7 +38,7 @@ - "interfaceName":"eth-rt4-2", - "active":true, - "labels":[ -- 16051, -+ 16501, - 16011 - ] - } -@@ -75,7 +75,7 @@ - "interfaceName":"eth-rt4-1", - "active":true, - "labels":[ -- 16051, -+ 16501, - 16031 - ] - }, -@@ -84,7 +84,7 @@ - "interfaceName":"eth-rt4-2", - "active":true, - "labels":[ -- 16051, -+ 16501, - 16031 - ] - } -@@ -132,7 +132,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16051, -+ 16501, - 16041 - ] - } -@@ -155,7 +155,7 @@ - "interfaceName":"eth-rt4-1", - "active":true, - "labels":[ -- 16051 -+ 16501 - ] - }, - { -@@ -164,7 +164,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16051 -+ 16501 - ] - }, - { -@@ -173,7 +173,7 @@ - "interfaceName":"eth-rt4-2", - "active":true, - "labels":[ -- 16051 -+ 16501 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref new file mode 100644 index 000000000000..0bba1359484a --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16500, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16501, + "interface":"eth-rt4-2" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16500, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "interface":"eth-rt4-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16501, + "interface":"eth-rt4-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt4-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + }, + "16500":{ + "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "installed":true, + "nexthop":"10.0.1.3", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16500, + "installed":true, + "nexthop":"10.0.3.4", + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16500, + "installed":true, + "nexthop":"10.0.2.4", + "interface":"eth-rt4-1" + } + ] + }, + "16501":{ + "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16501, + "installed":true, + "interface":"eth-rt4-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16501, + "installed":true, + "interface":"eth-rt4-1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref.diff deleted file mode 100644 index bc0ec3157ea2..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt2/step9/show_mpls_table.ref.diff +++ /dev/null @@ -1,182 +0,0 @@ ---- a/rt2/step8/show_mpls_table.ref -+++ b/rt2/step9/show_mpls_table.ref -@@ -17,12 +17,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16050, -+ "outLabel":16500, - "nexthop":"10.0.2.4" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16050, -+ "outLabel":16500, - "nexthop":"10.0.3.4" - } - ] -@@ -45,12 +45,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16051, -+ "outLabel":16501, - "interface":"eth-rt4-1" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16051, -+ "outLabel":16501, - "interface":"eth-rt4-2" - } - ] -@@ -73,12 +73,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16050, -+ "outLabel":16500, - "nexthop":"10.0.2.4" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16050, -+ "outLabel":16500, - "nexthop":"10.0.3.4" - } - ] -@@ -101,12 +101,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16051, -+ "outLabel":16501, - "interface":"eth-rt4-1" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16051, -+ "outLabel":16501, - "interface":"eth-rt4-2" - } - ] -@@ -137,7 +137,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16050, -+ "outLabel":16500, - "nexthop":"10.0.1.3" - } - ] -@@ -168,55 +168,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-sw1" -- } -- ] -- }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.3.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.2.4" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "installed":true, -- "nexthop":"10.0.1.3" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, -- "interface":"eth-rt4-2" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, -- "interface":"eth-rt4-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "installed":true, -+ "outLabel":16501, - "interface":"eth-sw1" - } - ] -@@ -282,5 +234,53 @@ - "interface":"eth-sw1" - } - ] -+ }, -+ "16500":{ -+ "inLabel":16500, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16500, -+ "installed":true, -+ "nexthop":"10.0.3.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16500, -+ "installed":true, -+ "nexthop":"10.0.2.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16500, -+ "installed":true, -+ "nexthop":"10.0.1.3" -+ } -+ ] -+ }, -+ "16501":{ -+ "inLabel":16501, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16501, -+ "installed":true, -+ "interface":"eth-rt4-2" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16501, -+ "installed":true, -+ "interface":"eth-rt4-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16501, -+ "installed":true, -+ "interface":"eth-sw1" -+ } -+ ] - } - } diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step1/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step1/show_ipv6_route.ref index 058d33609b89..45af4e067394 100644 --- a/tests/topotests/isis_tilfa_topo1/rt3/step1/show_ipv6_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt3/step1/show_ipv6_route.ref @@ -104,7 +104,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "labels":[ 16041 @@ -113,7 +113,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-sw1", + "interfaceName":"eth-rt5-1", "active":true, "labels":[ 16041 @@ -122,7 +122,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-sw1", "active":true, "labels":[ 16041 @@ -144,7 +144,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "backupIndex":[ 0 @@ -156,7 +156,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "backupIndex":[ 0 @@ -192,7 +192,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-1", + "interfaceName":"eth-rt5-2", "active":true, "backupIndex":[ 0 @@ -204,7 +204,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5-2", + "interfaceName":"eth-rt5-1", "active":true, "backupIndex":[ 0 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step1/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step1/show_mpls_table.ref index 1912df3f050c..1b12d04f2daf 100644 --- a/tests/topotests/isis_tilfa_topo1/rt3/step1/show_mpls_table.ref +++ b/tests/topotests/isis_tilfa_topo1/rt3/step1/show_mpls_table.ref @@ -8,6 +8,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.1.1", + "interface":"eth-sw1", "backupIndex":[ 0, 1 @@ -18,12 +19,14 @@ { "type":"SR (IS-IS)", "outLabel":16040, - "nexthop":"10.0.4.5" + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" }, { "type":"SR (IS-IS)", "outLabel":16040, - "nexthop":"10.0.5.5" + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" } ] }, @@ -64,6 +67,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.1.2", + "interface":"eth-sw1", "backupIndex":[ 0, 1 @@ -74,12 +78,14 @@ { "type":"SR (IS-IS)", "outLabel":16040, - "nexthop":"10.0.4.5" + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" }, { "type":"SR (IS-IS)", "outLabel":16040, - "nexthop":"10.0.5.5" + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" } ] }, @@ -119,19 +125,22 @@ "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.5.5" + "nexthop":"10.0.1.2", + "interface":"eth-sw1" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.4.5" + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" }, { "type":"SR (IS-IS)", "outLabel":16040, "installed":true, - "nexthop":"10.0.1.2" + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" } ] }, @@ -143,19 +152,19 @@ "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt5-2" + "interface":"eth-sw1" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-rt5-1" + "interface":"eth-rt5-2" }, { "type":"SR (IS-IS)", "outLabel":16041, "installed":true, - "interface":"eth-sw1" + "interface":"eth-rt5-1" } ] }, @@ -168,6 +177,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", "backupIndex":[ 0 ] @@ -177,6 +187,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", "backupIndex":[ 0 ] @@ -186,7 +197,8 @@ { "type":"SR (IS-IS)", "outLabel":16040, - "nexthop":"10.0.1.2" + "nexthop":"10.0.1.2", + "interface":"eth-sw1" } ] }, @@ -230,6 +242,7 @@ "outLabel":16060, "installed":true, "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", "backupIndex":[ 0 ] @@ -239,6 +252,7 @@ "outLabel":16060, "installed":true, "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", "backupIndex":[ 0 ] @@ -248,7 +262,8 @@ { "type":"SR (IS-IS)", "outLabel":16060, - "nexthop":"10.0.1.2" + "nexthop":"10.0.1.2", + "interface":"eth-sw1" } ] }, diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis_tilfa_topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref index 777c74981970..2645827ec48f 100644 --- a/tests/topotests/isis_tilfa_topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref +++ b/tests/topotests/isis_tilfa_topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref @@ -48,16 +48,16 @@ "adjacency": [ { "neighbor-sys-type": "level-1", - "neighbor-sysid": "0000.0000.0001", + "neighbor-sysid": "0000.0000.0002", "hold-timer": 10, - "neighbor-priority": 100, + "neighbor-priority": 64, "state": "up" }, { "neighbor-sys-type": "level-1", - "neighbor-sysid": "0000.0000.0002", + "neighbor-sysid": "0000.0000.0001", "hold-timer": 10, - "neighbor-priority": 64, + "neighbor-priority": 100, "state": "up" } ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ip_route.ref new file mode 100644 index 000000000000..d70e9fe882e2 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040, + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ipv6_route.ref new file mode 100644 index 000000000000..45af4e067394 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041, + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step2/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_mpls_table.ref new file mode 100644 index 000000000000..1b12d04f2daf --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step2/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step2/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ip_route.ref new file mode 100644 index 000000000000..d70e9fe882e2 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040, + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ipv6_route.ref new file mode 100644 index 000000000000..45af4e067394 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041, + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step3/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_mpls_table.ref new file mode 100644 index 000000000000..1b12d04f2daf --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step3/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step3/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref new file mode 100644 index 000000000000..5f8779966fa9 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref @@ -0,0 +1,405 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1" + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1" + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1" + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2" + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref.diff deleted file mode 100644 index 9ba73b057a0e..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ip_route.ref.diff +++ /dev/null @@ -1,288 +0,0 @@ ---- a/rt3/step3/show_ip_route.ref -+++ b/rt3/step4/show_ip_route.ref -@@ -15,36 +15,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.4.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5-1", -- "active":true, -- "labels":[ -- 16040, -- 16010 -- ] -- }, -- { -- "ip":"10.0.5.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5-2", -- "active":true, -- "labels":[ -- 16040, -- 16010 -- ] -- } - ] - } - ], -@@ -64,36 +38,10 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.4.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5-1", -- "active":true, -- "labels":[ -- 16040, -- 16020 -- ] -- }, -- { -- "ip":"10.0.5.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5-2", -- "active":true, -- "labels":[ -- 16040, -- 16020 -- ] -- } - ] - } - ], -@@ -112,30 +60,21 @@ - "ip":"10.0.1.2", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.4.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-1", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.5.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-2", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - } - ] - } -@@ -156,9 +95,6 @@ - "afi":"ipv4", - "interfaceName":"eth-rt5-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] -@@ -169,25 +105,10 @@ - "afi":"ipv4", - "interfaceName":"eth-rt5-2", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.2", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16040, -- 16050 -- ] -- } - ] - } - ], -@@ -251,40 +172,12 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -+ "interfaceName":"eth-sw1" - }, - { - "ip":"10.0.1.2", - "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.4.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5-1", -- "active":true, -- "labels":[ -- 16040 -- ] -- }, -- { -- "ip":"10.0.5.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5-2", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "interfaceName":"eth-sw1" - } - ] - } -@@ -375,30 +268,13 @@ - { - "ip":"10.0.4.5", - "afi":"ipv4", -- "interfaceName":"eth-rt5-1", -- "backupIndex":[ -- 0 -- ] -+ "interfaceName":"eth-rt5-1" - }, - { - "ip":"10.0.5.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-2", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.2", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - } - ] - } -@@ -414,29 +290,12 @@ - "ip":"10.0.4.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-1", -- "active":true, -- "backupIndex":[ -- 0 -- ] -+ "active":true - }, - { - "ip":"10.0.5.5", - "afi":"ipv4", -- "interfaceName":"eth-rt5-2", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.2", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "interfaceName":"eth-rt5-2" - } - ] - } -@@ -531,31 +390,14 @@ - "ip":"10.0.4.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-1", -- "active":true, -- "backupIndex":[ -- 0 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.5.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-2", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.1.2", -- "afi":"ipv4", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref new file mode 100644 index 000000000000..91426403e8e4 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref @@ -0,0 +1,155 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref.diff deleted file mode 100644 index 04f61c4eb40b..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_ipv6_route.ref.diff +++ /dev/null @@ -1,139 +0,0 @@ ---- a/rt3/step3/show_ipv6_route.ref -+++ b/rt3/step4/show_ipv6_route.ref -@@ -14,34 +14,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5-1", -- "active":true, -- "labels":[ -- 16041, -- 16011 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5-2", -- "active":true, -- "labels":[ -- 16041, -- 16011 -- ] -- } - ] - } - ], -@@ -60,34 +36,10 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -- "backupIndex":[ -- 0, -- 1 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5-1", -- "active":true, -- "labels":[ -- 16041, -- 16021 -- ] -- }, -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5-2", -- "active":true, -- "labels":[ -- 16041, -- 16021 -- ] -- } - ] - } - ], -@@ -105,28 +57,19 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5-1", -- "active":true, -- "labels":[ -- 16041 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16041 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5-2", -- "active":true, -- "labels":[ -- 16041 -- ] -+ "active":true - } - ] - } -@@ -146,9 +89,6 @@ - "afi":"ipv6", - "interfaceName":"eth-rt5-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] -@@ -158,24 +98,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt5-2", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-sw1", -- "active":true, -- "labels":[ -- 16041, -- 16051 -- ] -- } - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref new file mode 100644 index 000000000000..0a6e3169bf70 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref @@ -0,0 +1,155 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref.diff deleted file mode 100644 index b3588ca79132..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step4/show_mpls_table.ref.diff +++ /dev/null @@ -1,206 +0,0 @@ ---- a/rt3/step3/show_mpls_table.ref -+++ b/rt3/step4/show_mpls_table.ref -@@ -7,23 +7,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.4.5" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.5.5" -+ "nexthop":"10.0.1.1" - } - ] - }, -@@ -35,23 +19,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-rt5-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-rt5-2" -+ "interface":"eth-sw1" - } - ] - }, -@@ -63,23 +31,7 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.2", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.4.5" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.5.5" -+ "nexthop":"10.0.1.2" - } - ] - }, -@@ -91,70 +43,6 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1", -- "backupIndex":[ -- 0, -- 1 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-rt5-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-rt5-2" -- } -- ] -- }, -- "16040":{ -- "inLabel":16040, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "installed":true, -- "nexthop":"10.0.5.5" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "installed":true, -- "nexthop":"10.0.4.5" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "installed":true, -- "nexthop":"10.0.1.2" -- } -- ] -- }, -- "16041":{ -- "inLabel":16041, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "installed":true, -- "interface":"eth-rt5-2" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "installed":true, -- "interface":"eth-rt5-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "installed":true, - "interface":"eth-sw1" - } - ] -@@ -167,26 +55,13 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.5.5", -- "backupIndex":[ -- 0 -- ] -+ "nexthop":"10.0.5.5" - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.4.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.1.2" -+ "nexthop":"10.0.4.5" - } - ] - }, -@@ -198,26 +73,13 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt5-2", -- "backupIndex":[ -- 0 -- ] -+ "interface":"eth-rt5-2" - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt5-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-sw1" -+ "interface":"eth-rt5-1" - } - ] - }, diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref new file mode 100644 index 000000000000..d70e9fe882e2 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040, + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref.diff deleted file mode 100644 index 1af024fc2e78..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ip_route.ref.diff +++ /dev/null @@ -1,288 +0,0 @@ ---- a/rt3/step4/show_ip_route.ref -+++ b/rt3/step5/show_ip_route.ref -@@ -15,10 +15,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.4.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5-1", -+ "active":true, -+ "labels":[ -+ 16040, -+ 16010 -+ ] -+ }, -+ { -+ "ip":"10.0.5.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5-2", -+ "active":true, -+ "labels":[ -+ 16040, -+ 16010 -+ ] -+ } - ] - } - ], -@@ -38,10 +64,36 @@ - "afi":"ipv4", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.4.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5-1", -+ "active":true, -+ "labels":[ -+ 16040, -+ 16020 -+ ] -+ }, -+ { -+ "ip":"10.0.5.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5-2", -+ "active":true, -+ "labels":[ -+ 16040, -+ 16020 -+ ] -+ } - ] - } - ], -@@ -60,21 +112,30 @@ - "ip":"10.0.1.2", - "afi":"ipv4", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - }, - { - "fib":true, - "ip":"10.0.4.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - }, - { - "fib":true, - "ip":"10.0.5.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } -@@ -95,6 +156,9 @@ - "afi":"ipv4", - "interfaceName":"eth-rt5-1", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] -@@ -105,10 +169,25 @@ - "afi":"ipv4", - "interfaceName":"eth-rt5-2", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16040, -+ 16050 -+ ] -+ } - ] - } - ], -@@ -172,12 +251,40 @@ - { - "ip":"10.0.1.1", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] - }, - { - "ip":"10.0.1.2", - "afi":"ipv4", -- "interfaceName":"eth-sw1" -+ "interfaceName":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.4.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5-1", -+ "active":true, -+ "labels":[ -+ 16040 -+ ] -+ }, -+ { -+ "ip":"10.0.5.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5-2", -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } -@@ -268,13 +375,30 @@ - { - "ip":"10.0.4.5", - "afi":"ipv4", -- "interfaceName":"eth-rt5-1" -+ "interfaceName":"eth-rt5-1", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.5.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } -@@ -290,12 +414,29 @@ - "ip":"10.0.4.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.5.5", - "afi":"ipv4", -- "interfaceName":"eth-rt5-2" -+ "interfaceName":"eth-rt5-2", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } -@@ -390,14 +531,31 @@ - "ip":"10.0.4.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "fib":true, - "ip":"10.0.5.5", - "afi":"ipv4", - "interfaceName":"eth-rt5-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.1.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref new file mode 100644 index 000000000000..45af4e067394 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 16041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041, + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref.diff deleted file mode 100644 index 7cc79d0e5858..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_ipv6_route.ref.diff +++ /dev/null @@ -1,139 +0,0 @@ ---- a/rt3/step4/show_ipv6_route.ref -+++ b/rt3/step5/show_ipv6_route.ref -@@ -14,10 +14,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt5-1", -+ "active":true, -+ "labels":[ -+ 16041, -+ 16011 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt5-2", -+ "active":true, -+ "labels":[ -+ 16041, -+ 16011 -+ ] -+ } - ] - } - ], -@@ -36,10 +60,34 @@ - "afi":"ipv6", - "interfaceName":"eth-sw1", - "active":true, -+ "backupIndex":[ -+ 0, -+ 1 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt5-1", -+ "active":true, -+ "labels":[ -+ 16041, -+ 16021 -+ ] -+ }, -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt5-2", -+ "active":true, -+ "labels":[ -+ 16041, -+ 16021 -+ ] -+ } - ] - } - ], -@@ -57,19 +105,28 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16041 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-sw1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16041 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16041 -+ ] - } - ] - } -@@ -89,6 +146,9 @@ - "afi":"ipv6", - "interfaceName":"eth-rt5-1", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] -@@ -98,10 +158,24 @@ - "afi":"ipv6", - "interfaceName":"eth-rt5-2", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-sw1", -+ "active":true, -+ "labels":[ -+ 16041, -+ 16051 -+ ] -+ } - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref new file mode 100644 index 000000000000..1b12d04f2daf --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref.diff deleted file mode 100644 index 75a0f01f5514..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step5/show_mpls_table.ref.diff +++ /dev/null @@ -1,206 +0,0 @@ ---- a/rt3/step4/show_mpls_table.ref -+++ b/rt3/step5/show_mpls_table.ref -@@ -7,7 +7,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.1" -+ "nexthop":"10.0.1.1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.4.5" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.5.5" - } - ] - }, -@@ -19,7 +35,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-sw1" -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-rt5-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-rt5-2" - } - ] - }, -@@ -31,7 +63,23 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.1.2" -+ "nexthop":"10.0.1.2", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.4.5" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.5.5" - } - ] - }, -@@ -43,6 +91,70 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -+ "interface":"eth-sw1", -+ "backupIndex":[ -+ 0, -+ 1 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-rt5-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-rt5-2" -+ } -+ ] -+ }, -+ "16040":{ -+ "inLabel":16040, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "installed":true, -+ "nexthop":"10.0.5.5" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "installed":true, -+ "nexthop":"10.0.4.5" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "installed":true, -+ "nexthop":"10.0.1.2" -+ } -+ ] -+ }, -+ "16041":{ -+ "inLabel":16041, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "installed":true, -+ "interface":"eth-rt5-2" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "installed":true, -+ "interface":"eth-rt5-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "installed":true, - "interface":"eth-sw1" - } - ] -@@ -55,13 +167,26 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.5.5" -+ "nexthop":"10.0.5.5", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.4.5" -+ "nexthop":"10.0.4.5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.1.2" - } - ] - }, -@@ -73,13 +198,26 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt5-2" -+ "interface":"eth-rt5-2", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt5-1" -+ "interface":"eth-rt5-1", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-sw1" - } - ] - }, diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref new file mode 100644 index 000000000000..e6d99e59e377 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040, + 30050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref.diff deleted file mode 100644 index c814a2876b4d..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ip_route.ref.diff +++ /dev/null @@ -1,101 +0,0 @@ ---- a/rt3/step5/show_ip_route.ref -+++ b/rt3/step6/show_ip_route.ref -@@ -31,7 +31,7 @@ - "interfaceName":"eth-rt5-1", - "active":true, - "labels":[ -- 16040, -+ 30040, - 16010 - ] - }, -@@ -41,7 +41,7 @@ - "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16040, -+ 30040, - 16010 - ] - } -@@ -80,7 +80,7 @@ - "interfaceName":"eth-rt5-1", - "active":true, - "labels":[ -- 16040, -+ 30040, - 16020 - ] - }, -@@ -90,7 +90,7 @@ - "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16040, -+ 30040, - 16020 - ] - } -@@ -124,7 +124,7 @@ - "interfaceName":"eth-rt5-1", - "active":true, - "labels":[ -- 16040 -+ 30040 - ] - }, - { -@@ -134,7 +134,7 @@ - "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16040 -+ 30040 - ] - } - ] -@@ -185,7 +185,7 @@ - "active":true, - "labels":[ - 16040, -- 16050 -+ 30050 - ] - } - ] -@@ -211,7 +211,7 @@ - 0 - ], - "labels":[ -- 16060 -+ 30060 - ] - }, - { -@@ -224,7 +224,7 @@ - 0 - ], - "labels":[ -- 16060 -+ 30060 - ] - } - ], -@@ -274,7 +274,7 @@ - "interfaceName":"eth-rt5-1", - "active":true, - "labels":[ -- 16040 -+ 30040 - ] - }, - { -@@ -283,7 +283,7 @@ - "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16040 -+ 30040 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref new file mode 100644 index 000000000000..f844d5a49efa --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041, + 30051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref.diff deleted file mode 100644 index 6f9405f20ce9..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_ipv6_route.ref.diff +++ /dev/null @@ -1,83 +0,0 @@ ---- a/rt3/step5/show_ipv6_route.ref -+++ b/rt3/step6/show_ipv6_route.ref -@@ -29,7 +29,7 @@ - "interfaceName":"eth-rt5-1", - "active":true, - "labels":[ -- 16041, -+ 30041, - 16011 - ] - }, -@@ -38,7 +38,7 @@ - "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16041, -+ 30041, - 16011 - ] - } -@@ -75,7 +75,7 @@ - "interfaceName":"eth-rt5-1", - "active":true, - "labels":[ -- 16041, -+ 30041, - 16021 - ] - }, -@@ -84,7 +84,7 @@ - "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16041, -+ 30041, - 16021 - ] - } -@@ -107,7 +107,7 @@ - "interfaceName":"eth-rt5-1", - "active":true, - "labels":[ -- 16041 -+ 30041 - ] - }, - { -@@ -125,7 +125,7 @@ - "interfaceName":"eth-rt5-2", - "active":true, - "labels":[ -- 16041 -+ 30041 - ] - } - ] -@@ -173,7 +173,7 @@ - "active":true, - "labels":[ - 16041, -- 16051 -+ 30051 - ] - } - ] -@@ -198,7 +198,7 @@ - 0 - ], - "labels":[ -- 16061 -+ 30061 - ] - }, - { -@@ -210,7 +210,7 @@ - 0 - ], - "labels":[ -- 16061 -+ 30061 - ] - } - ], diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref new file mode 100644 index 000000000000..052a5a1cc198 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref.diff deleted file mode 100644 index d8c39685de7c..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step6/show_mpls_table.ref.diff +++ /dev/null @@ -1,130 +0,0 @@ ---- a/rt3/step5/show_mpls_table.ref -+++ b/rt3/step6/show_mpls_table.ref -@@ -17,12 +17,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":30040, - "nexthop":"10.0.4.5" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":30040, - "nexthop":"10.0.5.5" - } - ] -@@ -45,12 +45,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":30041, - "interface":"eth-rt5-1" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":30041, - "interface":"eth-rt5-2" - } - ] -@@ -73,12 +73,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":30040, - "nexthop":"10.0.4.5" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":30040, - "nexthop":"10.0.5.5" - } - ] -@@ -101,12 +101,12 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":30041, - "interface":"eth-rt5-1" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":30041, - "interface":"eth-rt5-2" - } - ] -@@ -117,13 +117,13 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":30040, - "installed":true, - "nexthop":"10.0.5.5" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":30040, - "installed":true, - "nexthop":"10.0.4.5" - }, -@@ -141,13 +141,13 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":30041, - "installed":true, - "interface":"eth-rt5-2" - }, - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":30041, - "installed":true, - "interface":"eth-rt5-1" - }, -@@ -227,7 +227,7 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16060, -+ "outLabel":30060, - "installed":true, - "nexthop":"10.0.5.5", - "backupIndex":[ -@@ -236,7 +236,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":16060, -+ "outLabel":30060, - "installed":true, - "nexthop":"10.0.4.5", - "backupIndex":[ -@@ -258,7 +258,7 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16061, -+ "outLabel":30061, - "installed":true, - "interface":"eth-rt5-2", - "backupIndex":[ -@@ -267,7 +267,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":16061, -+ "outLabel":30061, - "installed":true, - "interface":"eth-rt5-1", - "backupIndex":[ diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref new file mode 100644 index 000000000000..fd340ba96230 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref @@ -0,0 +1,556 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref.diff deleted file mode 100644 index c928fcdb4bf1..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ip_route.ref.diff +++ /dev/null @@ -1,32 +0,0 @@ ---- a/rt3/step6/show_ip_route.ref -+++ b/rt3/step7/show_ip_route.ref -@@ -158,9 +158,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - }, - { -@@ -171,9 +168,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -184,8 +178,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16040, -- 30050 -+ 16040 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref new file mode 100644 index 000000000000..27be6929fb09 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref @@ -0,0 +1,222 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref.diff deleted file mode 100644 index 0170971781cf..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_ipv6_route.ref.diff +++ /dev/null @@ -1,32 +0,0 @@ ---- a/rt3/step6/show_ipv6_route.ref -+++ b/rt3/step7/show_ipv6_route.ref -@@ -148,9 +148,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - }, - { -@@ -160,9 +157,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -172,8 +166,7 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16041, -- 30051 -+ 16041 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref new file mode 100644 index 000000000000..1d8d1d0cb7f8 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref @@ -0,0 +1,236 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref.diff deleted file mode 100644 index d7a3ed978f36..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step7/show_mpls_table.ref.diff +++ /dev/null @@ -1,71 +0,0 @@ ---- a/rt3/step6/show_mpls_table.ref -+++ b/rt3/step7/show_mpls_table.ref -@@ -159,68 +159,6 @@ - } - ] - }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.5.5", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.4.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.1.2" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt5-2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt5-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-sw1" -- } -- ] -- }, - "16060":{ - "inLabel":16060, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref new file mode 100644 index 000000000000..e6d99e59e377 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040, + 30050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref.diff deleted file mode 100644 index 41a7ff32552e..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ip_route.ref.diff +++ /dev/null @@ -1,32 +0,0 @@ ---- a/rt3/step7/show_ip_route.ref -+++ b/rt3/step8/show_ip_route.ref -@@ -158,6 +158,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - }, - { -@@ -168,6 +171,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -178,7 +184,8 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16040 -+ 16040, -+ 30050 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref new file mode 100644 index 000000000000..f844d5a49efa --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041, + 30051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref.diff deleted file mode 100644 index bd49f8606ba8..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_ipv6_route.ref.diff +++ /dev/null @@ -1,32 +0,0 @@ ---- a/rt3/step7/show_ipv6_route.ref -+++ b/rt3/step8/show_ipv6_route.ref -@@ -148,6 +148,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - }, - { -@@ -157,6 +160,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -166,7 +172,8 @@ - "interfaceName":"eth-sw1", - "active":true, - "labels":[ -- 16041 -+ 16041, -+ 30051 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref new file mode 100644 index 000000000000..052a5a1cc198 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-sw1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref.diff deleted file mode 100644 index 4cc69b66f24d..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step8/show_mpls_table.ref.diff +++ /dev/null @@ -1,71 +0,0 @@ ---- a/rt3/step7/show_mpls_table.ref -+++ b/rt3/step8/show_mpls_table.ref -@@ -159,6 +159,68 @@ - } - ] - }, -+ "16050":{ -+ "inLabel":16050, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.5.5", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.4.5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.1.2" -+ } -+ ] -+ }, -+ "16051":{ -+ "inLabel":16051, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt5-2", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt5-1", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-sw1" -+ } -+ ] -+ }, - "16060":{ - "inLabel":16060, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref new file mode 100644 index 000000000000..a9590ee0fc94 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref @@ -0,0 +1,563 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16010 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040, + 16020 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040, + 16020 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040, + 30500 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30060 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.1.1", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + }, + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30040 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true + }, + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.5", + "afi":"ipv4", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.1.2", + "afi":"ipv4", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref.diff deleted file mode 100644 index cc0a482eee4e..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ip_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt3/step8/show_ip_route.ref -+++ b/rt3/step9/show_ip_route.ref -@@ -185,7 +185,7 @@ - "active":true, - "labels":[ - 16040, -- 30050 -+ 30500 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref new file mode 100644 index 000000000000..ce635407d5c9 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref @@ -0,0 +1,229 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16011 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "backupIndex":[ + 0, + 1 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041, + 16021 + ] + }, + { + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "labels":[ + 30041 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16041, + 30501 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30061 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-sw1", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref.diff deleted file mode 100644 index 650b982f0b62..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_ipv6_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt3/step8/show_ipv6_route.ref -+++ b/rt3/step9/show_ipv6_route.ref -@@ -173,7 +173,7 @@ - "active":true, - "labels":[ - 16041, -- 30051 -+ 30501 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref new file mode 100644 index 000000000000..a364c2e4caac --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref @@ -0,0 +1,301 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.1", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-sw1", + "backupIndex":[ + 0, + 1 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5-2" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "installed":true, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30040, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "installed":true, + "interface":"eth-sw1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":30041, + "installed":true, + "interface":"eth-rt5-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30060, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":30061, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-sw1" + } + ] + }, + "16500":{ + "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.5", + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.5", + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.1.2", + "interface":"eth-sw1" + } + ] + }, + "16501":{ + "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-sw1" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref.diff deleted file mode 100644 index 8ce4f1d26610..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt3/step9/show_mpls_table.ref.diff +++ /dev/null @@ -1,133 +0,0 @@ ---- a/rt3/step8/show_mpls_table.ref -+++ b/rt3/step9/show_mpls_table.ref -@@ -159,13 +159,13 @@ - } - ] - }, -- "16050":{ -- "inLabel":16050, -+ "16060":{ -+ "inLabel":16060, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":30060, - "installed":true, - "nexthop":"10.0.5.5", - "backupIndex":[ -@@ -174,7 +174,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":30060, - "installed":true, - "nexthop":"10.0.4.5", - "backupIndex":[ -@@ -185,18 +185,18 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":16060, - "nexthop":"10.0.1.2" - } - ] - }, -- "16051":{ -- "inLabel":16051, -+ "16061":{ -+ "inLabel":16061, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":30061, - "installed":true, - "interface":"eth-rt5-2", - "backupIndex":[ -@@ -205,7 +205,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":30061, - "installed":true, - "interface":"eth-rt5-1", - "backupIndex":[ -@@ -216,18 +216,18 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":16061, - "interface":"eth-sw1" - } - ] - }, -- "16060":{ -- "inLabel":16060, -+ "16500":{ -+ "inLabel":16500, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30060, -+ "outLabel":3, - "installed":true, - "nexthop":"10.0.5.5", - "backupIndex":[ -@@ -236,7 +236,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":30060, -+ "outLabel":3, - "installed":true, - "nexthop":"10.0.4.5", - "backupIndex":[ -@@ -247,18 +247,18 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16060, -+ "outLabel":16040, - "nexthop":"10.0.1.2" - } - ] - }, -- "16061":{ -- "inLabel":16061, -+ "16501":{ -+ "inLabel":16501, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30061, -+ "outLabel":3, - "installed":true, - "interface":"eth-rt5-2", - "backupIndex":[ -@@ -267,7 +267,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":30061, -+ "outLabel":3, - "installed":true, - "interface":"eth-rt5-1", - "backupIndex":[ -@@ -278,7 +278,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16061, -+ "outLabel":16041, - "interface":"eth-sw1" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step1/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step1/show_ipv6_route.ref index b640df30c1fb..c757031881e2 100644 --- a/tests/topotests/isis_tilfa_topo1/rt4/step1/show_ipv6_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt4/step1/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "backupIndex":[ 0 @@ -24,7 +24,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "backupIndex":[ 0 @@ -59,7 +59,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "backupIndex":[ 0 @@ -71,7 +71,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "backupIndex":[ 0 @@ -107,7 +107,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-2", + "interfaceName":"eth-rt2-1", "active":true, "labels":[ 16031 @@ -116,7 +116,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt2-1", + "interfaceName":"eth-rt2-2", "active":true, "labels":[ 16031 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step1/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step1/show_mpls_table.ref index f60937ccbcd7..2a709070e472 100644 --- a/tests/topotests/isis_tilfa_topo1/rt4/step1/show_mpls_table.ref +++ b/tests/topotests/isis_tilfa_topo1/rt4/step1/show_mpls_table.ref @@ -8,6 +8,7 @@ "outLabel":16010, "installed":true, "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", "backupIndex":[ 0 ] @@ -17,6 +18,7 @@ "outLabel":16010, "installed":true, "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", "backupIndex":[ 0 ] @@ -26,7 +28,8 @@ { "type":"SR (IS-IS)", "outLabel":16010, - "nexthop":"10.0.6.5" + "nexthop":"10.0.6.5", + "interface":"eth-rt5" } ] }, @@ -70,6 +73,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", "backupIndex":[ 0 ] @@ -79,6 +83,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", "backupIndex":[ 0 ] @@ -88,7 +93,8 @@ { "type":"SR (IS-IS)", "outLabel":16030, - "nexthop":"10.0.6.5" + "nexthop":"10.0.6.5", + "interface":"eth-rt5" } ] }, @@ -131,19 +137,22 @@ "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.3.2" + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.2.2" + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" }, { "type":"SR (IS-IS)", "outLabel":16030, "installed":true, - "nexthop":"10.0.6.5" + "nexthop":"10.0.6.5", + "interface":"eth-rt5" } ] }, @@ -180,6 +189,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.6.5", + "interface":"eth-rt5", "backupIndex":[ 0 ] @@ -189,7 +199,8 @@ { "type":"SR (IS-IS)", "outLabel":16050, - "nexthop":"10.0.7.6" + "nexthop":"10.0.7.6", + "interface":"eth-rt6" } ] }, @@ -224,6 +235,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.7.6", + "interface":"eth-rt6", "backupIndex":[ 0 ] @@ -233,7 +245,8 @@ { "type":"SR (IS-IS)", "outLabel":16060, - "nexthop":"10.0.6.5" + "nexthop":"10.0.6.5", + "interface":"eth-rt5" } ] }, diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ip_route.ref new file mode 100644 index 000000000000..0ef5d1bc3f82 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ipv6_route.ref new file mode 100644 index 000000000000..c757031881e2 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step2/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_mpls_table.ref new file mode 100644 index 000000000000..2a709070e472 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.6", + "interface":"eth-rt6" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step2/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step2/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ip_route.ref new file mode 100644 index 000000000000..0ef5d1bc3f82 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ipv6_route.ref new file mode 100644 index 000000000000..c757031881e2 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step3/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_mpls_table.ref new file mode 100644 index 000000000000..2a709070e472 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.6", + "interface":"eth-rt6" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step3/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step3/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref new file mode 100644 index 000000000000..0f26fa5d7aed --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref @@ -0,0 +1,296 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1" + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2" + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5" + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6" + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref.diff deleted file mode 100644 index a9418473c75c..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ip_route.ref.diff +++ /dev/null @@ -1,367 +0,0 @@ ---- a/rt4/step3/show_ip_route.ref -+++ b/rt4/step4/show_ip_route.ref -@@ -14,37 +14,14 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 16010 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 16010 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16010 -- ] -+ "active":true - } - ] - } -@@ -64,38 +41,14 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16030, -- 16020 -- ] -+ "active":true - } - ] - } -@@ -115,30 +68,21 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true, -- "labels":[ -- 16030 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true, -- "labels":[ -- 16030 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16030 -- ] -+ "active":true - } - ] - } -@@ -158,24 +102,7 @@ - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } -@@ -195,24 +122,7 @@ - "ip":"10.0.7.6", - "afi":"ipv4", - "interfaceName":"eth-rt6", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16060 -- ] -+ "active":true - } - ] - } -@@ -232,27 +142,13 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true, -- "backupIndex":[ -- 0 -- ] -+ "active":true - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", - "active":true - } - ] -@@ -268,30 +164,13 @@ - { - "ip":"10.0.2.2", - "afi":"ipv4", -- "interfaceName":"eth-rt2-1", -- "backupIndex":[ -- 0 -- ] -+ "interfaceName":"eth-rt2-1" - }, - { - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16030 -- ] -+ "active":true - } - ] - } -@@ -307,29 +186,12 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true, -- "backupIndex":[ -- 0 -- ] -+ "active":true - }, - { - "ip":"10.0.3.2", - "afi":"ipv4", -- "interfaceName":"eth-rt2-2", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16030 -- ] -+ "interfaceName":"eth-rt2-2" - } - ] - } -@@ -349,31 +211,6 @@ - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0, -- 1, -- 2 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- }, -- { -- "ip":"10.0.2.2", -- "afi":"ipv4", -- "interfaceName":"eth-rt2-1", -- "active":true -- }, -- { -- "ip":"10.0.3.2", -- "afi":"ipv4", -- "interfaceName":"eth-rt2-2", - "active":true - } - ] -@@ -394,31 +231,6 @@ - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0, -- 1, -- 2 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -- }, -- { -- "ip":"10.0.2.2", -- "afi":"ipv4", -- "interfaceName":"eth-rt2-1", -- "active":true -- }, -- { -- "ip":"10.0.3.2", -- "afi":"ipv4", -- "interfaceName":"eth-rt2-2", - "active":true - } - ] -@@ -434,18 +246,7 @@ - { - "ip":"10.0.6.5", - "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.7.6", -- "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "active":true -+ "interfaceName":"eth-rt5" - } - ] - } -@@ -460,18 +261,7 @@ - { - "ip":"10.0.7.6", - "afi":"ipv4", -- "interfaceName":"eth-rt6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.5", -- "afi":"ipv4", -- "interfaceName":"eth-rt5", -- "active":true -+ "interfaceName":"eth-rt6" - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref new file mode 100644 index 000000000000..329fa39af910 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref @@ -0,0 +1,121 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref.diff deleted file mode 100644 index 991562ab9935..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_ipv6_route.ref.diff +++ /dev/null @@ -1,161 +0,0 @@ ---- a/rt4/step3/show_ipv6_route.ref -+++ b/rt4/step4/show_ipv6_route.ref -@@ -13,35 +13,13 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-2", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 16011 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-1", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 16011 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16011 -- ] -+ "active":true - } - ] - } -@@ -60,36 +38,13 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-2", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-1", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16031, -- 16021 -- ] -+ "active":true - } - ] - } -@@ -108,28 +63,19 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-2", -- "active":true, -- "labels":[ -- 16031 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-1", -- "active":true, -- "labels":[ -- 16031 -- ] -+ "active":true - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16031 -- ] -+ "active":true - } - ] - } -@@ -148,23 +94,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - } - ] - } -@@ -183,23 +113,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt6", -- "active":true, -- "backupIndex":[ -- 0 -- ], -- "labels":[ -- 3 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16061 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref @@ -0,0 +1 @@ +{} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref.diff deleted file mode 100644 index 660d2fbde23f..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step4/show_mpls_table.ref.diff +++ /dev/null @@ -1,265 +0,0 @@ ---- a/rt4/step3/show_mpls_table.ref -+++ b/rt4/step4/show_mpls_table.ref -@@ -1,262 +1,2 @@ - { -- "16010":{ -- "inLabel":16010, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16010, -- "installed":true, -- "nexthop":"10.0.3.2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16010, -- "installed":true, -- "nexthop":"10.0.2.2", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16010, -- "nexthop":"10.0.6.5" -- } -- ] -- }, -- "16011":{ -- "inLabel":16011, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16011, -- "installed":true, -- "interface":"eth-rt2-2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16011, -- "installed":true, -- "interface":"eth-rt2-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16011, -- "interface":"eth-rt5" -- } -- ] -- }, -- "16020":{ -- "inLabel":16020, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.3.2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.2.2", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16030, -- "nexthop":"10.0.6.5" -- } -- ] -- }, -- "16021":{ -- "inLabel":16021, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt2-2", -- "backupIndex":[ -- 0 -- ] -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt2-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16031, -- "interface":"eth-rt5" -- } -- ] -- }, -- "16030":{ -- "inLabel":16030, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16030, -- "installed":true, -- "nexthop":"10.0.3.2" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16030, -- "installed":true, -- "nexthop":"10.0.2.2" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16030, -- "installed":true, -- "nexthop":"10.0.6.5" -- } -- ] -- }, -- "16031":{ -- "inLabel":16031, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16031, -- "installed":true, -- "interface":"eth-rt2-2" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16031, -- "installed":true, -- "interface":"eth-rt2-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16031, -- "installed":true, -- "interface":"eth-rt5" -- } -- ] -- }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.6.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.7.6" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt6" -- } -- ] -- }, -- "16060":{ -- "inLabel":16060, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.7.6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16060, -- "nexthop":"10.0.6.5" -- } -- ] -- }, -- "16061":{ -- "inLabel":16061, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt6", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16061, -- "interface":"eth-rt5" -- } -- ] -- } - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref new file mode 100644 index 000000000000..0ef5d1bc3f82 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref.diff deleted file mode 100644 index 4385df2c3666..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ip_route.ref.diff +++ /dev/null @@ -1,367 +0,0 @@ ---- a/rt4/step4/show_ip_route.ref -+++ b/rt4/step5/show_ip_route.ref -@@ -14,14 +14,37 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 16010 -+ ] - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 16010 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16010 -+ ] - } - ] - } -@@ -41,14 +64,38 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16030, -+ 16020 -+ ] - } - ] - } -@@ -68,21 +115,30 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16030 -+ ] - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16030 -+ ] - }, - { - "fib":true, - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true -+ "active":true, -+ "labels":[ -+ 16030 -+ ] - } - ] - } -@@ -102,7 +158,24 @@ - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.7.6", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt6", -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } -@@ -122,7 +195,24 @@ - "ip":"10.0.7.6", - "afi":"ipv4", - "interfaceName":"eth-rt6", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16060 -+ ] - } - ] - } -@@ -142,13 +232,27 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "fib":true, - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5", - "active":true - } - ] -@@ -164,13 +268,30 @@ - { - "ip":"10.0.2.2", - "afi":"ipv4", -- "interfaceName":"eth-rt2-1" -+ "interfaceName":"eth-rt2-1", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.3.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16030 -+ ] - } - ] - } -@@ -186,12 +307,29 @@ - "ip":"10.0.2.2", - "afi":"ipv4", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.3.2", - "afi":"ipv4", -- "interfaceName":"eth-rt2-2" -+ "interfaceName":"eth-rt2-2", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16030 -+ ] - } - ] - } -@@ -211,6 +349,31 @@ - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -+ "active":true, -+ "backupIndex":[ -+ 0, -+ 1, -+ 2 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.7.6", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt6", -+ "active":true -+ }, -+ { -+ "ip":"10.0.2.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt2-1", -+ "active":true -+ }, -+ { -+ "ip":"10.0.3.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt2-2", - "active":true - } - ] -@@ -231,6 +394,31 @@ - "ip":"10.0.6.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -+ "active":true, -+ "backupIndex":[ -+ 0, -+ 1, -+ 2 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.7.6", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt6", -+ "active":true -+ }, -+ { -+ "ip":"10.0.2.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt2-1", -+ "active":true -+ }, -+ { -+ "ip":"10.0.3.2", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt2-2", - "active":true - } - ] -@@ -246,7 +434,18 @@ - { - "ip":"10.0.6.5", - "afi":"ipv4", -- "interfaceName":"eth-rt5" -+ "interfaceName":"eth-rt5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.7.6", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt6", -+ "active":true - } - ] - } -@@ -261,7 +460,18 @@ - { - "ip":"10.0.7.6", - "afi":"ipv4", -- "interfaceName":"eth-rt6" -+ "interfaceName":"eth-rt6", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.5", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt5", -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref new file mode 100644 index 000000000000..c757031881e2 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref.diff deleted file mode 100644 index 54a1dc23c510..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_ipv6_route.ref.diff +++ /dev/null @@ -1,161 +0,0 @@ ---- a/rt4/step4/show_ipv6_route.ref -+++ b/rt4/step5/show_ipv6_route.ref -@@ -13,13 +13,35 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 16011 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 16011 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16011 -+ ] - } - ] - } -@@ -38,13 +60,36 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16031, -+ 16021 -+ ] - } - ] - } -@@ -63,19 +108,28 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-2", -- "active":true -+ "active":true, -+ "labels":[ -+ 16031 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt2-1", -- "active":true -+ "active":true, -+ "labels":[ -+ 16031 -+ ] - }, - { - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5", -- "active":true -+ "active":true, -+ "labels":[ -+ 16031 -+ ] - } - ] - } -@@ -94,7 +148,23 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt5", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt6", -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - } - ] - } -@@ -113,7 +183,23 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt6", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ], -+ "labels":[ -+ 3 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt5", -+ "active":true, -+ "labels":[ -+ 16061 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref new file mode 100644 index 000000000000..2a709070e472 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.6", + "interface":"eth-rt6" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref.diff deleted file mode 100644 index fb6a1192813b..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step5/show_mpls_table.ref.diff +++ /dev/null @@ -1,265 +0,0 @@ ---- a/rt4/step4/show_mpls_table.ref -+++ b/rt4/step5/show_mpls_table.ref -@@ -1,2 +1,262 @@ - { -+ "16010":{ -+ "inLabel":16010, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16010, -+ "installed":true, -+ "nexthop":"10.0.3.2", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16010, -+ "installed":true, -+ "nexthop":"10.0.2.2", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16010, -+ "nexthop":"10.0.6.5" -+ } -+ ] -+ }, -+ "16011":{ -+ "inLabel":16011, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16011, -+ "installed":true, -+ "interface":"eth-rt2-2", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16011, -+ "installed":true, -+ "interface":"eth-rt2-1", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16011, -+ "interface":"eth-rt5" -+ } -+ ] -+ }, -+ "16020":{ -+ "inLabel":16020, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.3.2", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.2.2", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16030, -+ "nexthop":"10.0.6.5" -+ } -+ ] -+ }, -+ "16021":{ -+ "inLabel":16021, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt2-2", -+ "backupIndex":[ -+ 0 -+ ] -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt2-1", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16031, -+ "interface":"eth-rt5" -+ } -+ ] -+ }, -+ "16030":{ -+ "inLabel":16030, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16030, -+ "installed":true, -+ "nexthop":"10.0.3.2" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16030, -+ "installed":true, -+ "nexthop":"10.0.2.2" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16030, -+ "installed":true, -+ "nexthop":"10.0.6.5" -+ } -+ ] -+ }, -+ "16031":{ -+ "inLabel":16031, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16031, -+ "installed":true, -+ "interface":"eth-rt2-2" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16031, -+ "installed":true, -+ "interface":"eth-rt2-1" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16031, -+ "installed":true, -+ "interface":"eth-rt5" -+ } -+ ] -+ }, -+ "16050":{ -+ "inLabel":16050, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.6.5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.7.6" -+ } -+ ] -+ }, -+ "16051":{ -+ "inLabel":16051, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt6" -+ } -+ ] -+ }, -+ "16060":{ -+ "inLabel":16060, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.7.6", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16060, -+ "nexthop":"10.0.6.5" -+ } -+ ] -+ }, -+ "16061":{ -+ "inLabel":16061, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt6", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16061, -+ "interface":"eth-rt5" -+ } -+ ] -+ } - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref new file mode 100644 index 000000000000..89e556edd372 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref.diff deleted file mode 100644 index 9070414730e0..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ip_route.ref.diff +++ /dev/null @@ -1,56 +0,0 @@ ---- a/rt4/step5/show_ip_route.ref -+++ b/rt4/step6/show_ip_route.ref -@@ -43,7 +43,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16010 -+ 30010 - ] - } - ] -@@ -93,7 +93,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16030, -+ 30030, - 16020 - ] - } -@@ -137,7 +137,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16030 -+ 30030 - ] - } - ] -@@ -211,7 +211,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16060 -+ 30060 - ] - } - ] -@@ -290,7 +290,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16030 -+ 30030 - ] - } - ] -@@ -328,7 +328,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16030 -+ 30030 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref new file mode 100644 index 000000000000..12479fadb8a4 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref.diff deleted file mode 100644 index 57a57647a17e..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_ipv6_route.ref.diff +++ /dev/null @@ -1,38 +0,0 @@ ---- a/rt4/step5/show_ipv6_route.ref -+++ b/rt4/step6/show_ipv6_route.ref -@@ -40,7 +40,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16011 -+ 30011 - ] - } - ] -@@ -87,7 +87,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16031, -+ 30031, - 16021 - ] - } -@@ -128,7 +128,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16031 -+ 30031 - ] - } - ] -@@ -198,7 +198,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16061 -+ 30061 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref new file mode 100644 index 000000000000..6693de7666dd --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30010, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30011, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.6", + "interface":"eth-rt6" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref.diff deleted file mode 100644 index 94f87854d170..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step6/show_mpls_table.ref.diff +++ /dev/null @@ -1,74 +0,0 @@ ---- a/rt4/step5/show_mpls_table.ref -+++ b/rt4/step6/show_mpls_table.ref -@@ -25,7 +25,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16010, -+ "outLabel":30010, - "nexthop":"10.0.6.5" - } - ] -@@ -56,7 +56,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16011, -+ "outLabel":30011, - "interface":"eth-rt5" - } - ] -@@ -87,7 +87,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16030, -+ "outLabel":30030, - "nexthop":"10.0.6.5" - } - ] -@@ -118,7 +118,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16031, -+ "outLabel":30031, - "interface":"eth-rt5" - } - ] -@@ -141,7 +141,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":16030, -+ "outLabel":30030, - "installed":true, - "nexthop":"10.0.6.5" - } -@@ -165,7 +165,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":16031, -+ "outLabel":30031, - "installed":true, - "interface":"eth-rt5" - } -@@ -232,7 +232,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16060, -+ "outLabel":30060, - "nexthop":"10.0.6.5" - } - ] -@@ -254,7 +254,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16061, -+ "outLabel":30061, - "interface":"eth-rt5" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref new file mode 100644 index 000000000000..f90e7f4f57a2 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref @@ -0,0 +1,500 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref.diff deleted file mode 100644 index e54873d5ab59..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ip_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt4/step6/show_ip_route.ref -+++ b/rt4/step7/show_ip_route.ref -@@ -161,9 +161,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -172,10 +169,7 @@ - "ip":"10.0.7.6", - "afi":"ipv4", - "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref new file mode 100644 index 000000000000..f55d6ba94966 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref @@ -0,0 +1,201 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref.diff deleted file mode 100644 index 92e08f99a065..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_ipv6_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt4/step6/show_ipv6_route.ref -+++ b/rt4/step7/show_ipv6_route.ref -@@ -151,9 +151,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -161,10 +158,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref new file mode 100644 index 000000000000..e6a73be2ef81 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref @@ -0,0 +1,229 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30010, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30011, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref.diff deleted file mode 100644 index fb614ebf6a8a..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step7/show_mpls_table.ref.diff +++ /dev/null @@ -1,53 +0,0 @@ ---- a/rt4/step6/show_mpls_table.ref -+++ b/rt4/step7/show_mpls_table.ref -@@ -171,50 +171,6 @@ - } - ] - }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.6.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.7.6" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt6" -- } -- ] -- }, - "16060":{ - "inLabel":16060, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref new file mode 100644 index 000000000000..89e556edd372 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref.diff deleted file mode 100644 index 252da6e76417..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ip_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt4/step7/show_ip_route.ref -+++ b/rt4/step8/show_ip_route.ref -@@ -161,6 +161,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -169,7 +172,10 @@ - "ip":"10.0.7.6", - "afi":"ipv4", - "interfaceName":"eth-rt6", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref new file mode 100644 index 000000000000..12479fadb8a4 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref.diff deleted file mode 100644 index 7057d2166a0c..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_ipv6_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt4/step7/show_ipv6_route.ref -+++ b/rt4/step8/show_ipv6_route.ref -@@ -151,6 +151,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -158,7 +161,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt6", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref new file mode 100644 index 000000000000..6693de7666dd --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30010, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30011, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.6", + "interface":"eth-rt6" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref.diff deleted file mode 100644 index 3dc4303b9b4d..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step8/show_mpls_table.ref.diff +++ /dev/null @@ -1,53 +0,0 @@ ---- a/rt4/step7/show_mpls_table.ref -+++ b/rt4/step8/show_mpls_table.ref -@@ -171,6 +171,50 @@ - } - ] - }, -+ "16050":{ -+ "inLabel":16050, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.6.5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.7.6" -+ } -+ ] -+ }, -+ "16051":{ -+ "inLabel":16051, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt6" -+ } -+ ] -+ }, - "16060":{ - "inLabel":16060, - "installed":true, diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref new file mode 100644 index 000000000000..1a084c77425a --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030, + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16030 + ] + }, + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30030 + ] + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.2.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-1", + "active":true + }, + { + "ip":"10.0.3.2", + "afi":"ipv4", + "interfaceName":"eth-rt2-2", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + }, + { + "fib":true, + "ip":"10.0.7.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref.diff deleted file mode 100644 index 56f9cc534f95..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ip_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt4/step8/show_ip_route.ref -+++ b/rt4/step9/show_ip_route.ref -@@ -174,7 +174,7 @@ - "interfaceName":"eth-rt6", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref new file mode 100644 index 000000000000..1b08fde03ca7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031, + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-1", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt2-2", + "active":true, + "labels":[ + 16031 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30031 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16501 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref.diff deleted file mode 100644 index 41e552177a2f..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_ipv6_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt4/step8/show_ipv6_route.ref -+++ b/rt4/step9/show_ipv6_route.ref -@@ -163,7 +163,7 @@ - "interfaceName":"eth-rt6", - "active":true, - "labels":[ -- 16051 -+ 16501 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref new file mode 100644 index 000000000000..2c8ea080911a --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30010, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30011, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt2-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.3.2", + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.2.2", + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt2-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30060, + "nexthop":"10.0.6.5", + "interface":"eth-rt5" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30061, + "interface":"eth-rt5" + } + ] + }, + "16500":{ + "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "nexthop":"10.0.7.6", + "interface":"eth-rt6" + } + ] + }, + "16501":{ + "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "interface":"eth-rt6" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref.diff deleted file mode 100644 index 627e292518fa..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt4/step9/show_mpls_table.ref.diff +++ /dev/null @@ -1,110 +0,0 @@ ---- a/rt4/step8/show_mpls_table.ref -+++ b/rt4/step9/show_mpls_table.ref -@@ -171,15 +171,15 @@ - } - ] - }, -- "16050":{ -- "inLabel":16050, -+ "16060":{ -+ "inLabel":16060, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.6.5", -+ "nexthop":"10.0.7.6", - "backupIndex":[ - 0 - ] -@@ -188,20 +188,20 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.7.6" -+ "outLabel":30060, -+ "nexthop":"10.0.6.5" - } - ] - }, -- "16051":{ -- "inLabel":16051, -+ "16061":{ -+ "inLabel":16061, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt5", -+ "interface":"eth-rt6", - "backupIndex":[ - 0 - ] -@@ -210,20 +210,20 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt6" -+ "outLabel":30061, -+ "interface":"eth-rt5" - } - ] - }, -- "16060":{ -- "inLabel":16060, -+ "16500":{ -+ "inLabel":16500, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.7.6", -+ "nexthop":"10.0.6.5", - "backupIndex":[ - 0 - ] -@@ -232,20 +232,20 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30060, -- "nexthop":"10.0.6.5" -+ "outLabel":16500, -+ "nexthop":"10.0.7.6" - } - ] - }, -- "16061":{ -- "inLabel":16061, -+ "16501":{ -+ "inLabel":16501, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt6", -+ "interface":"eth-rt5", - "backupIndex":[ - 0 - ] -@@ -254,8 +254,8 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":30061, -- "interface":"eth-rt5" -+ "outLabel":16501, -+ "interface":"eth-rt6" - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step1/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step1/show_ipv6_route.ref index 6dafa69adb8f..168828dcc40e 100644 --- a/tests/topotests/isis_tilfa_topo1/rt5/step1/show_ipv6_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt5/step1/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt3-2", + "interfaceName":"eth-rt3-1", "active":true, "backupIndex":[ 0 @@ -24,7 +24,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt3-1", + "interfaceName":"eth-rt3-2", "active":true, "backupIndex":[ 0 @@ -59,7 +59,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt3-1", "active":true, "labels":[ 16021 @@ -77,7 +77,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt3-1", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16021 @@ -99,7 +99,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt3-2", + "interfaceName":"eth-rt3-1", "active":true, "backupIndex":[ 0 @@ -111,7 +111,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt3-1", + "interfaceName":"eth-rt3-2", "active":true, "backupIndex":[ 0 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step1/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step1/show_mpls_table.ref index 0c5861b5e89d..14de03d3f347 100644 --- a/tests/topotests/isis_tilfa_topo1/rt5/step1/show_mpls_table.ref +++ b/tests/topotests/isis_tilfa_topo1/rt5/step1/show_mpls_table.ref @@ -8,6 +8,7 @@ "outLabel":16010, "installed":true, "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", "backupIndex":[ 0 ] @@ -17,6 +18,7 @@ "outLabel":16010, "installed":true, "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", "backupIndex":[ 0 ] @@ -26,7 +28,8 @@ { "type":"SR (IS-IS)", "outLabel":16010, - "nexthop":"10.0.6.4" + "nexthop":"10.0.6.4", + "interface":"eth-rt4" } ] }, @@ -69,19 +72,22 @@ "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.5.3" + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.4.3" + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" }, { "type":"SR (IS-IS)", "outLabel":16020, "installed":true, - "nexthop":"10.0.6.4" + "nexthop":"10.0.6.4", + "interface":"eth-rt4" } ] }, @@ -118,6 +124,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", "backupIndex":[ 0 ] @@ -127,6 +134,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", "backupIndex":[ 0 ] @@ -136,7 +144,8 @@ { "type":"SR (IS-IS)", "outLabel":16020, - "nexthop":"10.0.6.4" + "nexthop":"10.0.6.4", + "interface":"eth-rt4" } ] }, @@ -180,6 +189,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.6.4", + "interface":"eth-rt4", "backupIndex":[ 0 ] @@ -189,7 +199,8 @@ { "type":"SR (IS-IS)", "outLabel":16040, - "nexthop":"10.0.8.6" + "nexthop":"10.0.8.6", + "interface":"eth-rt6" } ] }, @@ -224,6 +235,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.8.6", + "interface":"eth-rt6", "backupIndex":[ 0 ] @@ -233,7 +245,8 @@ { "type":"SR (IS-IS)", "outLabel":16060, - "nexthop":"10.0.6.4" + "nexthop":"10.0.6.4", + "interface":"eth-rt4" } ] }, diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref index fcaf5e6d6086..06f432c455de 100644 --- a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref @@ -467,10 +467,14 @@ { "prefix":"10.0.8.0\/24", "protocol":"isis", + "selected":true, + "destSelected":true, "distance":115, "metric":30, + "installed":true, "nexthops":[ { + "fib":true, "ip":"10.0.6.4", "afi":"ipv4", "interfaceName":"eth-rt4", diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref index d193e1e86b0d..bc39e119b2b1 100644 --- a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ipv6_route.ref @@ -150,8 +150,7 @@ "interfaceName":"eth-rt4", "active":true, "backupIndex":[ - 0, - 1 + 0 ], "labels":[ 3 @@ -161,19 +160,9 @@ "backupNexthops":[ { "afi":"ipv6", - "interfaceName":"eth-rt3-1", + "interfaceName":"eth-rt6", "active":true, "labels":[ - 16021, - 16041 - ] - }, - { - "afi":"ipv6", - "interfaceName":"eth-rt3-2", - "active":true, - "labels":[ - 16021, 16041 ] } @@ -195,31 +184,7 @@ "afi":"ipv6", "interfaceName":"eth-rt4", "active":true, - "backupIndex":[ - 0, - 1 - ], - "labels":[ - 16061 - ] - } - ], - "backupNexthops":[ - { - "afi":"ipv6", - "interfaceName":"eth-rt3-1", - "active":true, "labels":[ - 16021, - 16061 - ] - }, - { - "afi":"ipv6", - "interfaceName":"eth-rt3-2", - "active":true, - "labels":[ - 16021, 16061 ] } diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ip_route.ref new file mode 100644 index 000000000000..93740e22e0c7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ipv6_route.ref new file mode 100644 index 000000000000..168828dcc40e --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step2/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_mpls_table.ref new file mode 100644 index 000000000000..14de03d3f347 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.6", + "interface":"eth-rt6" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step2/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step2/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ip_route.ref new file mode 100644 index 000000000000..93740e22e0c7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ipv6_route.ref new file mode 100644 index 000000000000..168828dcc40e --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step3/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_mpls_table.ref new file mode 100644 index 000000000000..14de03d3f347 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.6", + "interface":"eth-rt6" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step3/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step3/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref new file mode 100644 index 000000000000..b5bd8c7a5c98 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref @@ -0,0 +1,439 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1" + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2" + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref.diff deleted file mode 100644 index 7545a31b9b05..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ip_route.ref.diff +++ /dev/null @@ -1,161 +0,0 @@ ---- a/rt5/step3/show_ip_route.ref -+++ b/rt5/step4/show_ip_route.ref -@@ -41,10 +41,7 @@ - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16010 -- ] -+ "active":true - } - ] - } -@@ -84,10 +81,7 @@ - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16020 -- ] -+ "active":true - } - ] - } -@@ -108,9 +102,6 @@ - "afi":"ipv4", - "interfaceName":"eth-rt3-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] -@@ -121,25 +112,10 @@ - "afi":"ipv4", - "interfaceName":"eth-rt3-2", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16020, -- 16030 -- ] -- } - ] - } - ], -@@ -161,9 +137,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -172,10 +145,7 @@ - "ip":"10.0.8.6", - "afi":"ipv4", - "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - } - ] - } -@@ -209,10 +179,7 @@ - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16060 -- ] -+ "active":true - } - ] - } -@@ -358,30 +325,13 @@ - { - "ip":"10.0.4.3", - "afi":"ipv4", -- "interfaceName":"eth-rt3-1", -- "backupIndex":[ -- 0 -- ] -+ "interfaceName":"eth-rt3-1" - }, - { - "ip":"10.0.5.3", - "afi":"ipv4", - "interfaceName":"eth-rt3-2", -- "active":true, -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16020 -- ] -+ "active":true - } - ] - } -@@ -397,29 +347,12 @@ - "ip":"10.0.4.3", - "afi":"ipv4", - "interfaceName":"eth-rt3-1", -- "active":true, -- "backupIndex":[ -- 0 -- ] -+ "active":true - }, - { - "ip":"10.0.5.3", - "afi":"ipv4", -- "interfaceName":"eth-rt3-2", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "ip":"10.0.6.4", -- "afi":"ipv4", -- "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16020 -- ] -+ "interfaceName":"eth-rt3-2" - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref new file mode 100644 index 000000000000..647add85f51d --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref @@ -0,0 +1,175 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 3 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref.diff deleted file mode 100644 index 1de62bb58e18..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_ipv6_route.ref.diff +++ /dev/null @@ -1,95 +0,0 @@ ---- a/rt5/step3/show_ipv6_route.ref -+++ b/rt5/step4/show_ipv6_route.ref -@@ -38,10 +38,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16011 -- ] -+ "active":true - } - ] - } -@@ -60,10 +57,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16021 -- ] -+ "active":true - }, - { - "fib":true, -@@ -101,9 +95,6 @@ - "afi":"ipv6", - "interfaceName":"eth-rt3-2", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] -@@ -113,24 +104,10 @@ - "afi":"ipv6", - "interfaceName":"eth-rt3-1", - "active":true, -- "backupIndex":[ -- 0 -- ], - "labels":[ - 3 - ] - } -- ], -- "backupNexthops":[ -- { -- "afi":"ipv6", -- "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16021, -- 16031 -- ] -- } - ] - } - ], -@@ -151,9 +128,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -161,10 +135,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt6", -- "active":true, -- "labels":[ -- 16041 -- ] -+ "active":true - } - ] - } -@@ -196,10 +167,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16061 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref new file mode 100644 index 000000000000..cfb0bf2fd747 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref @@ -0,0 +1,189 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref.diff deleted file mode 100644 index b3d525243052..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step4/show_mpls_table.ref.diff +++ /dev/null @@ -1,166 +0,0 @@ ---- a/rt5/step3/show_mpls_table.ref -+++ b/rt5/step4/show_mpls_table.ref -@@ -25,7 +25,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16010, -+ "outLabel":3, - "nexthop":"10.0.6.4" - } - ] -@@ -56,7 +56,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16011, -+ "outLabel":3, - "interface":"eth-rt4" - } - ] -@@ -76,12 +76,6 @@ - "outLabel":16020, - "installed":true, - "nexthop":"10.0.4.3" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16020, -- "installed":true, -- "nexthop":"10.0.6.4" - } - ] - }, -@@ -100,12 +94,6 @@ - "outLabel":16021, - "installed":true, - "interface":"eth-rt3-1" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16021, -- "installed":true, -- "interface":"eth-rt4" - } - ] - }, -@@ -117,26 +105,13 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.5.3", -- "backupIndex":[ -- 0 -- ] -+ "nexthop":"10.0.5.3" - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.4.3", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16020, -- "nexthop":"10.0.6.4" -+ "nexthop":"10.0.4.3" - } - ] - }, -@@ -148,70 +123,13 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt3-2", -- "backupIndex":[ -- 0 -- ] -+ "interface":"eth-rt3-2" - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt3-1", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16021, -- "interface":"eth-rt4" -- } -- ] -- }, -- "16040":{ -- "inLabel":16040, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.6.4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.8.6" -- } -- ] -- }, -- "16041":{ -- "inLabel":16041, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-rt6" -+ "interface":"eth-rt3-1" - } - ] - }, -@@ -232,7 +150,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16060, -+ "outLabel":3, - "nexthop":"10.0.6.4" - } - ] -@@ -254,7 +172,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16061, -+ "outLabel":3, - "interface":"eth-rt4" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref new file mode 100644 index 000000000000..93740e22e0c7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref.diff deleted file mode 100644 index be5d83f46357..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ip_route.ref.diff +++ /dev/null @@ -1,161 +0,0 @@ ---- a/rt5/step4/show_ip_route.ref -+++ b/rt5/step5/show_ip_route.ref -@@ -41,7 +41,10 @@ - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16010 -+ ] - } - ] - } -@@ -81,7 +84,10 @@ - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16020 -+ ] - } - ] - } -@@ -102,6 +108,9 @@ - "afi":"ipv4", - "interfaceName":"eth-rt3-1", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] -@@ -112,10 +121,25 @@ - "afi":"ipv4", - "interfaceName":"eth-rt3-2", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4", -+ "active":true, -+ "labels":[ -+ 16020, -+ 16030 -+ ] -+ } - ] - } - ], -@@ -137,6 +161,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -145,7 +172,10 @@ - "ip":"10.0.8.6", - "afi":"ipv4", - "interfaceName":"eth-rt6", -- "active":true -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } -@@ -179,7 +209,10 @@ - "ip":"10.0.6.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16060 -+ ] - } - ] - } -@@ -325,13 +358,30 @@ - { - "ip":"10.0.4.3", - "afi":"ipv4", -- "interfaceName":"eth-rt3-1" -+ "interfaceName":"eth-rt3-1", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.5.3", - "afi":"ipv4", - "interfaceName":"eth-rt3-2", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4", -+ "active":true, -+ "labels":[ -+ 16020 -+ ] - } - ] - } -@@ -347,12 +397,29 @@ - "ip":"10.0.4.3", - "afi":"ipv4", - "interfaceName":"eth-rt3-1", -- "active":true -+ "active":true, -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "ip":"10.0.5.3", - "afi":"ipv4", -- "interfaceName":"eth-rt3-2" -+ "interfaceName":"eth-rt3-2", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "ip":"10.0.6.4", -+ "afi":"ipv4", -+ "interfaceName":"eth-rt4", -+ "active":true, -+ "labels":[ -+ 16020 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref new file mode 100644 index 000000000000..168828dcc40e --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref.diff deleted file mode 100644 index a856019622d4..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_ipv6_route.ref.diff +++ /dev/null @@ -1,95 +0,0 @@ ---- a/rt5/step4/show_ipv6_route.ref -+++ b/rt5/step5/show_ipv6_route.ref -@@ -38,7 +38,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16011 -+ ] - } - ] - } -@@ -57,7 +60,10 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16021 -+ ] - }, - { - "fib":true, -@@ -95,6 +101,9 @@ - "afi":"ipv6", - "interfaceName":"eth-rt3-2", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] -@@ -104,10 +113,24 @@ - "afi":"ipv6", - "interfaceName":"eth-rt3-1", - "active":true, -+ "backupIndex":[ -+ 0 -+ ], - "labels":[ - 3 - ] - } -+ ], -+ "backupNexthops":[ -+ { -+ "afi":"ipv6", -+ "interfaceName":"eth-rt4", -+ "active":true, -+ "labels":[ -+ 16021, -+ 16031 -+ ] -+ } - ] - } - ], -@@ -128,6 +151,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -135,7 +161,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt6", -- "active":true -+ "active":true, -+ "labels":[ -+ 16041 -+ ] - } - ] - } -@@ -167,7 +196,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16061 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref new file mode 100644 index 000000000000..d40be3d11e81 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.6", + "interface":"eth-rt6" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt6" + } + ] + }, + "16060":{ + "inLabel":16060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "16061":{ + "inLabel":16061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref.diff deleted file mode 100644 index 74caa8620e61..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step5/show_mpls_table.ref.diff +++ /dev/null @@ -1,166 +0,0 @@ ---- a/rt5/step4/show_mpls_table.ref -+++ b/rt5/step5/show_mpls_table.ref -@@ -25,7 +25,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16010, - "nexthop":"10.0.6.4" - } - ] -@@ -56,7 +56,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16011, - "interface":"eth-rt4" - } - ] -@@ -69,6 +69,12 @@ - "type":"SR (IS-IS)", - "outLabel":16020, - "installed":true, -+ "nexthop":"10.0.6.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16020, -+ "installed":true, - "nexthop":"10.0.5.3" - }, - { -@@ -87,6 +93,12 @@ - "type":"SR (IS-IS)", - "outLabel":16021, - "installed":true, -+ "interface":"eth-rt4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16021, -+ "installed":true, - "interface":"eth-rt3-2" - }, - { -@@ -105,13 +117,26 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.5.3" -+ "nexthop":"10.0.5.3", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "nexthop":"10.0.4.3" -+ "nexthop":"10.0.4.3", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16020, -+ "nexthop":"10.0.6.4" - } - ] - }, -@@ -123,13 +148,70 @@ - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt3-2" -+ "interface":"eth-rt3-2", -+ "backupIndex":[ -+ 0 -+ ] - }, - { - "type":"SR (IS-IS)", - "outLabel":3, - "installed":true, -- "interface":"eth-rt3-1" -+ "interface":"eth-rt3-1", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16021, -+ "interface":"eth-rt4" -+ } -+ ] -+ }, -+ "16040":{ -+ "inLabel":16040, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.6.4", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.8.6" -+ } -+ ] -+ }, -+ "16041":{ -+ "inLabel":16041, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt4", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-rt6" - } - ] - }, -@@ -150,7 +232,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16060, - "nexthop":"10.0.6.4" - } - ] -@@ -172,7 +254,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16061, - "interface":"eth-rt4" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ip_route.ref new file mode 100644 index 000000000000..93740e22e0c7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ipv6_route.ref new file mode 100644 index 000000000000..168828dcc40e --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref new file mode 100644 index 000000000000..a21038bf9d38 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "30010":{ + "inLabel":30010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30011":{ + "inLabel":30011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "30020":{ + "inLabel":30020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30021":{ + "inLabel":30021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "30030":{ + "inLabel":30030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30031":{ + "inLabel":30031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "30040":{ + "inLabel":30040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.6", + "interface":"eth-rt6" + } + ] + }, + "30041":{ + "inLabel":30041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt6" + } + ] + }, + "30060":{ + "inLabel":30060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30061":{ + "inLabel":30061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref.diff deleted file mode 100644 index 2883c046fd50..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt5/step6/show_mpls_table.ref.diff +++ /dev/null @@ -1,146 +0,0 @@ ---- a/rt5/step5/show_mpls_table.ref -+++ b/rt5/step6/show_mpls_table.ref -@@ -1,6 +1,6 @@ - { -- "16010":{ -- "inLabel":16010, -+ "30010":{ -+ "inLabel":30010, - "installed":true, - "nexthops":[ - { -@@ -30,8 +30,8 @@ - } - ] - }, -- "16011":{ -- "inLabel":16011, -+ "30011":{ -+ "inLabel":30011, - "installed":true, - "nexthops":[ - { -@@ -61,56 +61,56 @@ - } - ] - }, -- "16020":{ -- "inLabel":16020, -+ "30020":{ -+ "inLabel":30020, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", - "outLabel":16020, - "installed":true, -- "nexthop":"10.0.6.4" -+ "nexthop":"10.0.5.3" - }, - { - "type":"SR (IS-IS)", - "outLabel":16020, - "installed":true, -- "nexthop":"10.0.5.3" -+ "nexthop":"10.0.4.3" - }, - { - "type":"SR (IS-IS)", - "outLabel":16020, - "installed":true, -- "nexthop":"10.0.4.3" -+ "nexthop":"10.0.6.4" - } - ] - }, -- "16021":{ -- "inLabel":16021, -+ "30021":{ -+ "inLabel":30021, - "installed":true, - "nexthops":[ - { - "type":"SR (IS-IS)", - "outLabel":16021, - "installed":true, -- "interface":"eth-rt4" -+ "interface":"eth-rt3-2" - }, - { - "type":"SR (IS-IS)", - "outLabel":16021, - "installed":true, -- "interface":"eth-rt3-2" -+ "interface":"eth-rt3-1" - }, - { - "type":"SR (IS-IS)", - "outLabel":16021, - "installed":true, -- "interface":"eth-rt3-1" -+ "interface":"eth-rt4" - } - ] - }, -- "16030":{ -- "inLabel":16030, -+ "30030":{ -+ "inLabel":30030, - "installed":true, - "nexthops":[ - { -@@ -140,8 +140,8 @@ - } - ] - }, -- "16031":{ -- "inLabel":16031, -+ "30031":{ -+ "inLabel":30031, - "installed":true, - "nexthops":[ - { -@@ -171,8 +171,8 @@ - } - ] - }, -- "16040":{ -- "inLabel":16040, -+ "30040":{ -+ "inLabel":30040, - "installed":true, - "nexthops":[ - { -@@ -193,8 +193,8 @@ - } - ] - }, -- "16041":{ -- "inLabel":16041, -+ "30041":{ -+ "inLabel":30041, - "installed":true, - "nexthops":[ - { -@@ -215,8 +215,8 @@ - } - ] - }, -- "16060":{ -- "inLabel":16060, -+ "30060":{ -+ "inLabel":30060, - "installed":true, - "nexthops":[ - { -@@ -237,8 +237,8 @@ - } - ] - }, -- "16061":{ -- "inLabel":16061, -+ "30061":{ -+ "inLabel":30061, - "installed":true, - "nexthops":[ - { diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ip_route.ref new file mode 100644 index 000000000000..93740e22e0c7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ipv6_route.ref new file mode 100644 index 000000000000..168828dcc40e --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step7/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_mpls_table.ref new file mode 100644 index 000000000000..a21038bf9d38 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "30010":{ + "inLabel":30010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30011":{ + "inLabel":30011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "30020":{ + "inLabel":30020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30021":{ + "inLabel":30021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "30030":{ + "inLabel":30030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30031":{ + "inLabel":30031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "30040":{ + "inLabel":30040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.6", + "interface":"eth-rt6" + } + ] + }, + "30041":{ + "inLabel":30041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt6" + } + ] + }, + "30060":{ + "inLabel":30060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30061":{ + "inLabel":30061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step7/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step7/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ip_route.ref new file mode 100644 index 000000000000..93740e22e0c7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ipv6_route.ref new file mode 100644 index 000000000000..168828dcc40e --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step8/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_mpls_table.ref new file mode 100644 index 000000000000..a21038bf9d38 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "30010":{ + "inLabel":30010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30011":{ + "inLabel":30011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "30020":{ + "inLabel":30020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30021":{ + "inLabel":30021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "30030":{ + "inLabel":30030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30031":{ + "inLabel":30031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "30040":{ + "inLabel":30040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.6", + "interface":"eth-rt6" + } + ] + }, + "30041":{ + "inLabel":30041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt6" + } + ] + }, + "30060":{ + "inLabel":30060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30061":{ + "inLabel":30061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step8/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step8/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ip_route.ref new file mode 100644 index 000000000000..93740e22e0c7 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ip_route.ref @@ -0,0 +1,506 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16010 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16020 + ] + }, + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020, + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "6.6.6.6\/32":[ + { + "prefix":"6.6.6.6\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16060 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "fib":true, + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0, + 1, + 2 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + }, + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.4.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ] + }, + { + "ip":"10.0.5.3", + "afi":"ipv4", + "interfaceName":"eth-rt3-2", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.6", + "afi":"ipv4", + "interfaceName":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.6.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ipv6_route.ref new file mode 100644 index 000000000000..168828dcc40e --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ipv6_route.ref @@ -0,0 +1,207 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16011 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "labels":[ + 16021 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-1", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt3-2", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16021, + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::6\/128":[ + { + "prefix":"2001:db8:1000::6\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt6", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16061 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step9/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_mpls_table.ref new file mode 100644 index 000000000000..a21038bf9d38 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_mpls_table.ref @@ -0,0 +1,275 @@ +{ + "30010":{ + "inLabel":30010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30011":{ + "inLabel":30011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "interface":"eth-rt4" + } + ] + }, + "30020":{ + "inLabel":30020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30021":{ + "inLabel":30021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-2" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt3-1" + }, + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "30030":{ + "inLabel":30030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.5.3", + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.4.3", + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30031":{ + "inLabel":30031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-2", + "backupIndex":[ + 0 + ] + }, + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt3-1", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt4" + } + ] + }, + "30040":{ + "inLabel":30040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.6.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.6", + "interface":"eth-rt6" + } + ] + }, + "30041":{ + "inLabel":30041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt6" + } + ] + }, + "30060":{ + "inLabel":30060, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.6", + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16060, + "nexthop":"10.0.6.4", + "interface":"eth-rt4" + } + ] + }, + "30061":{ + "inLabel":30061, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt6", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16061, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step9/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt5/step9/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step1/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step1/show_ipv6_route.ref index 1b1942939ddc..de31816fe533 100644 --- a/tests/topotests/isis_tilfa_topo1/rt6/step1/show_ipv6_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt6/step1/show_ipv6_route.ref @@ -12,7 +12,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt4", + "interfaceName":"eth-rt5", "active":true, "labels":[ 16011 @@ -21,7 +21,7 @@ { "fib":true, "afi":"ipv6", - "interfaceName":"eth-rt5", + "interfaceName":"eth-rt4", "active":true, "labels":[ 16011 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step1/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step1/show_mpls_table.ref index 5b52a16f48df..4bd85c36b943 100644 --- a/tests/topotests/isis_tilfa_topo1/rt6/step1/show_mpls_table.ref +++ b/tests/topotests/isis_tilfa_topo1/rt6/step1/show_mpls_table.ref @@ -7,13 +7,15 @@ "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.8.5" + "nexthop":"10.0.8.5", + "interface":"eth-rt5" }, { "type":"SR (IS-IS)", "outLabel":16010, "installed":true, - "nexthop":"10.0.7.4" + "nexthop":"10.0.7.4", + "interface":"eth-rt4" } ] }, @@ -44,6 +46,7 @@ "outLabel":16020, "installed":true, "nexthop":"10.0.7.4", + "interface":"eth-rt4", "backupIndex":[ 0 ] @@ -53,7 +56,8 @@ { "type":"SR (IS-IS)", "outLabel":16020, - "nexthop":"10.0.8.5" + "nexthop":"10.0.8.5", + "interface":"eth-rt5" } ] }, @@ -88,6 +92,7 @@ "outLabel":16030, "installed":true, "nexthop":"10.0.8.5", + "interface":"eth-rt5", "backupIndex":[ 0 ] @@ -97,7 +102,8 @@ { "type":"SR (IS-IS)", "outLabel":16030, - "nexthop":"10.0.7.4" + "nexthop":"10.0.7.4", + "interface":"eth-rt4" } ] }, @@ -132,6 +138,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.7.4", + "interface":"eth-rt4", "backupIndex":[ 0 ] @@ -141,7 +148,8 @@ { "type":"SR (IS-IS)", "outLabel":16040, - "nexthop":"10.0.8.5" + "nexthop":"10.0.8.5", + "interface":"eth-rt5" } ] }, @@ -176,6 +184,7 @@ "outLabel":3, "installed":true, "nexthop":"10.0.8.5", + "interface":"eth-rt5", "backupIndex":[ 0 ] @@ -185,7 +194,8 @@ { "type":"SR (IS-IS)", "outLabel":16050, - "nexthop":"10.0.7.4" + "nexthop":"10.0.7.4", + "interface":"eth-rt4" } ] }, diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref index c7e79852fbeb..7a87f447ccd7 100644 --- a/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt6/step10/show_ipv6_route.ref @@ -9,6 +9,15 @@ "metric":40, "installed":true, "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + }, { "fib":true, "afi":"ipv6", @@ -36,10 +45,23 @@ "afi":"ipv6", "interfaceName":"eth-rt4", "active":true, + "backupIndex":[ + 0 + ], "labels":[ 16021 ] } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30021 + ] + } ] } ], @@ -80,10 +102,23 @@ "afi":"ipv6", "interfaceName":"eth-rt4", "active":true, + "backupIndex":[ + 0 + ], "labels":[ 3 ] } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30041 + ] + } ] } ], diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ip_route.ref new file mode 100644 index 000000000000..b9b43c413927 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ip_route.ref @@ -0,0 +1,413 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ipv6_route.ref new file mode 100644 index 000000000000..de31816fe533 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ipv6_route.ref @@ -0,0 +1,173 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step2/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_mpls_table.ref new file mode 100644 index 000000000000..4bd85c36b943 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_mpls_table.ref @@ -0,0 +1,224 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step2/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step2/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ip_route.ref new file mode 100644 index 000000000000..b9b43c413927 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ip_route.ref @@ -0,0 +1,413 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ip_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ipv6_route.ref new file mode 100644 index 000000000000..de31816fe533 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ipv6_route.ref @@ -0,0 +1,173 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_ipv6_route.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step3/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_mpls_table.ref new file mode 100644 index 000000000000..4bd85c36b943 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_mpls_table.ref @@ -0,0 +1,224 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt5" + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step3/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step3/show_mpls_table.ref.diff deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref new file mode 100644 index 000000000000..d34a28ee0f00 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref @@ -0,0 +1,395 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref.diff deleted file mode 100644 index 7c2f00419ab0..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ip_route.ref.diff +++ /dev/null @@ -1,70 +0,0 @@ ---- a/rt6/step3/show_ip_route.ref -+++ b/rt6/step4/show_ip_route.ref -@@ -14,10 +14,7 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16010 -- ] -+ "active":true - }, - { - "fib":true, -@@ -50,9 +47,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 16020 - ] - } - ], -@@ -98,10 +92,7 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16030 -- ] -+ "active":true - } - ] - } -@@ -124,9 +115,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -135,10 +123,7 @@ - "ip":"10.0.8.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16040 -- ] -+ "active":true - } - ] - } -@@ -172,10 +157,7 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref new file mode 100644 index 000000000000..2527c85bf862 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref @@ -0,0 +1,155 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref.diff deleted file mode 100644 index 70f872e9de36..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_ipv6_route.ref.diff +++ /dev/null @@ -1,70 +0,0 @@ ---- a/rt6/step3/show_ipv6_route.ref -+++ b/rt6/step4/show_ipv6_route.ref -@@ -13,10 +13,7 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16011 -- ] -+ "active":true - }, - { - "fib":true, -@@ -47,9 +44,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 16021 - ] - } - ], -@@ -92,10 +86,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16031 -- ] -+ "active":true - } - ] - } -@@ -117,9 +108,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -127,10 +115,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt5", -- "active":true, -- "labels":[ -- 16041 -- ] -+ "active":true - } - ] - } -@@ -162,10 +147,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref new file mode 100644 index 000000000000..5cac9257053b --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref @@ -0,0 +1,165 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref.diff deleted file mode 100644 index c191763a73f7..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step4/show_mpls_table.ref.diff +++ /dev/null @@ -1,109 +0,0 @@ ---- a/rt6/step3/show_mpls_table.ref -+++ b/rt6/step4/show_mpls_table.ref -@@ -8,12 +8,6 @@ - "outLabel":16010, - "installed":true, - "nexthop":"10.0.8.5" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16010, -- "installed":true, -- "nexthop":"10.0.7.4" - } - ] - }, -@@ -26,12 +20,6 @@ - "outLabel":16011, - "installed":true, - "interface":"eth-rt5" -- }, -- { -- "type":"SR (IS-IS)", -- "outLabel":16011, -- "installed":true, -- "interface":"eth-rt4" - } - ] - }, -@@ -96,7 +84,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16030, -+ "outLabel":3, - "nexthop":"10.0.7.4" - } - ] -@@ -118,52 +106,8 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16031, -- "interface":"eth-rt4" -- } -- ] -- }, -- "16040":{ -- "inLabel":16040, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.7.4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16040, -- "nexthop":"10.0.8.5" -- } -- ] -- }, -- "16041":{ -- "inLabel":16041, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", - "outLabel":3, -- "installed":true, -- "interface":"eth-rt4", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16041, -- "interface":"eth-rt5" -+ "interface":"eth-rt4" - } - ] - }, -@@ -184,7 +128,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16050, -+ "outLabel":3, - "nexthop":"10.0.7.4" - } - ] -@@ -206,7 +150,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16051, -+ "outLabel":3, - "interface":"eth-rt4" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref new file mode 100644 index 000000000000..b9b43c413927 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref @@ -0,0 +1,413 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref.diff deleted file mode 100644 index 9f017d24925b..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ip_route.ref.diff +++ /dev/null @@ -1,70 +0,0 @@ ---- a/rt6/step4/show_ip_route.ref -+++ b/rt6/step5/show_ip_route.ref -@@ -14,7 +14,10 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16010 -+ ] - }, - { - "fib":true, -@@ -47,6 +50,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 16020 - ] - } - ], -@@ -92,7 +98,10 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16030 -+ ] - } - ] - } -@@ -115,6 +124,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -123,7 +135,10 @@ - "ip":"10.0.8.5", - "afi":"ipv4", - "interfaceName":"eth-rt5", -- "active":true -+ "active":true, -+ "labels":[ -+ 16040 -+ ] - } - ] - } -@@ -157,7 +172,10 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref new file mode 100644 index 000000000000..de31816fe533 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref @@ -0,0 +1,173 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 16041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref.diff deleted file mode 100644 index 1209504e9425..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_ipv6_route.ref.diff +++ /dev/null @@ -1,70 +0,0 @@ ---- a/rt6/step4/show_ipv6_route.ref -+++ b/rt6/step5/show_ipv6_route.ref -@@ -13,7 +13,10 @@ - "fib":true, - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16011 -+ ] - }, - { - "fib":true, -@@ -44,6 +47,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 16021 - ] - } - ], -@@ -86,7 +92,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16031 -+ ] - } - ] - } -@@ -108,6 +117,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -115,7 +127,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt5", -- "active":true -+ "active":true, -+ "labels":[ -+ 16041 -+ ] - } - ] - } -@@ -147,7 +162,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref new file mode 100644 index 000000000000..ef2310f03f9c --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref @@ -0,0 +1,224 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16040, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16041, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref.diff deleted file mode 100644 index abf7c2a32d73..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step5/show_mpls_table.ref.diff +++ /dev/null @@ -1,112 +0,0 @@ ---- a/rt6/step4/show_mpls_table.ref -+++ b/rt6/step5/show_mpls_table.ref -@@ -7,6 +7,12 @@ - "type":"SR (IS-IS)", - "outLabel":16010, - "installed":true, -+ "nexthop":"10.0.7.4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16010, -+ "installed":true, - "nexthop":"10.0.8.5" - } - ] -@@ -19,6 +25,12 @@ - "type":"SR (IS-IS)", - "outLabel":16011, - "installed":true, -+ "interface":"eth-rt4" -+ }, -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16011, -+ "installed":true, - "interface":"eth-rt5" - } - ] -@@ -84,7 +96,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16030, - "nexthop":"10.0.7.4" - } - ] -@@ -106,11 +118,55 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16031, - "interface":"eth-rt4" - } - ] - }, -+ "16040":{ -+ "inLabel":16040, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.7.4", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16040, -+ "nexthop":"10.0.8.5" -+ } -+ ] -+ }, -+ "16041":{ -+ "inLabel":16041, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt4", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16041, -+ "interface":"eth-rt5" -+ } -+ ] -+ }, - "16050":{ - "inLabel":16050, - "installed":true, -@@ -128,7 +184,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16050, - "nexthop":"10.0.7.4" - } - ] -@@ -150,7 +206,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":3, -+ "outLabel":16051, - "interface":"eth-rt4" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref new file mode 100644 index 000000000000..ca39251e4ac1 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref @@ -0,0 +1,413 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref.diff deleted file mode 100644 index f318f95e212b..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ip_route.ref.diff +++ /dev/null @@ -1,38 +0,0 @@ ---- a/rt6/step5/show_ip_route.ref -+++ b/rt6/step6/show_ip_route.ref -@@ -26,7 +26,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16010 -+ 30010 - ] - } - ] -@@ -63,7 +63,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16020 -+ 30020 - ] - } - ] -@@ -89,7 +89,7 @@ - 0 - ], - "labels":[ -- 16030 -+ 30030 - ] - } - ], -@@ -137,7 +137,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16040 -+ 30040 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref new file mode 100644 index 000000000000..4a42ec9df83f --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref @@ -0,0 +1,173 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref.diff deleted file mode 100644 index 9208491fc824..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_ipv6_route.ref.diff +++ /dev/null @@ -1,38 +0,0 @@ ---- a/rt6/step5/show_ipv6_route.ref -+++ b/rt6/step6/show_ipv6_route.ref -@@ -24,7 +24,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16011 -+ 30011 - ] - } - ] -@@ -59,7 +59,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16021 -+ 30021 - ] - } - ] -@@ -84,7 +84,7 @@ - 0 - ], - "labels":[ -- 16031 -+ 30031 - ] - } - ], -@@ -129,7 +129,7 @@ - "interfaceName":"eth-rt5", - "active":true, - "labels":[ -- 16041 -+ 30041 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref new file mode 100644 index 000000000000..edbe78aa98ab --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref @@ -0,0 +1,224 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30011, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref.diff deleted file mode 100644 index aee8969deddc..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step6/show_mpls_table.ref.diff +++ /dev/null @@ -1,74 +0,0 @@ ---- a/rt6/step5/show_mpls_table.ref -+++ b/rt6/step6/show_mpls_table.ref -@@ -11,7 +11,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":16010, -+ "outLabel":30010, - "installed":true, - "nexthop":"10.0.8.5" - } -@@ -29,7 +29,7 @@ - }, - { - "type":"SR (IS-IS)", -- "outLabel":16011, -+ "outLabel":30011, - "installed":true, - "interface":"eth-rt5" - } -@@ -52,7 +52,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16020, -+ "outLabel":30020, - "nexthop":"10.0.8.5" - } - ] -@@ -74,7 +74,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16021, -+ "outLabel":30021, - "interface":"eth-rt5" - } - ] -@@ -85,7 +85,7 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16030, -+ "outLabel":30030, - "installed":true, - "nexthop":"10.0.8.5", - "backupIndex":[ -@@ -107,7 +107,7 @@ - "nexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16031, -+ "outLabel":30031, - "installed":true, - "interface":"eth-rt5", - "backupIndex":[ -@@ -140,7 +140,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16040, -+ "outLabel":30040, - "nexthop":"10.0.8.5" - } - ] -@@ -162,7 +162,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16041, -+ "outLabel":30041, - "interface":"eth-rt5" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref new file mode 100644 index 000000000000..ee47c1aa9305 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref @@ -0,0 +1,407 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref.diff deleted file mode 100644 index 0e6c3ff5cd54..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ip_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt6/step6/show_ip_route.ref -+++ b/rt6/step7/show_ip_route.ref -@@ -161,9 +161,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -172,10 +169,7 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16050 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref new file mode 100644 index 000000000000..c5ef607aeb64 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref @@ -0,0 +1,167 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref.diff deleted file mode 100644 index 2fe46c82658a..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_ipv6_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt6/step6/show_ipv6_route.ref -+++ b/rt6/step7/show_ipv6_route.ref -@@ -152,9 +152,6 @@ - "active":true, - "backupIndex":[ - 0 -- ], -- "labels":[ -- 3 - ] - } - ], -@@ -162,10 +159,7 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true, -- "labels":[ -- 16051 -- ] -+ "active":true - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref new file mode 100644 index 000000000000..ad965cee679b --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref @@ -0,0 +1,178 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30011, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref.diff deleted file mode 100644 index 179a4f460b2a..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step7/show_mpls_table.ref.diff +++ /dev/null @@ -1,52 +0,0 @@ ---- a/rt6/step6/show_mpls_table.ref -+++ b/rt6/step7/show_mpls_table.ref -@@ -166,49 +166,5 @@ - "interface":"eth-rt5" - } - ] -- }, -- "16050":{ -- "inLabel":16050, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "nexthop":"10.0.8.5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16050, -- "nexthop":"10.0.7.4" -- } -- ] -- }, -- "16051":{ -- "inLabel":16051, -- "installed":true, -- "nexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":3, -- "installed":true, -- "interface":"eth-rt5", -- "backupIndex":[ -- 0 -- ] -- } -- ], -- "backupNexthops":[ -- { -- "type":"SR (IS-IS)", -- "outLabel":16051, -- "interface":"eth-rt4" -- } -- ] - } - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref new file mode 100644 index 000000000000..ca39251e4ac1 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref @@ -0,0 +1,413 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16050 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref.diff deleted file mode 100644 index 9d5c440a2215..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ip_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt6/step7/show_ip_route.ref -+++ b/rt6/step8/show_ip_route.ref -@@ -161,6 +161,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -169,7 +172,10 @@ - "ip":"10.0.7.4", - "afi":"ipv4", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16050 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref new file mode 100644 index 000000000000..4a42ec9df83f --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref @@ -0,0 +1,173 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16051 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref.diff deleted file mode 100644 index 21cab20a470a..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_ipv6_route.ref.diff +++ /dev/null @@ -1,24 +0,0 @@ ---- a/rt6/step7/show_ipv6_route.ref -+++ b/rt6/step8/show_ipv6_route.ref -@@ -152,6 +152,9 @@ - "active":true, - "backupIndex":[ - 0 -+ ], -+ "labels":[ -+ 3 - ] - } - ], -@@ -159,7 +162,10 @@ - { - "afi":"ipv6", - "interfaceName":"eth-rt4", -- "active":true -+ "active":true, -+ "labels":[ -+ 16051 -+ ] - } - ] - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref new file mode 100644 index 000000000000..edbe78aa98ab --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref @@ -0,0 +1,224 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30011, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5" + } + ] + }, + "16050":{ + "inLabel":16050, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16050, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16051":{ + "inLabel":16051, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16051, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref.diff deleted file mode 100644 index 760c5542cb7e..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step8/show_mpls_table.ref.diff +++ /dev/null @@ -1,52 +0,0 @@ ---- a/rt6/step7/show_mpls_table.ref -+++ b/rt6/step8/show_mpls_table.ref -@@ -166,5 +166,49 @@ - "interface":"eth-rt5" - } - ] -+ }, -+ "16050":{ -+ "inLabel":16050, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "nexthop":"10.0.8.5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16050, -+ "nexthop":"10.0.7.4" -+ } -+ ] -+ }, -+ "16051":{ -+ "inLabel":16051, -+ "installed":true, -+ "nexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":3, -+ "installed":true, -+ "interface":"eth-rt5", -+ "backupIndex":[ -+ 0 -+ ] -+ } -+ ], -+ "backupNexthops":[ -+ { -+ "type":"SR (IS-IS)", -+ "outLabel":16051, -+ "interface":"eth-rt4" -+ } -+ ] - } - } diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref new file mode 100644 index 000000000000..879d595c884b --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref @@ -0,0 +1,413 @@ +{ + "1.1.1.1\/32":[ + { + "prefix":"1.1.1.1\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16010 + ] + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30010 + ] + } + ] + } + ], + "2.2.2.2\/32":[ + { + "prefix":"2.2.2.2\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16020 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30020 + ] + } + ] + } + ], + "3.3.3.3\/32":[ + { + "prefix":"3.3.3.3\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30030 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16030 + ] + } + ] + } + ], + "4.4.4.4\/32":[ + { + "prefix":"4.4.4.4\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30040 + ] + } + ] + } + ], + "5.5.5.5\/32":[ + { + "prefix":"5.5.5.5\/32", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16500 + ] + } + ] + } + ], + "10.0.1.0\/24":[ + { + "prefix":"10.0.1.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.2.0\/24":[ + { + "prefix":"10.0.2.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.3.0\/24":[ + { + "prefix":"10.0.3.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.4.0\/24":[ + { + "prefix":"10.0.4.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.5.0\/24":[ + { + "prefix":"10.0.5.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ], + "10.0.6.0\/24":[ + { + "prefix":"10.0.6.0\/24", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + }, + { + "fib":true, + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.7.0\/24":[ + { + "prefix":"10.0.7.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "active":true + } + ] + } + ], + "10.0.8.0\/24":[ + { + "prefix":"10.0.8.0\/24", + "protocol":"isis", + "distance":115, + "metric":20, + "nexthops":[ + { + "ip":"10.0.8.5", + "afi":"ipv4", + "interfaceName":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "ip":"10.0.7.4", + "afi":"ipv4", + "interfaceName":"eth-rt4", + "active":true + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref.diff deleted file mode 100644 index ee296470c0cc..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ip_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt6/step8/show_ip_route.ref -+++ b/rt6/step9/show_ip_route.ref -@@ -174,7 +174,7 @@ - "interfaceName":"eth-rt4", - "active":true, - "labels":[ -- 16050 -+ 16500 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref new file mode 100644 index 000000000000..e8a72001d195 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref @@ -0,0 +1,173 @@ +{ + "2001:db8:1000::1\/128":[ + { + "prefix":"2001:db8:1000::1\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":40, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30011 + ] + }, + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16011 + ] + } + ] + } + ], + "2001:db8:1000::2\/128":[ + { + "prefix":"2001:db8:1000::2\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 16021 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30021 + ] + } + ] + } + ], + "2001:db8:1000::3\/128":[ + { + "prefix":"2001:db8:1000::3\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":30, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 30031 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16031 + ] + } + ] + } + ], + "2001:db8:1000::4\/128":[ + { + "prefix":"2001:db8:1000::4\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "labels":[ + 30041 + ] + } + ] + } + ], + "2001:db8:1000::5\/128":[ + { + "prefix":"2001:db8:1000::5\/128", + "protocol":"isis", + "selected":true, + "destSelected":true, + "distance":115, + "metric":20, + "installed":true, + "nexthops":[ + { + "fib":true, + "afi":"ipv6", + "interfaceName":"eth-rt5", + "active":true, + "backupIndex":[ + 0 + ], + "labels":[ + 3 + ] + } + ], + "backupNexthops":[ + { + "afi":"ipv6", + "interfaceName":"eth-rt4", + "active":true, + "labels":[ + 16501 + ] + } + ] + } + ] +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref.diff deleted file mode 100644 index bebca4dcf189..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_ipv6_route.ref.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- a/rt6/step8/show_ipv6_route.ref -+++ b/rt6/step9/show_ipv6_route.ref -@@ -164,7 +164,7 @@ - "interfaceName":"eth-rt4", - "active":true, - "labels":[ -- 16051 -+ 16501 - ] - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref new file mode 100644 index 000000000000..4b6c4eebfea9 --- /dev/null +++ b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref @@ -0,0 +1,224 @@ +{ + "16010":{ + "inLabel":16010, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16010, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30010, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16011":{ + "inLabel":16011, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16011, + "installed":true, + "interface":"eth-rt4" + }, + { + "type":"SR (IS-IS)", + "outLabel":30011, + "installed":true, + "interface":"eth-rt5" + } + ] + }, + "16020":{ + "inLabel":16020, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16020, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30020, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16021":{ + "inLabel":16021, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16021, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30021, + "interface":"eth-rt5" + } + ] + }, + "16030":{ + "inLabel":16030, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30030, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16030, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16031":{ + "inLabel":16031, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30031, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16031, + "interface":"eth-rt4" + } + ] + }, + "16040":{ + "inLabel":16040, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.7.4", + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30040, + "nexthop":"10.0.8.5", + "interface":"eth-rt5" + } + ] + }, + "16041":{ + "inLabel":16041, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt4", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":30041, + "interface":"eth-rt5" + } + ] + }, + "16500":{ + "inLabel":16500, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "nexthop":"10.0.8.5", + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16500, + "nexthop":"10.0.7.4", + "interface":"eth-rt4" + } + ] + }, + "16501":{ + "inLabel":16501, + "installed":true, + "nexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":3, + "installed":true, + "interface":"eth-rt5", + "backupIndex":[ + 0 + ] + } + ], + "backupNexthops":[ + { + "type":"SR (IS-IS)", + "outLabel":16501, + "interface":"eth-rt4" + } + ] + } +} diff --git a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref.diff b/tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref.diff deleted file mode 100644 index 57347d15beed..000000000000 --- a/tests/topotests/isis_tilfa_topo1/rt6/step9/show_mpls_table.ref.diff +++ /dev/null @@ -1,39 +0,0 @@ ---- a/rt6/step8/show_mpls_table.ref -+++ b/rt6/step9/show_mpls_table.ref -@@ -167,8 +167,8 @@ - } - ] - }, -- "16050":{ -- "inLabel":16050, -+ "16500":{ -+ "inLabel":16500, - "installed":true, - "nexthops":[ - { -@@ -184,13 +184,13 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16050, -+ "outLabel":16500, - "nexthop":"10.0.7.4" - } - ] - }, -- "16051":{ -- "inLabel":16051, -+ "16501":{ -+ "inLabel":16501, - "installed":true, - "nexthops":[ - { -@@ -206,7 +206,7 @@ - "backupNexthops":[ - { - "type":"SR (IS-IS)", -- "outLabel":16051, -+ "outLabel":16501, - "interface":"eth-rt4" - } - ] diff --git a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py index 2f5a5898afdd..aaf6af0be4cb 100755 --- a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py +++ b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py @@ -56,6 +56,7 @@ import json import tempfile from functools import partial +from time import sleep # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -120,54 +121,6 @@ def build_topo(tgen): switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6") switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5") - # - # Populate multi-dimensional dictionary containing all expected outputs - # - files = [ - "show_ip_route.ref", - "show_ipv6_route.ref", - "show_mpls_table.ref", - "show_yang_interface_isis_adjacencies.ref", - ] - for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: - outputs[rname] = {} - for step in range(1, 9 + 1): - outputs[rname][step] = {} - for file in files: - if step == 1: - # Get snapshots relative to the expected initial network convergence - filename = "{}/{}/step{}/{}".format(CWD, rname, step, file) - outputs[rname][step][file] = open(filename).read() - else: - if file == "show_yang_interface_isis_adjacencies.ref": - continue - - # Get diff relative to the previous step - filename = "{}/{}/step{}/{}.diff".format(CWD, rname, step, file) - - # Create temporary files in order to apply the diff - f_in = tempfile.NamedTemporaryFile(mode="w") - f_in.write(outputs[rname][step - 1][file]) - f_in.flush() - f_out = tempfile.NamedTemporaryFile(mode="r") - os.system( - "patch -s -o %s %s %s" % (f_out.name, f_in.name, filename) - ) - - # Store the updated snapshot and remove the temporary files - outputs[rname][step][file] = open(f_out.name).read() - f_in.close() - f_out.close() - # HACK: use full snapshots for step 10 - step = 10 - for rname in ["rt5", "rt6"]: - outputs[rname][step] = {} - for file in files: - if file == "show_yang_interface_isis_adjacencies.ref": - continue - filename = "{}/{}/step{}/{}".format(CWD, rname, step, file) - outputs[rname][step][file] = open(filename).read() - def setup_module(mod): "Sets up the pytest environment" @@ -199,12 +152,174 @@ def teardown_module(mod): tgen.stop_topology() -def router_compare_json_output(rname, command, reference, count=120, wait=0.5): +def filter_json(data, keys_to_keep): + """ + Filters a dictionary, keeping only the specified keys. + """ + return {k: v for k, v in data.items() if k in keys_to_keep} + + +def regen_data(rname, command, step, file, wait): + """ + Regenerates reference data. + """ + # Sleep enough time to ensure the protocol has converged + if rname == "rt1": + sleep(wait) + if step == 10: + sleep(10) + + # Get and parse JSON output + tgen = get_topogen() + output = json.loads(tgen.gears[rname].vtysh_cmd(command)) + + # Default JSON separators + separators = (",", ":") + + # Process JSON output based on the specified file + if file == "show_yang_interface_isis_adjacencies.ref": + # Filter out the loopback interface + output["frr-interface:lib"]["interface"] = [ + interface + for interface in output["frr-interface:lib"]["interface"] + if interface["name"] != "lo" + ] + + # Filter out unwanted fields + for interface in output["frr-interface:lib"]["interface"]: + keys_to_keep = {"name", "vrf", "state"} + filtered_interface = filter_json(interface, keys_to_keep) + interface.clear() + interface.update(filtered_interface) + + keys_to_keep = {"frr-isisd:isis"} + filtered_state = filter_json(interface["state"], keys_to_keep) + interface["state"].clear() + interface["state"].update(filtered_state) + + keys_to_keep = {"adjacencies"} + filtered_isis = filter_json( + interface["state"]["frr-isisd:isis"], keys_to_keep + ) + interface["state"]["frr-isisd:isis"].clear() + interface["state"]["frr-isisd:isis"].update(filtered_isis) + if "adjacencies" in interface["state"]["frr-isisd:isis"]: + for adjacency in interface["state"]["frr-isisd:isis"]["adjacencies"][ + "adjacency" + ]: + keys_to_keep = { + "neighbor-sys-type", + "neighbor-sysid", + "hold-timer", + "neighbor-priority", + "state", + } + filtered_adjacency = filter_json(adjacency, keys_to_keep) + adjacency.clear() + adjacency.update(filtered_adjacency) + # Adjust separators to match libyang's output. + separators = (",", ": ") + + elif file == "show_ip_route.ref" or file == "show_ipv6_route.ref": + # Filter out unwanted fields + keys_to_keep_route = { + "prefix", + "protocol", + "selected", + "destSelected", + "distance", + "metric", + "installed", + "nexthops", + "backupNexthops", + } + keys_to_keep_nh = { + "fib", + "ip", + "afi", + "interfaceName", + "active", + "backupIndex", + "labels", + } + for prefix_key, prefix_value in output.items(): + filtered_routes = [] + for route in prefix_value: + if "nexthops" in route: + filtered_nhs = [] + for nh in route["nexthops"]: + if nh["ip"].startswith("fe80"): + del nh["ip"] + filtered_nhs.append(filter_json(nh, keys_to_keep_nh)) + route["nexthops"] = filtered_nhs + if "backupNexthops" in route: + filtered_nhs = [] + for nh in route["backupNexthops"]: + if nh["ip"].startswith("fe80"): + del nh["ip"] + filtered_nhs.append(filter_json(nh, keys_to_keep_nh)) + route["backupNexthops"] = filtered_nhs + filtered_routes.append(filter_json(route, keys_to_keep_route)) + output[prefix_key] = filtered_routes + + elif file == "show_mpls_table.ref": + # Filter out Adj-SID labels + output = {int(key): value for key, value in output.items() if int(key) >= 16000} + + # Filter out unwanted fields + keys_to_keep_label = { + "inLabel", + "installed", + "nexthops", + "backupNexthops", + } + keys_to_keep_nh = { + "type", + "outLabel", + "installed", + "interface", + "nexthop", + "backupIndex", + } + for label_key, label_value in output.items(): + if "nexthops" in label_value: + filtered_nhs = [] + for nh in label_value["nexthops"]: + if nh["nexthop"].startswith("fe80"): + del nh["nexthop"] + filtered_nhs.append(filter_json(nh, keys_to_keep_nh)) + label_value["nexthops"] = filtered_nhs + if "backupNexthops" in label_value: + filtered_nhs = [] + for nh in label_value["backupNexthops"]: + if nh["nexthop"].startswith("fe80"): + del nh["nexthop"] + filtered_nhs.append(filter_json(nh, keys_to_keep_nh)) + label_value["backupNexthops"] = filtered_nhs + output[label_key] = filter_json(label_value, keys_to_keep_label) + + elif file.startswith("show_bfd_peer"): + keys_to_keep = ["multihop", "peer", "interface", "status"] + output = filter_json(output, keys_to_keep) + + # Save the processed output to a file + filename = "{}/{}/step{}/{}".format(CWD, rname, step, file) + output = json.dumps(output, separators=separators, indent=2).replace("/", "\\/") + with open(filename, "w", encoding="ascii") as file: + file.write(output + "\n") + + +def router_compare_json_output(rname, command, step, file, count=120, wait=0.5): "Compare router JSON output" - logger.info('Comparing router "%s" "%s" output', rname, command) + # Regenerate reference data when the REGEN_DATA environment variable is set + if os.environ.get("REGEN_DATA") is not None: + regen_data(rname, command, step, file, count * wait) + return tgen = get_topogen() + logger.info('Comparing router "%s" "%s" output', rname, command) + reference = open("{}/{}/step{}/{}".format(CWD, rname, step, file)).read() expected = json.loads(reference) # Run test function until we get an result. Wait at most 60 seconds. @@ -231,7 +346,8 @@ def test_isis_adjacencies_step1(): router_compare_json_output( rname, "show yang operational-data /frr-interface:lib isisd", - outputs[rname][1]["show_yang_interface_isis_adjacencies.ref"], + 1, + "show_yang_interface_isis_adjacencies.ref", ) @@ -245,7 +361,7 @@ def test_rib_ipv4_step1(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][1]["show_ip_route.ref"] + rname, "show ip route isis json", 1, "show_ip_route.ref" ) @@ -259,7 +375,7 @@ def test_rib_ipv6_step1(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][1]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 1, "show_ipv6_route.ref" ) @@ -273,7 +389,7 @@ def test_mpls_lib_step1(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][1]["show_mpls_table.ref"] + rname, "show mpls table json", 1, "show_mpls_table.ref" ) @@ -301,7 +417,7 @@ def test_rib_ipv4_step2(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][2]["show_ip_route.ref"] + rname, "show ip route isis json", 2, "show_ip_route.ref" ) @@ -315,7 +431,7 @@ def test_rib_ipv6_step2(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][2]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 2, "show_ipv6_route.ref" ) @@ -329,7 +445,7 @@ def test_mpls_lib_step2(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][2]["show_mpls_table.ref"] + rname, "show mpls table json", 2, "show_mpls_table.ref" ) @@ -357,7 +473,7 @@ def test_rib_ipv4_step3(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][3]["show_ip_route.ref"] + rname, "show ip route isis json", 3, "show_ip_route.ref" ) @@ -371,7 +487,7 @@ def test_rib_ipv6_step3(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][3]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 3, "show_ipv6_route.ref" ) @@ -385,7 +501,7 @@ def test_mpls_lib_step3(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][3]["show_mpls_table.ref"] + rname, "show mpls table json", 3, "show_mpls_table.ref" ) @@ -418,7 +534,7 @@ def test_rib_ipv4_step4(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][4]["show_ip_route.ref"] + rname, "show ip route isis json", 4, "show_ip_route.ref" ) @@ -432,7 +548,7 @@ def test_rib_ipv6_step4(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][4]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 4, "show_ipv6_route.ref" ) @@ -446,7 +562,7 @@ def test_mpls_lib_step4(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][4]["show_mpls_table.ref"] + rname, "show mpls table json", 4, "show_mpls_table.ref" ) @@ -472,7 +588,7 @@ def test_rib_ipv4_step5(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][5]["show_ip_route.ref"] + rname, "show ip route isis json", 5, "show_ip_route.ref" ) @@ -486,7 +602,7 @@ def test_rib_ipv6_step5(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][5]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 5, "show_ipv6_route.ref" ) @@ -500,7 +616,7 @@ def test_mpls_lib_step5(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][5]["show_mpls_table.ref"] + rname, "show mpls table json", 5, "show_mpls_table.ref" ) @@ -528,7 +644,7 @@ def test_rib_ipv4_step6(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][6]["show_ip_route.ref"] + rname, "show ip route isis json", 6, "show_ip_route.ref" ) @@ -542,7 +658,7 @@ def test_rib_ipv6_step6(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][6]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 6, "show_ipv6_route.ref" ) @@ -556,7 +672,7 @@ def test_mpls_lib_step6(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][6]["show_mpls_table.ref"] + rname, "show mpls table json", 6, "show_mpls_table.ref" ) @@ -588,7 +704,7 @@ def test_rib_ipv4_step7(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][7]["show_ip_route.ref"] + rname, "show ip route isis json", 7, "show_ip_route.ref" ) @@ -602,7 +718,7 @@ def test_rib_ipv6_step7(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][7]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 7, "show_ipv6_route.ref" ) @@ -616,7 +732,7 @@ def test_mpls_lib_step7(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][7]["show_mpls_table.ref"] + rname, "show mpls table json", 7, "show_mpls_table.ref" ) @@ -647,7 +763,7 @@ def test_rib_ipv4_step8(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][8]["show_ip_route.ref"] + rname, "show ip route isis json", 8, "show_ip_route.ref" ) @@ -661,7 +777,7 @@ def test_rib_ipv6_step8(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][8]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 8, "show_ipv6_route.ref" ) @@ -675,7 +791,7 @@ def test_mpls_lib_step8(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][8]["show_mpls_table.ref"] + rname, "show mpls table json", 8, "show_mpls_table.ref" ) @@ -707,7 +823,7 @@ def test_rib_ipv4_step9(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][9]["show_ip_route.ref"] + rname, "show ip route isis json", 9, "show_ip_route.ref" ) @@ -721,7 +837,7 @@ def test_rib_ipv6_step9(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show ipv6 route isis json", outputs[rname][9]["show_ipv6_route.ref"] + rname, "show ipv6 route isis json", 9, "show_ipv6_route.ref" ) @@ -735,7 +851,7 @@ def test_mpls_lib_step9(): for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][9]["show_mpls_table.ref"] + rname, "show mpls table json", 9, "show_mpls_table.ref" ) @@ -768,13 +884,9 @@ def test_rib_ipv4_step10(): tgen.net["rt6"].cmd('vtysh -c "conf t" -c "int eth-rt5" -c "isis bfd"') logger.info("Checking if the BFD session is up") - expect = ( - '{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"up"}' - ) + expect = '{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"up"}' router_compare_json_output( - "rt6", - "show bfd peer 10.0.8.5 json", - expect, + "rt6", "show bfd peer 10.0.8.5 json", 10, "show_bfd_peer_up.ref" ) logger.info("Setting SPF delay-ietf initial delay to 60 seconds") @@ -793,14 +905,12 @@ def test_rib_ipv4_step10(): '{"multihop":false,"peer":"10.0.8.5","interface":"eth-rt5","status":"down"}' ) router_compare_json_output( - "rt6", - "show bfd peer 10.0.8.5 json", - expect, + "rt6", "show bfd peer 10.0.8.5 json", 10, "show_bfd_peer_down.ref" ) for rname in ["rt5", "rt6"]: router_compare_json_output( - rname, "show ip route isis json", outputs[rname][10]["show_ip_route.ref"] + rname, "show ip route isis json", 10, "show_ip_route.ref" ) @@ -816,7 +926,8 @@ def test_rib_ipv6_step10(): router_compare_json_output( rname, "show ipv6 route isis json", - outputs[rname][10]["show_ipv6_route.ref"], + 10, + "show_ipv6_route.ref", ) @@ -830,7 +941,7 @@ def test_mpls_lib_step10(): for rname in ["rt5", "rt6"]: router_compare_json_output( - rname, "show mpls table json", outputs[rname][10]["show_mpls_table.ref"] + rname, "show mpls table json", 10, "show_mpls_table.ref" ) From 51f070028692260ea19b5ef0f489c56de5683bbc Mon Sep 17 00:00:00 2001 From: Volodymyr Huti Date: Mon, 13 Nov 2023 22:47:31 +0200 Subject: [PATCH 234/472] nhrp: add `cisco-authentication` password support Implemented: - handling 8 char long password, aka Cisco style. - minimal error inidication routine - test case, password change affects conection Signed-off-by: Volodymyr Huti --- doc/user/nhrpd.rst | 6 ++ nhrpd/nhrp_nhs.c | 4 +- nhrpd/nhrp_packet.c | 27 ++++-- nhrpd/nhrp_peer.c | 98 ++++++++++++++++++--- nhrpd/nhrp_shortcut.c | 4 +- nhrpd/nhrp_vty.c | 63 +++++++++++++ nhrpd/nhrpd.h | 10 ++- nhrpd/subdir.am | 4 + tests/topotests/nhrp_topo/r1/nhrpd.conf | 1 + tests/topotests/nhrp_topo/r2/nhrpd.conf | 1 + tests/topotests/nhrp_topo/test_nhrp_topo.py | 55 ++++++++++-- 11 files changed, 242 insertions(+), 31 deletions(-) diff --git a/doc/user/nhrpd.rst b/doc/user/nhrpd.rst index 54527a0c9a85..e0ba90fcc139 100644 --- a/doc/user/nhrpd.rst +++ b/doc/user/nhrpd.rst @@ -84,6 +84,12 @@ Configuring NHRP registration requests are sent. By default registrations are sent every one third of the holdtime. +.. clicmd:: ip nhrp authentication PASSWORD + + Enables Cisco style authentication on NHRP packets. This embeds the + plaintext password to the outgoing NHRP packets. + Maximum length of the is 8 characters. + .. clicmd:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local Map an IP address of a station to the station's NBMA address. diff --git a/nhrpd/nhrp_nhs.c b/nhrpd/nhrp_nhs.c index f779f93486d8..b8958ba22595 100644 --- a/nhrpd/nhrp_nhs.c +++ b/nhrpd/nhrp_nhs.c @@ -216,7 +216,7 @@ static void nhrp_reg_send_req(struct event *t) cie->holding_time = htons(if_ad->holdtime); cie->mtu = htons(if_ad->mtu); - nhrp_ext_request(zb, hdr, ifp); + nhrp_ext_request(zb, hdr); /* Cisco NAT detection extension */ if (sockunion_family(&r->proto_addr) != AF_UNSPEC) { @@ -240,7 +240,7 @@ static void nhrp_reg_send_req(struct event *t) cie->mtu = htons(if_ad->mtu); nhrp_ext_complete(zb, ext); - nhrp_packet_complete(zb, hdr); + nhrp_packet_complete(zb, hdr, ifp); nhrp_peer_send(r->peer, zb); zbuf_free(zb); } diff --git a/nhrpd/nhrp_packet.c b/nhrpd/nhrp_packet.c index c6bd3bbbde0d..71f5c2f00797 100644 --- a/nhrpd/nhrp_packet.c +++ b/nhrpd/nhrp_packet.c @@ -115,14 +115,32 @@ uint16_t nhrp_packet_calculate_checksum(const uint8_t *pdu, uint16_t len) return (~csum) & 0xffff; } -void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr) +void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr, + struct interface *ifp) { + nhrp_packet_complete_auth(zb, hdr, ifp, true); +} + +void nhrp_packet_complete_auth(struct zbuf *zb, struct nhrp_packet_header *hdr, + struct interface *ifp, bool auth) +{ + struct nhrp_interface *nifp = ifp->info; + struct zbuf *auth_token = nifp->auth_token; + struct nhrp_extension_header *dst; unsigned short size; + if (auth && auth_token) { + dst = nhrp_ext_push(zb, hdr, + NHRP_EXTENSION_AUTHENTICATION | + NHRP_EXTENSION_FLAG_COMPULSORY); + zbuf_copy_peek(zb, auth_token, zbuf_size(auth_token)); + nhrp_ext_complete(zb, dst); + } + if (hdr->extension_offset) nhrp_ext_push(zb, hdr, - NHRP_EXTENSION_END - | NHRP_EXTENSION_FLAG_COMPULSORY); + NHRP_EXTENSION_END | + NHRP_EXTENSION_FLAG_COMPULSORY); size = zb->tail - (uint8_t *)hdr; hdr->packet_size = htons(size); @@ -225,8 +243,7 @@ struct nhrp_extension_header *nhrp_ext_pull(struct zbuf *zb, return ext; } -void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr, - struct interface *ifp) +void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr) { /* Place holders for standard extensions */ nhrp_ext_push(zb, hdr, diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 6e7857c777a0..84fcdb069744 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -603,7 +603,7 @@ static void nhrp_handle_resolution_req(struct nhrp_packet_parser *pp) break; } } - nhrp_packet_complete(zb, hdr); + nhrp_packet_complete(zb, hdr, ifp); nhrp_peer_send(peer, zb); err: nhrp_peer_unref(peer); @@ -730,7 +730,8 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p) } } - nhrp_packet_complete(zb, hdr); + // auth ext was validated and copied from the request + nhrp_packet_complete_auth(zb, hdr, ifp, false); nhrp_peer_send(p->peer, zb); err: zbuf_free(zb); @@ -812,7 +813,7 @@ void nhrp_peer_send_indication(struct interface *ifp, uint16_t protocol_type, /* Payload is the packet causing indication */ zbuf_copy(zb, pkt, zbuf_used(pkt)); - nhrp_packet_complete(zb, hdr); + nhrp_packet_complete(zb, hdr, ifp); nhrp_peer_send(p, zb); nhrp_peer_unref(p); zbuf_free(zb); @@ -1063,7 +1064,8 @@ static void nhrp_peer_forward(struct nhrp_peer *p, nhrp_ext_complete(zb, dst); } - nhrp_packet_complete(zb, hdr); + // XXX: auth already handled ??? + nhrp_packet_complete_auth(zb, hdr, pp->ifp, false); nhrp_peer_send(p, zb); zbuf_free(zb); zbuf_free(zb_copy); @@ -1089,8 +1091,7 @@ static void nhrp_packet_debug(struct zbuf *zb, const char *dir) reply = packet_types[hdr->type].type == PACKET_REPLY; debugf(NHRP_DEBUG_COMMON, "%s %s(%d) %pSU -> %pSU", dir, - (packet_types[hdr->type].name ? packet_types[hdr->type].name - : "Unknown"), + (packet_types[hdr->type].name ? : "Unknown"), hdr->type, reply ? &dst_proto : &src_proto, reply ? &src_proto : &dst_proto); } @@ -1106,11 +1107,70 @@ static int proto2afi(uint16_t proto) return AF_UNSPEC; } -struct nhrp_route_info { - int local; - struct interface *ifp; - struct nhrp_vc *vc; -}; +static int nhrp_packet_send_error(struct nhrp_packet_parser *pp, + uint16_t indication_code, uint16_t offset) +{ + union sockunion src_proto, dst_proto; + struct nhrp_packet_header *hdr; + struct zbuf *zb; + + src_proto = pp->src_proto; + dst_proto = pp->dst_proto; + if (packet_types[pp->hdr->type].type != PACKET_REPLY) { + src_proto = pp->dst_proto; + dst_proto = pp->src_proto; + } + /* Create reply */ + zb = zbuf_alloc(1500); // XXX: hardcode -> calculation routine + hdr = nhrp_packet_push(zb, NHRP_PACKET_ERROR_INDICATION, &pp->src_nbma, + &src_proto, &dst_proto); + + hdr->u.error.code = indication_code; + hdr->u.error.offset = htons(offset); + hdr->flags = pp->hdr->flags; + hdr->hop_count = 0; // XXX: cisco returns 255 + + /* Payload is the packet causing error */ + /* Don`t add extension according to RFC */ + /* wireshark gives bad checksum, without exts */ + // pp->hdr->checksum = nhrp_packet_calculate_checksum(zbuf_used(&pp->payload)) + zbuf_put(zb, pp->hdr, sizeof(*pp->hdr)); + zbuf_copy(zb, &pp->payload, zbuf_used(&pp->payload)); + nhrp_packet_complete_auth(zb, hdr, pp->ifp, false); + + /* nhrp_packet_debug(zb, "SEND_ERROR"); */ + nhrp_peer_send(pp->peer, zb); + zbuf_free(zb); + return 0; +} + +static bool nhrp_connection_authorized(struct nhrp_packet_parser *pp) +{ + struct nhrp_cisco_authentication_extension *auth_ext; + struct nhrp_interface *nifp = pp->ifp->info; + struct zbuf *auth = nifp->auth_token; + struct nhrp_extension_header *ext; + struct zbuf *extensions, pl; + int cmp = 0; + + + extensions = zbuf_alloc(zbuf_used(&pp->extensions)); + zbuf_copy_peek(extensions, &pp->extensions, zbuf_used(&pp->extensions)); + while ((ext = nhrp_ext_pull(extensions, &pl)) != NULL) { + switch (htons(ext->type) & ~NHRP_EXTENSION_FLAG_COMPULSORY) { + case NHRP_EXTENSION_AUTHENTICATION: + cmp = memcmp(auth->buf, pl.buf, zbuf_size(auth)); + auth_ext = (struct nhrp_cisco_authentication_extension *) + auth->buf; + debugf(NHRP_DEBUG_COMMON, + "Processing Authentication Extension for (%s:%s|%d)", + auth_ext->secret, (const char *)pl.buf, cmp); + break; + } + } + zbuf_free(extensions); + return cmp == 0; +} void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb) { @@ -1191,10 +1251,20 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb) goto drop; } + /* RFC2332 5.3.4 - Authentication is always done pairwise on an NHRP + * hop-by-hop basis; i.e. regenerated at each hop. */ nhrp_packet_debug(zb, "Recv"); - - /* FIXME: Check authentication here. This extension needs to be - * pre-handled. */ + if (nifp->auth_token && + (hdr->type != NHRP_PACKET_ERROR_INDICATION || + hdr->u.error.code != NHRP_ERROR_AUTHENTICATION_FAILURE)) { + if (!nhrp_connection_authorized(&pp)) { + nhrp_packet_send_error(&pp, + NHRP_ERROR_AUTHENTICATION_FAILURE, + 0); + info = "authentication failure"; + goto drop; + } + } /* Figure out if this is local */ target_addr = (packet_types[hdr->type].type == PACKET_REPLY) diff --git a/nhrpd/nhrp_shortcut.c b/nhrpd/nhrp_shortcut.c index e83ce7f58f47..9b47d974c340 100644 --- a/nhrpd/nhrp_shortcut.c +++ b/nhrpd/nhrp_shortcut.c @@ -425,7 +425,7 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s) "Shortcut res_req: set cie ht to %u and mtu to %u. shortcut ht is %u", ntohs(cie->holding_time), ntohs(cie->mtu), s->holding_time); - nhrp_ext_request(zb, hdr, ifp); + nhrp_ext_request(zb, hdr); /* Cisco NAT detection extension */ hdr->flags |= htons(NHRP_FLAG_RESOLUTION_NAT); @@ -438,7 +438,7 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s) nhrp_ext_complete(zb, ext); } - nhrp_packet_complete(zb, hdr); + nhrp_packet_complete(zb, hdr, ifp); nhrp_peer_send(peer, zb); nhrp_peer_unref(peer); diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index 40d38c44d272..66659bdcdb92 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -12,6 +12,9 @@ #include "nhrpd.h" #include "netlink.h" +#include "nhrp_protocol.h" + +#include "nhrpd/nhrp_vty_clippy.c" static int nhrp_config_write(struct vty *vty); static struct cmd_node zebra_node = { @@ -459,6 +462,56 @@ DEFUN(if_no_nhrp_holdtime, if_no_nhrp_holdtime_cmd, return CMD_SUCCESS; } +#define NHRP_CISCO_PASS_LEN 8 +DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd, + AFI_CMD "nhrp authentication PASSWORD$password", + AFI_STR + NHRP_STR + "Specify plaint text password used for authenticantion\n" + "Password, plain text, limited to 8 characters\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct nhrp_cisco_authentication_extension *auth; + struct nhrp_interface *nifp = ifp->info; + int pass_len = strlen(password); + + if (pass_len > NHRP_CISCO_PASS_LEN) { + vty_out(vty, "Password size limit exceeded (%d>%d)\n", + pass_len, NHRP_CISCO_PASS_LEN); + return CMD_WARNING_CONFIG_FAILED; + } + + if (nifp->auth_token) + zbuf_free(nifp->auth_token); + + nifp->auth_token = zbuf_alloc(pass_len + sizeof(uint32_t)); + auth = (struct nhrp_cisco_authentication_extension *) + nifp->auth_token->buf; + auth->type = htonl(NHRP_AUTHENTICATION_PLAINTEXT); + memcpy(auth->secret, password, pass_len); + + // XXX RFC: reset active (non-authorized) connections? + /* vty_out(vty, "NHRP passwd (%s:%s)", nifp->ifp->name, auth->secret); */ + return CMD_SUCCESS; +} + + +DEFPY(if_no_nhrp_authentication, if_no_nhrp_authentication_cmd, + "no " AFI_CMD "nhrp authentication PASSWORD$password", + NO_STR + AFI_STR + NHRP_STR + "Reset password used for authentication\n" + "Password, plain text\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct nhrp_interface *nifp = ifp->info; + if (nifp->auth_token) + zbuf_free(nifp->auth_token); + return CMD_SUCCESS; +} + + DEFUN(if_nhrp_mtu, if_nhrp_mtu_cmd, "ip nhrp mtu <(576-1500)|opennhrp>", IP_STR @@ -1053,6 +1106,7 @@ DEFUN(show_dmvpn, show_dmvpn_cmd, static void clear_nhrp_cache(struct nhrp_cache *c, void *data) { struct info_ctx *ctx = data; + if (c->cur.type <= NHRP_CACHE_DYNAMIC) { nhrp_cache_update_binding(c, c->cur.type, -1, NULL, 0, NULL, NULL); @@ -1129,6 +1183,7 @@ static void interface_config_write_nhrp_map(struct nhrp_cache_config *c, static int interface_config_write(struct vty *vty) { struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct nhrp_cisco_authentication_extension *auth; struct write_map_ctx mapctx; struct interface *ifp; struct nhrp_interface *nifp; @@ -1155,6 +1210,12 @@ static int interface_config_write(struct vty *vty) if (nifp->source) vty_out(vty, " tunnel source %s\n", nifp->source); + if (nifp->auth_token) { + auth = (struct nhrp_cisco_authentication_extension *) + nifp->auth_token->buf; + vty_out(vty, " ip nhrp authentication %s\n", auth->secret); + } + for (afi = 0; afi < AFI_MAX; afi++) { struct nhrp_afi_data *ad = &nifp->afi[afi]; @@ -1256,6 +1317,8 @@ void nhrp_config_init(void) install_element(INTERFACE_NODE, &if_no_nhrp_network_id_cmd); install_element(INTERFACE_NODE, &if_nhrp_holdtime_cmd); install_element(INTERFACE_NODE, &if_no_nhrp_holdtime_cmd); + install_element(INTERFACE_NODE, &if_nhrp_authentication_cmd); + install_element(INTERFACE_NODE, &if_no_nhrp_authentication_cmd); install_element(INTERFACE_NODE, &if_nhrp_mtu_cmd); install_element(INTERFACE_NODE, &if_no_nhrp_mtu_cmd); install_element(INTERFACE_NODE, &if_nhrp_flags_cmd); diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h index e389b7489d36..344e1d51780f 100644 --- a/nhrpd/nhrpd.h +++ b/nhrpd/nhrpd.h @@ -311,6 +311,7 @@ DECLARE_DLIST(nhrp_reglist, struct nhrp_registration, reglist_entry); struct nhrp_interface { struct interface *ifp; + struct zbuf *auth_token; unsigned enabled : 1; char *ipsec_profile, *ipsec_fallback_profile, *source; @@ -480,9 +481,13 @@ struct nhrp_packet_header *nhrp_packet_push(struct zbuf *zb, uint8_t type, const union sockunion *src_nbma, const union sockunion *src_proto, const union sockunion *dst_proto); -void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr); uint16_t nhrp_packet_calculate_checksum(const uint8_t *pdu, uint16_t len); +void nhrp_packet_complete(struct zbuf *zb, struct nhrp_packet_header *hdr, + struct interface *ifp); +void nhrp_packet_complete_auth(struct zbuf *zb, struct nhrp_packet_header *hdr, + struct interface *ifp, bool auth); + struct nhrp_packet_header *nhrp_packet_pull(struct zbuf *zb, union sockunion *src_nbma, union sockunion *src_proto, @@ -501,8 +506,7 @@ nhrp_ext_push(struct zbuf *zb, struct nhrp_packet_header *hdr, uint16_t type); void nhrp_ext_complete(struct zbuf *zb, struct nhrp_extension_header *ext); struct nhrp_extension_header *nhrp_ext_pull(struct zbuf *zb, struct zbuf *payload); -void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr, - struct interface *); +void nhrp_ext_request(struct zbuf *zb, struct nhrp_packet_header *hdr); int nhrp_ext_reply(struct zbuf *zb, struct nhrp_packet_header *hdr, struct interface *ifp, struct nhrp_extension_header *ext, struct zbuf *extpayload); diff --git a/nhrpd/subdir.am b/nhrpd/subdir.am index 227ff6c6787d..94fb3bb5bebe 100644 --- a/nhrpd/subdir.am +++ b/nhrpd/subdir.am @@ -42,3 +42,7 @@ noinst_HEADERS += \ nhrpd/zbuf.h \ nhrpd/znl.h \ # end + +clippy_scan += \ + nhrpd/nhrp_vty.c \ + # end diff --git a/tests/topotests/nhrp_topo/r1/nhrpd.conf b/tests/topotests/nhrp_topo/r1/nhrpd.conf index e5224e4aabe9..027312dcd53f 100644 --- a/tests/topotests/nhrp_topo/r1/nhrpd.conf +++ b/tests/topotests/nhrp_topo/r1/nhrpd.conf @@ -1,6 +1,7 @@ log stdout debugging ! debug nhrp all interface r1-gre0 + ip nhrp authentication secret ip nhrp holdtime 500 ip nhrp shortcut ip nhrp network-id 42 diff --git a/tests/topotests/nhrp_topo/r2/nhrpd.conf b/tests/topotests/nhrp_topo/r2/nhrpd.conf index f9185f9a6398..621db6abc838 100644 --- a/tests/topotests/nhrp_topo/r2/nhrpd.conf +++ b/tests/topotests/nhrp_topo/r2/nhrpd.conf @@ -2,6 +2,7 @@ log stdout debugging nhrp nflog-group 1 interface r2-gre0 + ip nhrp authentication secret ip nhrp holdtime 500 ip nhrp redirect ip nhrp network-id 42 diff --git a/tests/topotests/nhrp_topo/test_nhrp_topo.py b/tests/topotests/nhrp_topo/test_nhrp_topo.py index 284c58a8e781..c57d28b709bc 100644 --- a/tests/topotests/nhrp_topo/test_nhrp_topo.py +++ b/tests/topotests/nhrp_topo/test_nhrp_topo.py @@ -214,19 +214,64 @@ def test_protocols_convergence(): def test_nhrp_connection(): "Assert that the NHRP peers can find themselves." tgen = get_topogen() + pingrouter = tgen.gears["r1"] + hubrouter = tgen.gears["r2"] if tgen.routers_have_failure(): pytest.skip(tgen.errors) - pingrouter = tgen.gears["r1"] - logger.info("Check Ping IPv4 from R1 to R2 = 10.255.255.2)") - output = pingrouter.run("ping 10.255.255.2 -f -c 1000") - logger.info(output) - if "1000 packets transmitted, 1000 received" not in output: + def ping_helper(): + output = pingrouter.run("ping 10.255.255.2 -f -c 100") + logger.info(output) + return output + + # force session to reinitialize + def relink_session(): + for r in ["r1", "r2"]: + tgen.gears[r].vtysh_cmd("clear ip nhrp cache") + tgen.net[r].cmd("ip l del {}-gre0".format(r)); + _populate_iface(); + + ### Passwords are the same + logger.info("Check Ping IPv4 from R1 to R2 = 10.255.255.2") + output = ping_helper() + if "100 packets transmitted, 100 received" not in output: assertmsg = "expected ping IPv4 from R1 to R2 should be ok" assert 0, assertmsg else: logger.info("Check Ping IPv4 from R1 to R2 OK") + ### Passwords are different + logger.info("Modify password and send ping again, should drop") + hubrouter.vtysh_cmd(""" + configure + interface r2-gre0 + ip nhrp authentication secret12 + """) + relink_session() + topotest.sleep(10, "Waiting for session to initialize") + output = ping_helper() + if "Network is unreachable" not in output: + assertmsg = "expected ping IPv4 from R1 to R2 - should be down" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1 to R2 missing - OK") + + ### Passwords are the same - again + logger.info("Recover password and verify conectivity is back") + hubrouter.vtysh_cmd(""" + configure + interface r2-gre0 + ip nhrp authentication secret + """) + relink_session() + topotest.sleep(10, "Waiting for session to initialize") + output = pingrouter.run("ping 10.255.255.2 -f -c 100") + logger.info(output) + if "100 packets transmitted, 100 received" not in output: + assertmsg = "expected ping IPv4 from R1 to R2 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1 to R2 OK") def test_route_install(): "Test use of NHRP routes by other protocols (sharpd here)." From b5540d326b82ca92ed88f9082fe0ed2433b09c27 Mon Sep 17 00:00:00 2001 From: Dave LeRoy Date: Wed, 5 Jun 2024 12:10:11 -0700 Subject: [PATCH 235/472] nhrpd: add cisco-authentication password support Taking over this development from https://github.com/FRRouting/frr/pull/14788 This commit addresses 4 issues found in the previous PR 1) FRR would accept messages from a spoke without authentication when FRR NHRP had auth configured. 2) The error indication was not being sent in network byte order 3) The debug print in nhrp_connection_authorized was not correctly printing the received password 4) The addresses portion of the mandatory part of the error indication was invalid on the wire (confirmed in wireshark) Signed-off-by: Dave LeRoy Co-authored-by: Volodymyr Huti --- doc/user/nhrpd.rst | 2 +- nhrpd/nhrp_interface.c | 2 + nhrpd/nhrp_peer.c | 31 ++++++++------ nhrpd/nhrp_vty.c | 9 ++-- tests/topotests/nhrp_topo/r1/nhrpd.conf | 2 +- tests/topotests/nhrp_topo/r2/nhrpd.conf | 2 +- tests/topotests/nhrp_topo/test_nhrp_topo.py | 46 ++++++++++----------- 7 files changed, 51 insertions(+), 43 deletions(-) diff --git a/doc/user/nhrpd.rst b/doc/user/nhrpd.rst index e0ba90fcc139..648d56d9c18a 100644 --- a/doc/user/nhrpd.rst +++ b/doc/user/nhrpd.rst @@ -88,7 +88,7 @@ Configuring NHRP Enables Cisco style authentication on NHRP packets. This embeds the plaintext password to the outgoing NHRP packets. - Maximum length of the is 8 characters. + Maximum length of the password is 8 characters. .. clicmd:: ip nhrp map A.B.C.D|X:X::X:X A.B.C.D|local diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index 7d0ab9762f71..e81a2efbb685 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -99,6 +99,8 @@ static int nhrp_if_delete_hook(struct interface *ifp) free(nifp->ipsec_fallback_profile); if (nifp->source) free(nifp->source); + if (nifp->auth_token) + zbuf_free(nifp->auth_token); XFREE(MTYPE_NHRP_IF, ifp->info); return 0; diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 84fcdb069744..2414541bfaf4 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -730,7 +730,7 @@ static void nhrp_handle_registration_request(struct nhrp_packet_parser *p) } } - // auth ext was validated and copied from the request + /* auth ext was validated and copied from the request */ nhrp_packet_complete_auth(zb, hdr, ifp, false); nhrp_peer_send(p->peer, zb); err: @@ -1064,7 +1064,6 @@ static void nhrp_peer_forward(struct nhrp_peer *p, nhrp_ext_complete(zb, dst); } - // XXX: auth already handled ??? nhrp_packet_complete_auth(zb, hdr, pp->ifp, false); nhrp_peer_send(p, zb); zbuf_free(zb); @@ -1121,24 +1120,26 @@ static int nhrp_packet_send_error(struct nhrp_packet_parser *pp, dst_proto = pp->src_proto; } /* Create reply */ - zb = zbuf_alloc(1500); // XXX: hardcode -> calculation routine + zb = zbuf_alloc(1500); hdr = nhrp_packet_push(zb, NHRP_PACKET_ERROR_INDICATION, &pp->src_nbma, &src_proto, &dst_proto); - hdr->u.error.code = indication_code; + hdr->u.error.code = htons(indication_code); hdr->u.error.offset = htons(offset); hdr->flags = pp->hdr->flags; - hdr->hop_count = 0; // XXX: cisco returns 255 + hdr->hop_count = 0; /* XXX: cisco returns 255 */ /* Payload is the packet causing error */ /* Don`t add extension according to RFC */ - /* wireshark gives bad checksum, without exts */ - // pp->hdr->checksum = nhrp_packet_calculate_checksum(zbuf_used(&pp->payload)) zbuf_put(zb, pp->hdr, sizeof(*pp->hdr)); - zbuf_copy(zb, &pp->payload, zbuf_used(&pp->payload)); + zbuf_put(zb, sockunion_get_addr(&pp->src_nbma), + hdr->src_nbma_address_len); + zbuf_put(zb, sockunion_get_addr(&pp->src_proto), + hdr->src_protocol_address_len); + zbuf_put(zb, sockunion_get_addr(&pp->dst_proto), + hdr->dst_protocol_address_len); nhrp_packet_complete_auth(zb, hdr, pp->ifp, false); - /* nhrp_packet_debug(zb, "SEND_ERROR"); */ nhrp_peer_send(pp->peer, zb); zbuf_free(zb); return 0; @@ -1151,8 +1152,7 @@ static bool nhrp_connection_authorized(struct nhrp_packet_parser *pp) struct zbuf *auth = nifp->auth_token; struct nhrp_extension_header *ext; struct zbuf *extensions, pl; - int cmp = 0; - + int cmp = 1; extensions = zbuf_alloc(zbuf_used(&pp->extensions)); zbuf_copy_peek(extensions, &pp->extensions, zbuf_used(&pp->extensions)); @@ -1164,7 +1164,14 @@ static bool nhrp_connection_authorized(struct nhrp_packet_parser *pp) auth->buf; debugf(NHRP_DEBUG_COMMON, "Processing Authentication Extension for (%s:%s|%d)", - auth_ext->secret, (const char *)pl.buf, cmp); + auth_ext->secret, + ((struct nhrp_cisco_authentication_extension *) + pl.buf) + ->secret, + cmp); + break; + default: + /* Ignoring all received extensions except Authentication*/ break; } } diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index 66659bdcdb92..b938ae4cf0e8 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -467,7 +467,7 @@ DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd, AFI_CMD "nhrp authentication PASSWORD$password", AFI_STR NHRP_STR - "Specify plaint text password used for authenticantion\n" + "Specify plain text password used for authenticantion\n" "Password, plain text, limited to 8 characters\n") { VTY_DECLVAR_CONTEXT(interface, ifp); @@ -490,8 +490,6 @@ DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd, auth->type = htonl(NHRP_AUTHENTICATION_PLAINTEXT); memcpy(auth->secret, password, pass_len); - // XXX RFC: reset active (non-authorized) connections? - /* vty_out(vty, "NHRP passwd (%s:%s)", nifp->ifp->name, auth->secret); */ return CMD_SUCCESS; } @@ -501,11 +499,12 @@ DEFPY(if_no_nhrp_authentication, if_no_nhrp_authentication_cmd, NO_STR AFI_STR NHRP_STR - "Reset password used for authentication\n" - "Password, plain text\n") + "Specify plain text password used for authenticantion\n" + "Password, plain text, limited to 8 characters\n") { VTY_DECLVAR_CONTEXT(interface, ifp); struct nhrp_interface *nifp = ifp->info; + if (nifp->auth_token) zbuf_free(nifp->auth_token); return CMD_SUCCESS; diff --git a/tests/topotests/nhrp_topo/r1/nhrpd.conf b/tests/topotests/nhrp_topo/r1/nhrpd.conf index 027312dcd53f..8ade77d07de2 100644 --- a/tests/topotests/nhrp_topo/r1/nhrpd.conf +++ b/tests/topotests/nhrp_topo/r1/nhrpd.conf @@ -2,7 +2,7 @@ log stdout debugging ! debug nhrp all interface r1-gre0 ip nhrp authentication secret - ip nhrp holdtime 500 + ip nhrp holdtime 10 ip nhrp shortcut ip nhrp network-id 42 ip nhrp nhs dynamic nbma 10.2.1.2 diff --git a/tests/topotests/nhrp_topo/r2/nhrpd.conf b/tests/topotests/nhrp_topo/r2/nhrpd.conf index 621db6abc838..d8e59936c865 100644 --- a/tests/topotests/nhrp_topo/r2/nhrpd.conf +++ b/tests/topotests/nhrp_topo/r2/nhrpd.conf @@ -3,7 +3,7 @@ log stdout debugging nhrp nflog-group 1 interface r2-gre0 ip nhrp authentication secret - ip nhrp holdtime 500 + ip nhrp holdtime 10 ip nhrp redirect ip nhrp network-id 42 ip nhrp registration no-unique diff --git a/tests/topotests/nhrp_topo/test_nhrp_topo.py b/tests/topotests/nhrp_topo/test_nhrp_topo.py index c57d28b709bc..883300310773 100644 --- a/tests/topotests/nhrp_topo/test_nhrp_topo.py +++ b/tests/topotests/nhrp_topo/test_nhrp_topo.py @@ -28,7 +28,7 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger -from lib.common_config import required_linux_kernel_version +from lib.common_config import required_linux_kernel_version, retry # Required to instantiate the topology builder class. @@ -231,14 +231,27 @@ def relink_session(): tgen.net[r].cmd("ip l del {}-gre0".format(r)); _populate_iface(); + @retry(retry_timeout=40, initial_wait=5) + def verify_same_password(): + output = ping_helper() + if "100 packets transmitted, 100 received" not in output: + assertmsg = "expected ping IPv4 from R1 to R2 should be ok" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1 to R2 OK") + + @retry(retry_timeout=40, initial_wait=5) + def verify_mismatched_password(): + output = ping_helper() + if "Network is unreachable" not in output: + assertmsg = "expected ping IPv4 from R1 to R2 - should be down" + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1 to R2 missing - OK") + ### Passwords are the same logger.info("Check Ping IPv4 from R1 to R2 = 10.255.255.2") - output = ping_helper() - if "100 packets transmitted, 100 received" not in output: - assertmsg = "expected ping IPv4 from R1 to R2 should be ok" - assert 0, assertmsg - else: - logger.info("Check Ping IPv4 from R1 to R2 OK") + verify_same_password() ### Passwords are different logger.info("Modify password and send ping again, should drop") @@ -248,14 +261,8 @@ def relink_session(): ip nhrp authentication secret12 """) relink_session() - topotest.sleep(10, "Waiting for session to initialize") - output = ping_helper() - if "Network is unreachable" not in output: - assertmsg = "expected ping IPv4 from R1 to R2 - should be down" - assert 0, assertmsg - else: - logger.info("Check Ping IPv4 from R1 to R2 missing - OK") - + verify_mismatched_password() + ### Passwords are the same - again logger.info("Recover password and verify conectivity is back") hubrouter.vtysh_cmd(""" @@ -264,14 +271,7 @@ def relink_session(): ip nhrp authentication secret """) relink_session() - topotest.sleep(10, "Waiting for session to initialize") - output = pingrouter.run("ping 10.255.255.2 -f -c 100") - logger.info(output) - if "100 packets transmitted, 100 received" not in output: - assertmsg = "expected ping IPv4 from R1 to R2 should be ok" - assert 0, assertmsg - else: - logger.info("Check Ping IPv4 from R1 to R2 OK") + verify_same_password() def test_route_install(): "Test use of NHRP routes by other protocols (sharpd here)." From e7bc47b5013758e1d99d114f6310746c1cc488ca Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 11 Jun 2024 10:03:17 +0300 Subject: [PATCH 236/472] bgpd: Check against extended community unit size for link bandwidth If we receive a malformed packets, this could lead ptr_get_be64() reading the packets more than needed (heap overflow). ``` Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1". 0 0xaaaaaadf86ec in __asan_memcpy (/home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/.libs/bgpd+0x3586ec) (BuildId: 78123cd26ada92b8b59fc0d74d292ba70c9d2e01) 1 0xaaaaaaeb60fc in ptr_get_be64 /home/ubuntu/frr-public/frr_public_private-libfuzzer/./lib/stream.h:377:2 2 0xaaaaaaeb5b90 in ecommunity_linkbw_present /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_ecommunity.c:1895:10 3 0xaaaaaae50f30 in bgp_attr_ext_communities /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_attr.c:2639:8 4 0xaaaaaae49d58 in bgp_attr_parse /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_attr.c:3776:10 5 0xaaaaab063260 in bgp_update_receive /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:2371:20 6 0xaaaaab05df00 in bgp_process_packet /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:4063:11 7 0xaaaaaae36110 in LLVMFuzzerTestOneInput /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_main.c:582:3 ``` This is triggered when receiving such a packet (malformed): ``` (gdb) bt 0 ecommunity_linkbw_present (ecom=0x555556287990, bw=bw@entry=0x7fffffffda68) at bgpd/bgp_ecommunity.c:1802 1 0x000055555564fcac in bgp_attr_ext_communities (args=0x7fffffffd840) at bgpd/bgp_attr.c:2619 2 bgp_attr_parse (peer=peer@entry=0x55555628cdf0, attr=attr@entry=0x7fffffffd960, size=size@entry=20, mp_update=mp_update@entry=0x7fffffffd940, mp_withdraw=mp_withdraw@entry=0x7fffffffd950) at bgpd/bgp_attr.c:3755 3 0x00005555556aa655 in bgp_update_receive (connection=connection@entry=0x5555562aa030, peer=peer@entry=0x55555628cdf0, size=size@entry=41) at bgpd/bgp_packet.c:2324 4 0x00005555556afab7 in bgp_process_packet (thread=) at bgpd/bgp_packet.c:3897 5 0x00007ffff7ac2f73 in event_call (thread=thread@entry=0x7fffffffdc70) at lib/event.c:2011 6 0x00007ffff7a6fb90 in frr_run (master=0x555555bc7c90) at lib/libfrr.c:1212 7 0x00005555556457e1 in main (argc=, argv=) at bgpd/bgp_main.c:543 (gdb) p *ecom $1 = {refcnt = 1, unit_size = 8 '\b', disable_ieee_floating = false, size = 2, val = 0x555556282150 "", str = 0x5555562a9c30 "UNK:0, 255 UNK:2, 6"} ``` Reported-by: Iggy Frankovic Signed-off-by: Donatas Abraitis --- bgpd/bgp_ecommunity.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 66898d07bc21..1beb0307d20a 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -1856,7 +1856,7 @@ ecommunity_add_origin_validation_state(enum rpki_states rpki_state, */ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw) { - const uint8_t *eval; + const uint8_t *data; uint32_t i; if (bw) @@ -1869,10 +1869,19 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw) const uint8_t *pnt; uint8_t type, sub_type; - eval = pnt = (ecom->val + (i * ecom->unit_size)); + data = pnt = (ecom->val + (i * ecom->unit_size)); type = *pnt++; sub_type = *pnt++; + const uint8_t *end = data + ecom->unit_size; + size_t len = end - data; + + /* Sanity check for extended communities lenght, to avoid + * overrun when dealing with bits, e.g. ptr_get_be64(). + */ + if (len < ecom->unit_size) + return NULL; + if ((type == ECOMMUNITY_ENCODE_AS || type == ECOMMUNITY_ENCODE_AS_NON_TRANS) && sub_type == ECOMMUNITY_LINK_BANDWIDTH) { @@ -1886,11 +1895,14 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw) ? bwval : ieee_float_uint32_to_uint32( bwval)); - return eval; + return data; } else if (type == ECOMMUNITY_ENCODE_AS4 && sub_type == ECOMMUNITY_EXTENDED_LINK_BANDWIDTH) { uint64_t bwval; + if (len < IPV6_ECOMMUNITY_SIZE) + return NULL; + pnt += 2; /* Reserved */ pnt = ptr_get_be64(pnt, &bwval); (void)pnt; @@ -1898,7 +1910,7 @@ const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint64_t *bw) if (bw) *bw = bwval; - return eval; + return data; } } From 9fb7d677d3584eadd1d4568bedd542eb880afcd7 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 30 May 2024 15:47:11 +0200 Subject: [PATCH 237/472] bgpd: fix do not skip paths with same nexthop Under a setup where two BGP prefixes are available from multiple sources, if one of the two prefixes is recursive over the other BGP prefix, then it will not be considered as multipath. The below output shows the two prefixes 192.0.2.24/32 and 192.0.2.21/32. The 192.0.2.[5,6,8] are the known IP addresses visible from the IGP. > # show bgp ipv4 192.0.2.24/32 > *>i 192.0.2.24/32 192.0.2.21 0 100 0 i > * i 192.0.2.21 0 100 0 i > * i 192.0.2.21 0 100 0 i > # show bgp ipv4 192.0.2.21/32 > *>i 192.0.2.21/32 192.0.2.5 0 100 0 i > *=i 192.0.2.6 0 100 0 i > *=i 192.0.2.8 0 100 0 i The bgp best selection algorithm refuses to consider the paths to '192.0.2.24/32' as multipath, whereas the BGP paths which use the BGP peer as nexthop are considered multipath. > ... has the same nexthop as the bestpath, skip it ... Previously, this condition has been added to prevent ZEBRA from installing routes with same nexthop: > Here you can see the two paths with nexthop 210.2.2.2 > superm-redxp-05# show ip route 2.23.24.192/28 > Routing entry for 2.23.24.192/28 > Known via "bgp", distance 20, metric 0, best > Last update 00:32:12 ago > * 210.2.2.2, via swp3 > * 210.2.0.2, via swp1 > * 210.2.1.2, via swp2 > * 210.2.2.2, via swp3 > [..] But today, ZEBRA knows how to handle it. When receiving incoming routes, nexthop groups are used. At creation, duplicated nexthops are identified, and will not be installed. The below output illustrate the duplicate paths to 172.16.0.200 received by an other peer. > r1# show ip route 172.18.1.100 nexthop-group > Routing entry for 172.18.1.100/32 > Known via "bgp", distance 200, metric 0, best > Last update 00:03:03 ago > Nexthop Group ID: 75757580 > 172.16.0.200 (recursive), weight 1 > * 172.31.0.3, via r1-eth1, label 16055, weight 1 > * 172.31.2.4, via r1-eth2, label 16055, weight 1 > * 172.31.0.3, via r1-eth1, label 16006, weight 1 > * 172.31.2.4, via r1-eth2, label 16006, weight 1 > * 172.31.8.7, via r1-eth4, label 16008, weight 1 > 172.16.0.200 (duplicate nexthop removed) (recursive), weight 1 > 172.31.0.3, via r1-eth1 (duplicate nexthop removed), label 16055, weight 1 > 172.31.2.4, via r1-eth2 (duplicate nexthop removed), label 16055, weight 1 > 172.31.0.3, via r1-eth1 (duplicate nexthop removed), label 16006, weight 1 > 172.31.2.4, via r1-eth2 (duplicate nexthop removed), label 16006, weight 1 > 172.31.8.7, via r1-eth4 (duplicate nexthop removed), label 16008, weight 1 Fix this by proposing to let ZEBRA handle this duplicate decision. Fixes: 7dc9d4e4e360 ("bgp may add multiple path entries with the same nexthop") Signed-off-by: Philippe Guibert --- bgpd/bgp_mpath.c | 115 +++++++++++++++++++++++++++++------------------ bgpd/bgp_route.c | 9 ---- 2 files changed, 71 insertions(+), 53 deletions(-) diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index e12d84b84c00..eadd52b8e0f2 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -605,31 +605,43 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest, if (mp_node && (listgetdata(mp_node) == cur_mpath)) { list_delete_node(mp_list, mp_node); bgp_path_info_mpath_dequeue(cur_mpath); - if ((mpath_count < maxpaths) - && prev_mpath - && bgp_path_info_nexthop_cmp(prev_mpath, - cur_mpath)) { + if ((mpath_count < maxpaths) && prev_mpath) { + mpath_count++; + if (bgp_path_info_nexthop_cmp(prev_mpath, + cur_mpath)) { + if (ecommunity_linkbw_present( + bgp_attr_get_ecommunity( + cur_mpath->attr), + &bwval) || + ecommunity_linkbw_present( + bgp_attr_get_ipv6_ecommunity( + cur_mpath->attr), + &bwval)) + cum_bw += bwval; + else + all_paths_lb = false; + if (debug) { + bgp_path_info_path_with_addpath_rx_str( + cur_mpath, path_buf, + sizeof(path_buf)); + zlog_debug("%pBD: %s is still multipath, cur count %d", + dest, path_buf, + mpath_count); + } + } else { + if (debug) { + bgp_path_info_path_with_addpath_rx_str( + cur_mpath, path_buf, + sizeof(path_buf)); + zlog_debug("%pBD: nexthop equal, however add mpath %s nexthop %pI4, cur count %d", + dest, path_buf, + &cur_mpath->attr->nexthop, + mpath_count); + } + } bgp_path_info_mpath_enqueue(prev_mpath, cur_mpath); prev_mpath = cur_mpath; - mpath_count++; - if (ecommunity_linkbw_present(bgp_attr_get_ecommunity( - cur_mpath->attr), - &bwval) || - ecommunity_linkbw_present( - bgp_attr_get_ipv6_ecommunity( - cur_mpath->attr), - &bwval)) - cum_bw += bwval; - else - all_paths_lb = false; - if (debug) { - bgp_path_info_path_with_addpath_rx_str( - cur_mpath, path_buf, - sizeof(path_buf)); - zlog_debug("%pBD: %s is still multipath, cur count %d", - dest, path_buf, mpath_count); - } } else { mpath_changed = 1; if (debug) { @@ -693,35 +705,50 @@ void bgp_path_info_mpath_update(struct bgp *bgp, struct bgp_dest *dest, list_delete_node(mp_list, mp_node); assert(new_mpath); assert(prev_mpath); - if ((mpath_count < maxpaths) && (new_mpath != new_best) - && bgp_path_info_nexthop_cmp(prev_mpath, - new_mpath)) { + if ((mpath_count < maxpaths) && (new_mpath != new_best)) { + /* keep duplicate nexthop */ bgp_path_info_mpath_dequeue(new_mpath); bgp_path_info_mpath_enqueue(prev_mpath, new_mpath); - prev_mpath = new_mpath; mpath_changed = 1; mpath_count++; - if (ecommunity_linkbw_present(bgp_attr_get_ecommunity( - new_mpath->attr), - &bwval) || - ecommunity_linkbw_present( - bgp_attr_get_ipv6_ecommunity( - new_mpath->attr), - &bwval)) - cum_bw += bwval; - else - all_paths_lb = false; - if (debug) { - bgp_path_info_path_with_addpath_rx_str( - new_mpath, path_buf, - sizeof(path_buf)); - zlog_debug("%pBD: add mpath %s nexthop %pI4, cur count %d", - dest, path_buf, - &new_mpath->attr->nexthop, - mpath_count); + if (bgp_path_info_nexthop_cmp(prev_mpath, + new_mpath)) { + if (ecommunity_linkbw_present( + bgp_attr_get_ecommunity( + new_mpath->attr), + &bwval) || + ecommunity_linkbw_present( + bgp_attr_get_ipv6_ecommunity( + new_mpath->attr), + &bwval)) + cum_bw += bwval; + else + all_paths_lb = false; + if (debug) { + bgp_path_info_path_with_addpath_rx_str( + new_mpath, path_buf, + sizeof(path_buf)); + zlog_debug("%pBD: add mpath %s nexthop %pI4, cur count %d", + dest, path_buf, + &new_mpath->attr + ->nexthop, + mpath_count); + } + } else { + if (debug) { + bgp_path_info_path_with_addpath_rx_str( + new_mpath, path_buf, + sizeof(path_buf)); + zlog_debug("%pBD: nexthop equal, however add mpath %s nexthop %pI4, cur count %d", + dest, path_buf, + &new_mpath->attr + ->nexthop, + mpath_count); + } } + prev_mpath = new_mpath; } mp_node = mp_next_node; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 94c21e186150..4dcb22234ac5 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3256,15 +3256,6 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, if (!peer_established(pi->peer->connection)) continue; - if (!bgp_path_info_nexthop_cmp(pi, new_select)) { - if (debug) - zlog_debug( - "%pBD(%s): %s has the same nexthop as the bestpath, skip it", - dest, bgp->name_pretty, - path_buf); - continue; - } - bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg, debug, pfx_buf, afi, safi, &dest->reason); From a6b1d38d7f038c335143d963b7b7a13377ef5f22 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 10 Jun 2024 08:38:22 +0200 Subject: [PATCH 238/472] topotests: add API to detect if iproute2 is json capable Some tests may want to use the json facility of iproute2 to dump some results. Add an internal API in lib/topotest.py that tells whether iproute2 is json capable or not. Signed-off-by: Philippe Guibert --- tests/topotests/lib/topotest.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/topotests/lib/topotest.py b/tests/topotests/lib/topotest.py index 087d8454fce3..1d4bc2eac6a5 100644 --- a/tests/topotests/lib/topotest.py +++ b/tests/topotests/lib/topotest.py @@ -602,6 +602,30 @@ def is_linux(): return False +def iproute2_is_json_capable(): + """ + Checks if the iproute2 version installed on the system is capable of + handling JSON outputss + + Returns True if capability can be detected, returns False otherwise. + """ + if is_linux(): + try: + subp = subprocess.Popen( + ["ip", "-json", "route", "show"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE, + ) + iproute2_err = subp.communicate()[1].splitlines()[0].split()[0] + + if iproute2_err != "Error:": + return True + except Exception: + pass + return False + + def iproute2_is_vrf_capable(): """ Checks if the iproute2 version installed on the system is capable of From d0bac2796b404e3b206313c9003b770a50b45cdf Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 4 Jun 2024 18:50:26 +0200 Subject: [PATCH 239/472] topotests: add bgp duplicate nexthop test Add a topotest that ensures that when addpath is enabled and two paths with same nexthop are received, they are sent to ZEBRA which detects 'duplicate nexthop'. Signed-off-by: Philippe Guibert --- .../bgp_duplicate_nexthop/r1/bgpd.conf | 13 + .../bgp_duplicate_nexthop/r1/isisd.conf | 26 + .../bgp_duplicate_nexthop/r1/zebra.conf | 24 + .../bgp_duplicate_nexthop/r3/bgpd.conf | 16 + .../bgp_duplicate_nexthop/r3/isisd.conf | 38 ++ .../bgp_duplicate_nexthop/r3/zebra.conf | 16 + .../bgp_duplicate_nexthop/r4/isisd.conf | 30 ++ .../bgp_duplicate_nexthop/r4/zebra.conf | 20 + .../bgp_duplicate_nexthop/r5/bgpd.conf | 19 + .../bgp_duplicate_nexthop/r5/isisd.conf | 26 + .../bgp_duplicate_nexthop/r5/zebra.conf | 19 + .../bgp_duplicate_nexthop/r6/bgpd.conf | 19 + .../bgp_duplicate_nexthop/r6/isisd.conf | 22 + .../bgp_duplicate_nexthop/r6/zebra.conf | 20 + .../test_bgp_duplicate_nexthop.py | 458 ++++++++++++++++++ tests/topotests/lib/common_check.py | 48 ++ 16 files changed, 814 insertions(+) create mode 100644 tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r1/isisd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r1/zebra.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r3/isisd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r3/zebra.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r4/isisd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r4/zebra.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r5/isisd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r5/zebra.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r6/isisd.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/r6/zebra.conf create mode 100644 tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py create mode 100644 tests/topotests/lib/common_check.py diff --git a/tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf new file mode 100644 index 000000000000..31f06dbb9031 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf @@ -0,0 +1,13 @@ +router bgp 64500 + bgp router-id 192.0.2.1 + no bgp ebgp-requires-policy + neighbor rrserver peer-group + neighbor rrserver remote-as 64500 + neighbor rrserver update-source lo + neighbor rrserver timers connect 2 + neighbor 192.0.2.3 peer-group rrserver + address-family ipv4 unicast + neighbor rrserver next-hop-self + neighbor rrserver activate + exit-address-family +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r1/isisd.conf b/tests/topotests/bgp_duplicate_nexthop/r1/isisd.conf new file mode 100644 index 000000000000..9660577f4e8f --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r1/isisd.conf @@ -0,0 +1,26 @@ +hostname r1 +interface lo + ip router isis 1 + isis passive +! +interface r1-eth1 + ip router isis 1 + isis network point-to-point +! +interface r1-eth2 + ip router isis 1 + isis network point-to-point +! +interface r1-eth4 + ip router isis 1 + isis network point-to-point +! +router isis 1 + net 49.0123.6452.0001.00 + is-type level-2-only + mpls-te on + segment-routing on + segment-routing global-block 16000 17000 + segment-routing node-msd 10 + segment-routing prefix 192.0.2.1/32 index 1 +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r1/zebra.conf b/tests/topotests/bgp_duplicate_nexthop/r1/zebra.conf new file mode 100644 index 000000000000..2e3549a57401 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r1/zebra.conf @@ -0,0 +1,24 @@ +log stdout +interface lo + ip address 192.0.2.1/32 +! +interface r1-eth0 + ip address 172.31.10.1/24 +! +interface r1-eth1 + ip address 172.31.0.1/24 + mpls enable +! +interface r1-eth2 + ip address 172.31.2.1/24 + mpls enable +! +interface r1-eth3 + ip address 172.31.11.1/24 + mpls enable +! +interface r1-eth4 + ip address 172.31.8.1/24 + mpls enable +! + diff --git a/tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf new file mode 100644 index 000000000000..2b03f51a2376 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf @@ -0,0 +1,16 @@ +router bgp 64500 view one + bgp router-id 192.0.2.3 + neighbor rr peer-group + neighbor rr remote-as 64500 + neighbor rr update-source lo + neighbor 192.0.2.1 peer-group rr + neighbor 192.0.2.5 peer-group rr + neighbor 192.0.2.6 peer-group rr + neighbor 192.0.2.8 peer-group rr + ! + address-family ipv4 unicast + neighbor rr activate + neighbor rr route-reflector-client + neighbor rr addpath-tx-all-paths + exit-address-family +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r3/isisd.conf b/tests/topotests/bgp_duplicate_nexthop/r3/isisd.conf new file mode 100644 index 000000000000..ae6bddee9208 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r3/isisd.conf @@ -0,0 +1,38 @@ +hostname r3 +interface lo + ip router isis 1 + isis passive +! +interface r3-eth0 + ip router isis 1 + isis network point-to-point +! +interface r3-eth1 + ip router isis 1 + isis network point-to-point +! +interface r3-eth2 + ip router isis 1 + isis network point-to-point +! +interface r3-eth3 + ip router isis 1 + isis network point-to-point +! +interface r3-eth4 + ip router isis 1 + isis network point-to-point +! +interface r3-eth5 + ip router isis 1 + isis network point-to-point +! +router isis 1 + net 49.0123.6452.0003.00 + is-type level-2-only + mpls-te on + segment-routing on + segment-routing global-block 16000 17000 + segment-routing node-msd 10 + segment-routing prefix 192.0.2.3/32 index 3 +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r3/zebra.conf b/tests/topotests/bgp_duplicate_nexthop/r3/zebra.conf new file mode 100644 index 000000000000..05b3769fb8bf --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r3/zebra.conf @@ -0,0 +1,16 @@ +log stdout +interface lo + ip address 192.0.2.3/32 +! +interface r3-eth0 + ip address 172.31.0.3/24 + mpls enable +! +interface r3-eth1 + ip address 172.31.4.3/24 + mpls enable +! +interface r3-eth2 + ip address 172.31.5.3/24 + mpls enable +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r4/isisd.conf b/tests/topotests/bgp_duplicate_nexthop/r4/isisd.conf new file mode 100644 index 000000000000..4d49d0de0a45 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r4/isisd.conf @@ -0,0 +1,30 @@ +hostname r4 +interface lo + ip router isis 1 + isis passive +! +interface r4-eth0 + ip router isis 1 + isis network point-to-point +! +interface r4-eth1 + ip router isis 1 + isis network point-to-point +! +interface r4-eth2 + ip router isis 1 + isis network point-to-point +! +interface r4-eth3 + ip router isis 1 + isis network point-to-point +! +router isis 1 + net 49.0123.6452.0004.00 + is-type level-2-only + mpls-te on + segment-routing on + segment-routing global-block 16000 17000 + segment-routing node-msd 10 + segment-routing prefix 192.0.2.4/32 index 4 +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r4/zebra.conf b/tests/topotests/bgp_duplicate_nexthop/r4/zebra.conf new file mode 100644 index 000000000000..9ea1b7ec4314 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r4/zebra.conf @@ -0,0 +1,20 @@ +log stdout +interface lo + ip address 192.0.2.4/32 +! +interface r4-eth0 + ip address 172.31.2.4/24 + mpls enable +! +interface r4-eth1 + ip address 172.31.6.4/24 + mpls enable +! +interface r4-eth2 + ip address 172.31.7.4/24 + mpls enable +! +interface r4-eth3 + mpls enable +! + diff --git a/tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf new file mode 100644 index 000000000000..272183b1ac83 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf @@ -0,0 +1,19 @@ +router bgp 64500 + bgp router-id 192.0.2.5 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor rrserver peer-group + neighbor rrserver remote-as 64500 + neighbor rrserver update-source lo + neighbor rrserver timers connect 2 + neighbor 192.0.2.3 peer-group rrserver + address-family ipv4 unicast + network 192.0.2.9/32 + network 192.0.2.8/32 route-map rmap + neighbor rrserver activate + neighbor rrserver addpath-tx-all-paths + exit-address-family +! +route-map rmap permit 1 + set ip next-hop 192.0.2.9 +exit diff --git a/tests/topotests/bgp_duplicate_nexthop/r5/isisd.conf b/tests/topotests/bgp_duplicate_nexthop/r5/isisd.conf new file mode 100644 index 000000000000..46556d9a567a --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r5/isisd.conf @@ -0,0 +1,26 @@ +hostname r5 +interface lo + ip router isis 1 + isis passive +! +interface r5-eth1 + ip router isis 1 + isis network point-to-point +! +interface r5-eth2 + ip router isis 1 + isis network point-to-point +! +interface r5-eth3 + ip router isis 1 + isis network point-to-point +! +router isis 1 + net 49.0123.6452.0005.00 + is-type level-2-only + mpls-te on + segment-routing on + segment-routing global-block 16000 17000 + segment-routing node-msd 10 + segment-routing prefix 192.0.2.5/32 index 55 +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r5/zebra.conf b/tests/topotests/bgp_duplicate_nexthop/r5/zebra.conf new file mode 100644 index 000000000000..6f326561e733 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r5/zebra.conf @@ -0,0 +1,19 @@ +log stdout +mpls label dynamic-block 5000 5999 +interface lo + ip address 192.0.2.5/32 +! +interface r5-eth0 + ip address 172.31.12.5/24 +! +interface r5-eth1 + ip address 172.31.4.5/24 + mpls enable +! +interface r5-eth2 + ip address 172.31.7.5/24 + mpls enable +! +interface r5-eth3 + ip address 172.31.21.5/24 +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf new file mode 100644 index 000000000000..68bd36eb8a80 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf @@ -0,0 +1,19 @@ +router bgp 64500 + bgp router-id 192.0.2.6 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor rrserver peer-group + neighbor rrserver remote-as 64500 + neighbor rrserver update-source lo + neighbor rrserver bfd + neighbor 192.0.2.3 peer-group rrserver + address-family ipv4 unicast + network 192.0.2.9/32 + network 192.0.2.8/32 route-map rmap + neighbor rrserver activate + neighbor rrserver addpath-tx-all-paths + exit-address-family +! +route-map rmap permit 1 + set ip next-hop 192.0.2.9 +exit diff --git a/tests/topotests/bgp_duplicate_nexthop/r6/isisd.conf b/tests/topotests/bgp_duplicate_nexthop/r6/isisd.conf new file mode 100644 index 000000000000..5126a6485846 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r6/isisd.conf @@ -0,0 +1,22 @@ +hostname r6 +interface lo + ip router isis 1 + isis passive +! +interface r6-eth1 + ip router isis 1 + isis network point-to-point +! +interface r6-eth2 + ip router isis 1 + isis network point-to-point +! +router isis 1 + net 49.0123.6452.0006.00 + is-type level-2-only + mpls-te on + segment-routing on + segment-routing global-block 16000 17000 + segment-routing node-msd 10 + segment-routing prefix 192.0.2.6/32 index 6 +! diff --git a/tests/topotests/bgp_duplicate_nexthop/r6/zebra.conf b/tests/topotests/bgp_duplicate_nexthop/r6/zebra.conf new file mode 100644 index 000000000000..cda62d7e87a0 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/r6/zebra.conf @@ -0,0 +1,20 @@ +log stdout +mpls label dynamic-block 6000 6999 +interface lo + ip address 192.0.2.6/32 +! +interface r6-eth0 + ip address 172.31.13.6/24 +! +interface r6-eth1 + ip address 172.31.5.6/24 + mpls enable +! +interface r6-eth2 + ip address 172.31.6.6/24 + mpls enable +! +interface r6-eth3 + ip address 172.31.22.6/24 +! + diff --git a/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py new file mode 100644 index 000000000000..955881e6f905 --- /dev/null +++ b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py @@ -0,0 +1,458 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_bgp_duplicate_nexthop.py +# +# Copyright 2024 6WIND S.A. +# + +""" + test_bgp_nhg_duplicate_nexthop.py: + Check that the FRR BGP daemon on r1 selects updates with same nexthops + + ++---+----+ +---+----+ +--------+ +| | | + | | +| r1 +----------+ r3 +----------+ r5 + +| | | rr + +-----+ | ++++-+----+ +--------+\ / +--------+ + | \/ + | /\ + | +--------+/ \ +--------+ + | | + +-----+ + + +---------------+ r4 +----------+ r6 + + | | | | + +--------+ +--------+ +""" + +import os +import sys +import json +from functools import partial +import pytest +import functools + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.common_check import ip_check_path_selection, iproute2_check_path_selection +from lib.common_config import step +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. + + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + "Build function" + + # Create 7 PE routers. + tgen.add_router("r1") + tgen.add_router("r3") + tgen.add_router("r4") + tgen.add_router("r5") + tgen.add_router("r6") + + # switch + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r5"]) + + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["r6"]) + + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r3"]) + + switch = tgen.add_switch("s7") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r4"]) + + switch = tgen.add_switch("s8") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r5"]) + + switch = tgen.add_switch("s9") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r6"]) + + switch = tgen.add_switch("s10") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["r6"]) + + switch = tgen.add_switch("s11") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["r5"]) + + switch = tgen.add_switch("s12") + switch.add_link(tgen.gears["r5"]) + + switch = tgen.add_switch("s13") + switch.add_link(tgen.gears["r6"]) + + switch = tgen.add_switch("s14") + switch.add_link(tgen.gears["r1"]) + + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for rname, router in router_list.items(): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) + ) + if rname in ("r1", "r3", "r5", "r6"): + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(_mod): + "Teardown the pytest environment" + tgen = get_topogen() + + tgen.stop_topology() + + +def check_ipv4_prefix_with_multiple_nexthops(prefix, multipath=True): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info( + f"Check that {prefix} unicast entry is installed with paths for r5 and r6" + ) + + r5_nh = [ + { + "ip": "192.0.2.5", + "active": True, + "recursive": True, + }, + { + "ip": "172.31.0.3", + "interfaceName": "r1-eth1", + "active": True, + "labels": [ + 16055, + ], + }, + { + "ip": "172.31.2.4", + "interfaceName": "r1-eth2", + "active": True, + "labels": [ + 16055, + ], + }, + ] + + r6_nh = [ + { + "ip": "192.0.2.6", + "active": True, + "recursive": True, + }, + { + "ip": "172.31.0.3", + "interfaceName": "r1-eth1", + "active": True, + "labels": [ + 16006, + ], + }, + { + "ip": "172.31.2.4", + "interfaceName": "r1-eth2", + "active": True, + "labels": [ + 16006, + ], + }, + ] + + expected = { + prefix: [ + { + "prefix": prefix, + "protocol": "bgp", + "metric": 0, + "table": 254, + "nexthops": [], + } + ] + } + for nh in r5_nh: + expected[prefix][0]["nexthops"].append(nh) + if multipath: + for nh in r6_nh: + expected[prefix][0]["nexthops"].append(nh) + + test_func = functools.partial( + ip_check_path_selection, tgen.gears["r1"], prefix, expected + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert ( + result is None + ), f"Failed to check that {prefix} uses the IGP label 16055 and 16006" + + +def get_nh_formatted(nexthop, fib=True, duplicate=False): + nh = dict(nexthop) + if duplicate: + nh.update({"duplicate": True}) + if fib: + nh.update({"fib": True}) + return nh + + +def check_ipv4_prefix_recursive_with_multiple_nexthops( + prefix, recursive_nexthop, multipath=True +): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + logger.info( + f"Check that {prefix} unicast entry is correctly recursive via {recursive_nexthop} with paths for r5 and r6" + ) + + r5_nh = [ + { + "ip": "172.31.0.3", + "interfaceName": "r1-eth1", + "active": True, + "labels": [ + 16055, + ], + }, + { + "ip": "172.31.2.4", + "interfaceName": "r1-eth2", + "active": True, + "labels": [ + 16055, + ], + }, + ] + + r6_nh = [ + { + "ip": "172.31.0.3", + "interfaceName": "r1-eth1", + "active": True, + "labels": [ + 16006, + ], + }, + { + "ip": "172.31.2.4", + "interfaceName": "r1-eth2", + "active": True, + "labels": [ + 16006, + ], + }, + ] + + expected = { + prefix: [ + { + "prefix": prefix, + "protocol": "bgp", + "metric": 0, + "table": 254, + "nexthops": [], + } + ] + } + + recursive_nh = [ + { + "ip": recursive_nexthop, + "active": True, + "recursive": True, + }, + ] + for nh in recursive_nh: + expected[prefix][0]["nexthops"].append(get_nh_formatted(nh, fib=False)) + + for nh in r5_nh: + expected[prefix][0]["nexthops"].append(get_nh_formatted(nh)) + + if multipath: + for nh in r6_nh: + expected[prefix][0]["nexthops"].append(get_nh_formatted(nh)) + + for nh in recursive_nh: + expected[prefix][0]["nexthops"].append( + get_nh_formatted(nh, fib=False, duplicate=True) + ) + + for nh in r5_nh: + expected[prefix][0]["nexthops"].append( + get_nh_formatted(nh, fib=False, duplicate=True) + ) + + for nh in r6_nh: + expected[prefix][0]["nexthops"].append( + get_nh_formatted(nh, fib=False, duplicate=True) + ) + + test_func = functools.partial( + ip_check_path_selection, tgen.gears["r1"], prefix, expected + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert ( + result is None + ), f"Failed to check that {prefix} is correctly recursive via {recursive_nexthop}" + + +def check_ipv4_prefix_with_multiple_nexthops_linux(prefix): + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + step( + f"Check that {prefix} unicast entry is installed with paths for r5 and r6 on Linux" + ) + + r5_nh = [ + { + "encap": "mpls", + "dst": "16055", + "gateway": "172.31.0.3", + "dev": "r1-eth1", + }, + { + "encap": "mpls", + "dst": "16055", + "gateway": "172.31.2.4", + "dev": "r1-eth2", + }, + ] + + r6_nh = [ + { + "encap": "mpls", + "dst": "16006", + "gateway": "172.31.0.3", + "dev": "r1-eth1", + }, + { + "encap": "mpls", + "dst": "16006", + "gateway": "172.31.2.4", + "dev": "r1-eth2", + }, + ] + + expected = [ + { + "dst": prefix, + "protocol": "bgp", + "metric": 20, + "nexthops": [], + } + ] + + # only one path + for nh in r5_nh: + expected[0]["nexthops"].append(nh) + for nh in r6_nh: + expected[0]["nexthops"].append(nh) + + test_func = functools.partial( + iproute2_check_path_selection, tgen.routers()["r1"], prefix, expected + ) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert ( + result is None + ), f"Failed to check that {prefix} unicast entry is installed with paths for r5 and r6 on Linux" + + +def test_bgp_ipv4_convergence(): + """ + Check that R1 has received the 192.0.2.9/32 prefix from R5, and R6 + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Ensure that the 192.0.2.9/32 route is available") + check_ipv4_prefix_with_multiple_nexthops("192.0.2.9/32") + + check_ipv4_prefix_with_multiple_nexthops_linux("192.0.2.9") + + +def test_bgp_ipv4_recursive_routes(): + """ + Check that R1 has received the recursive routes, and duplicate nexthops are in zebra, but are not installed + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + check_ipv4_prefix_recursive_with_multiple_nexthops("192.0.2.8/32", "192.0.2.9") + + check_ipv4_prefix_with_multiple_nexthops_linux("192.0.2.8") + + +def test_bgp_ipv4_recursive_routes_when_no_mpath(): + """ + Unconfigure multipath ibgp + Check that duplicate nexthops are not in zebra + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + tgen.gears["r1"].vtysh_cmd( + """ + configure terminal + router bgp + address family ipv4 unicast + maximum-paths ibgp 1 + """, + isjson=False, + ) + tgen.gears["r1"].vtysh_cmd("clear bgp ipv4 *") + check_ipv4_prefix_with_multiple_nexthops("192.0.2.9/32", multipath=False) + + check_ipv4_prefix_recursive_with_multiple_nexthops( + "192.0.2.8/32", "192.0.2.9", multipath=False + ) + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/lib/common_check.py b/tests/topotests/lib/common_check.py new file mode 100644 index 000000000000..be3241fd2022 --- /dev/null +++ b/tests/topotests/lib/common_check.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC +# +# common_check.py +# +# Copyright 2024 6WIND S.A. + +# +import json +from lib import topotest + + +def ip_check_path_selection(router, ipaddr_str, expected, vrf_name=None): + if vrf_name: + cmdstr = f'show ip route vrf {vrf_name} {ipaddr_str} json' + else: + cmdstr = f'show ip route {ipaddr_str} json' + try: + output = json.loads(router.vtysh_cmd(cmdstr)) + except: + output = {} + + ret = topotest.json_cmp(output, expected) + if ret is None: + num_nh_expected = len(expected[ipaddr_str][0]["nexthops"]) + num_nh_observed = len(output[ipaddr_str][0]["nexthops"]) + if num_nh_expected == num_nh_observed: + return ret + return "{}, prefix {} does not have the correct number of nexthops : observed {}, expected {}".format( + router.name, ipaddr_str, num_nh_observed, num_nh_expected + ) + return ret + + +def iproute2_check_path_selection(router, ipaddr_str, expected, vrf_name=None): + if not topotest.iproute2_is_json_capable(): + return None + + if vrf_name: + cmdstr = f'ip -json route show vrf {vrf_name} {ipaddr_str}' + else: + cmdstr = f'ip -json route show {ipaddr_str}' + try: + output = json.loads(cmdstr) + except: + output = [] + + return topotest.json_cmp(output, expected) From e24ff4c275f0729f75be9f68d08be80ac1e0ec56 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 11 Jun 2024 11:59:37 +0300 Subject: [PATCH 240/472] ospfd: Drop `interfaceIp` from `show ip ospf neigh json` Deprecated. Now it's under interface field directly: ``` { "interfaces":{ "enp3s0":{ "ifUp":true, "ifIndex":2, "mtuBytes":1500, "bandwidthMbit":100, "ifFlags":"", "ospfEnabled":true, "ipAddress":"192.168.10.19", "ipAddressPrefixlen":24, "ospfIfType":"Broadcast", "localIfUsed":"192.168.10.255", "area":"0.0.0.0", "routerId":"100.100.100.100", "networkType":"POINTOPOINT", "cost":1000, "transmitDelaySecs":1, "state":"Point-To-Point", "priority":1, "opaqueCapable":true, "mcastMemberOspfAllRouters":true, "timerMsecs":10000, "timerDeadSecs":40, "timerWaitSecs":40, "timerRetransmitSecs":5, "timerHelloInMsecs":2924, "nbrCount":0, "nbrAdjacentCount":0, "grHelloDelaySecs":10, "prefixSuppression":false, "nbrFilterPrefixList":"N\/A" } } } ``` Signed-off-by: Donatas Abraitis --- ospfd/ospf_vty.c | 192 +++++++---------------------------------------- 1 file changed, 26 insertions(+), 166 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 7cb51976f564..21acd402f489 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3576,7 +3576,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, struct route_node *rn; uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed; struct ospf_if_params *params; - json_object *json_ois = NULL; json_object *json_oi = NULL; /* Is interface up? */ @@ -3628,33 +3627,20 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, } } - if (use_json) { - json_ois = json_object_new_object(); - json_object_object_add(json_interface_sub, "interfaceIp", - json_ois); - } - for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) { struct ospf_interface *oi = rn->info; if (oi == NULL) continue; -#if CONFDATE > 20240601 - CPP_NOTICE( - "Use all fields following ospfEnabled from interfaceIp hierarchy") -#endif - if (use_json) json_oi = json_object_new_object(); if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { - if (use_json) { - json_object_boolean_true_add(json_interface_sub, - "ifUnnumbered"); + if (use_json) json_object_boolean_true_add(json_oi, "ifUnnumbered"); - } else + else vty_out(vty, " This interface is UNNUMBERED,"); } else { struct in_addr dest; @@ -3668,13 +3654,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_int_add(json_interface_sub, "ipAddressPrefixlen", oi->address->prefixlen); - - json_object_string_addf( - json_oi, "ipAddress", "%pI4", - &oi->address->u.prefix4); - json_object_int_add(json_oi, - "ipAddressPrefixlen", - oi->address->prefixlen); } else vty_out(vty, " Internet Address %pFX,", oi->address); @@ -3700,26 +3679,14 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_string_add(json_interface_sub, "ospfIfType", dstr); - json_object_string_add(json_oi, "ospfIfType", - dstr); - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) { + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) json_object_string_addf( json_interface_sub, "vlinkPeer", "%pI4", &dest); - - json_object_string_addf(json_oi, - "vlinkPeer", - "%pI4", &dest); - } else { + else json_object_string_addf( json_interface_sub, "localIfUsed", "%pI4", &dest); - - json_object_string_addf(json_oi, - "localIfUsed", - "%pI4", &dest); - } } else vty_out(vty, " %s %pI4,", dstr, &dest); @@ -3728,16 +3695,10 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_string_add(json_interface_sub, "area", ospf_area_desc_string(oi->area)); - json_object_string_add(json_oi, "area", - ospf_area_desc_string(oi->area)); - - if (OSPF_IF_PARAM(oi, mtu_ignore)) { - json_object_boolean_true_add( - json_oi, "mtuMismatchDetect"); + if (OSPF_IF_PARAM(oi, mtu_ignore)) json_object_boolean_true_add( json_interface_sub, "mtuMismatchDetect"); - } json_object_string_addf(json_interface_sub, "routerId", "%pI4", &ospf->router_id); @@ -3754,18 +3715,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, oi->state, NULL)); json_object_int_add(json_interface_sub, "priority", PRIORITY(oi)); - - json_object_string_addf(json_oi, "routerId", "%pI4", - &ospf->router_id); - json_object_string_add(json_oi, "networkType", - ospf_network_type_str[oi->type]); - json_object_int_add(json_oi, "cost", oi->output_cost); - json_object_int_add(json_oi, "transmitDelaySecs", - OSPF_IF_PARAM(oi, transmit_delay)); - json_object_string_add(json_oi, "state", - lookup_msg(ospf_ism_state_msg, - oi->state, NULL)); - json_object_int_add(json_oi, "priority", PRIORITY(oi)); json_object_boolean_add( json_interface_sub, "opaqueCapable", OSPF_IF_PARAM(oi, opaque_capable)); @@ -3809,13 +3758,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_interface_sub, "drAddress", "%pI4", &nbr->address.u.prefix4); - - json_object_string_addf( - json_oi, "drId", "%pI4", - &nbr->router_id); - json_object_string_addf( - json_oi, "drAddress", "%pI4", - &nbr->address.u.prefix4); } else { vty_out(vty, " Designated Router (ID) %pI4", @@ -3841,13 +3783,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_interface_sub, "bdrAddress", "%pI4", &nbr->address.u.prefix4); - - json_object_string_addf( - json_oi, "bdrId", "%pI4", - &nbr->router_id); - json_object_string_addf( - json_oi, "bdrAddress", "%pI4", - &nbr->address.u.prefix4); } else { vty_out(vty, " Backup Designated Router (ID) %pI4,", @@ -3863,43 +3798,28 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, if (oi->params && ntohl(oi->params->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) { - if (use_json) { + if (use_json) json_object_int_add( json_interface_sub, "networkLsaSequence", ntohl(oi->params->network_lsa_seqnum)); - - json_object_int_add( - json_oi, "networkLsaSequence", - ntohl(oi->params->network_lsa_seqnum)); - } else { + else vty_out(vty, " Saved Network-LSA sequence number 0x%x\n", ntohl(oi->params->network_lsa_seqnum)); - } } if (use_json) { if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) { - if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) { + if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)) json_object_boolean_true_add( json_interface_sub, "mcastMemberOspfAllRouters"); - - json_object_boolean_true_add( - json_oi, - "mcastMemberOspfAllRouters"); - } - if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) { + if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) json_object_boolean_true_add( json_interface_sub, "mcastMemberOspfDesignatedRouters"); - - json_object_boolean_true_add( - json_oi, - "mcastMemberOspfDesignatedRouters"); - } } } else { vty_out(vty, " Multicast group memberships:"); @@ -3915,23 +3835,14 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, } if (use_json) { - if (OSPF_IF_PARAM(oi, fast_hello) == 0) { + if (OSPF_IF_PARAM(oi, fast_hello) == 0) json_object_int_add( json_interface_sub, "timerMsecs", OSPF_IF_PARAM(oi, v_hello) * 1000); - - json_object_int_add(json_oi, "timerMsecs", - OSPF_IF_PARAM(oi, v_hello) * - 1000); - } else { + else json_object_int_add( json_interface_sub, "timerMsecs", 1000 / OSPF_IF_PARAM(oi, fast_hello)); - - json_object_int_add( - json_oi, "timerMsecs", - 1000 / OSPF_IF_PARAM(oi, fast_hello)); - } json_object_int_add(json_interface_sub, "timerDeadSecs", OSPF_IF_PARAM(oi, v_wait)); json_object_int_add(json_interface_sub, "timerWaitSecs", @@ -3939,14 +3850,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_int_add( json_interface_sub, "timerRetransmitSecs", OSPF_IF_PARAM(oi, retransmit_interval)); - - json_object_int_add(json_oi, "timerDeadSecs", - OSPF_IF_PARAM(oi, v_wait)); - json_object_int_add(json_oi, "timerWaitSecs", - OSPF_IF_PARAM(oi, v_wait)); - json_object_int_add( - json_oi, "timerRetransmitSecs", - OSPF_IF_PARAM(oi, retransmit_interval)); } else { vty_out(vty, " Timer intervals configured,"); vty_out(vty, " Hello "); @@ -3975,23 +3878,17 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_int_add(json_interface_sub, "timerHelloInMsecs", time_store); - json_object_int_add(json_oi, - "timerHelloInMsecs", - time_store); } else vty_out(vty, " Hello due in %s\n", ospf_timer_dump(oi->t_hello, timebuf, sizeof(timebuf))); } else /* passive-interface is set */ { - if (use_json) { + if (use_json) json_object_boolean_true_add( json_interface_sub, "timerPassiveIface"); - - json_object_boolean_true_add( - json_oi, "timerPassiveIface"); - } else + else vty_out(vty, " No Hellos (Passive interface)\n"); } @@ -4002,11 +3899,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_int_add(json_interface_sub, "nbrAdjacentCount", ospf_nbr_count(oi, NSM_Full)); - - json_object_int_add(json_oi, "nbrCount", - ospf_nbr_count(oi, 0)); - json_object_int_add(json_oi, "nbrAdjacentCount", - ospf_nbr_count(oi, NSM_Full)); } else vty_out(vty, " Neighbor Count is %d, Adjacent neighbor count is %d\n", @@ -4016,14 +3908,11 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, params = IF_DEF_PARAMS(ifp); if (params && OSPF_IF_PARAM_CONFIGURED(params, v_gr_hello_delay)) { - if (use_json) { + if (use_json) json_object_int_add(json_interface_sub, "grHelloDelaySecs", params->v_gr_hello_delay); - - json_object_int_add(json_oi, "grHelloDelaySecs", - params->v_gr_hello_delay); - } else + else vty_out(vty, " Graceful Restart hello delay: %us\n", params->v_gr_hello_delay); @@ -4031,19 +3920,14 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, ospf_interface_bfd_show(vty, ifp, json_interface_sub); - if (use_json) { + if (use_json) json_object_boolean_add(json_interface_sub, "prefixSuppression", OSPF_IF_PARAM(oi, prefix_suppression)); - json_object_boolean_add(json_oi, "prefixSuppression", - OSPF_IF_PARAM(oi, - prefix_suppression)); - } else { - if (OSPF_IF_PARAM(oi, prefix_suppression)) - vty_out(vty, - " Suppress advertisement of interface IP prefix\n"); - } + else if (OSPF_IF_PARAM(oi, prefix_suppression)) + vty_out(vty, + " Suppress advertisement of interface IP prefix\n"); /* OSPF Authentication information */ ospf_interface_auth_show(vty, oi, json_interface_sub, use_json); @@ -4052,63 +3936,39 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, /* Point-to-Multipoint Interface options. */ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { - if (use_json) { + if (use_json) json_object_boolean_add(json_interface_sub, "p2mpDelayReflood", oi->p2mp_delay_reflood); - - json_object_boolean_add(json_oi, - "p2mpDelayReflood", - oi->p2mp_delay_reflood); - } else { + else vty_out(vty, " %sDelay reflooding LSAs received on P2MP interface\n", oi->p2mp_delay_reflood ? "" : "Don't "); - } - if (use_json) { + if (use_json) json_object_boolean_add(json_interface_sub, "p2mpNonBroadcast", oi->p2mp_non_broadcast); - - json_object_boolean_add(json_oi, - "p2mpNonBroadcast", - oi->p2mp_non_broadcast); - } else { + else vty_out(vty, " P2MP interface does %ssupport broadcast\n", oi->p2mp_non_broadcast ? "not " : ""); - } } - /* Add ospf_interface object to main json blob using SIP as key - */ - if (use_json) - json_object_object_addf(json_ois, json_oi, "%pI4", - &oi->address->u.prefix4); - if (oi->nbr_filter) { - if (use_json) { + if (use_json) json_object_string_add(json_interface_sub, "nbrFilterPrefixList", prefix_list_name( oi->nbr_filter)); - json_object_string_add(json_oi, - "nbrFilterPrefixList", - prefix_list_name( - oi->nbr_filter)); - } else + else vty_out(vty, " Neighbor filter prefix-list: %s\n", prefix_list_name(oi->nbr_filter)); } else { - if (use_json) { + if (use_json) json_object_string_add(json_interface_sub, "nbrFilterPrefixList", "N/A"); - json_object_string_add(json_oi, - "nbrFilterPrefixList", - "N/A"); - } } } } From ad1244f88a5ffa0bebcc95d70481865a1ea3e57b Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sat, 8 Jun 2024 23:38:05 +0800 Subject: [PATCH 241/472] yang: fix wrong check for isis metric style Before: ``` anlan(config)# route isis ix anlan(config-router)# metric-style transition ... anlan(config-if)# isis metric 200 % Configuration failed. Error type: validation Error description: YANG error(s): Path: Data location "/frr-interface:lib/interface[name='x']/frr-isisd:isis/metric/level-1". Error: Must condition ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide' or not(/frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style)" not satisfied. Path: Data location "/frr-interface:lib/interface[name='x']/frr-isisd:isis/metric/level-2". Error: Must condition ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide' or not(/frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style)" not satisfied ``` After: ``` anlan(config)# route isis ix anlan(config-router)# metric-style transition ... anlan(config-if)# isis metric 200 anlan(config-if)# ``` Signed-off-by: anlan_cs --- yang/frr-isisd.yang | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index d1a08fa976b9..60914b0be961 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -685,7 +685,7 @@ module frr-isisd { type uint32 { range "0..16777215"; } - must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide' or not(/frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style)"; + must ". < 64 or not(/frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style) or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style != 'narrow'"; default "10"; description "Default level-1 metric for this IS-IS circuit."; @@ -695,7 +695,7 @@ module frr-isisd { type uint32 { range "0..16777215"; } - must ". < 64 or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style = 'wide' or not(/frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style)"; + must ". < 64 or not(/frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style) or /frr-isisd:isis/instance[area-tag = current()/../../area-tag]/metric-style != 'narrow'"; default "10"; description "Default level-2 metric for this IS-IS circuit."; From 3cc01bb00b85d9ff74c00130dadeb53913f02e79 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 11 Jun 2024 15:48:23 +0300 Subject: [PATCH 242/472] tests: Drop `interfaceIp` from OSPF tests Deprecated. Signed-off-by: Donatas Abraitis --- .../ospf_p2mp/test_ospf_p2mp_broadcast.py | 27 ------------------- .../ospf_p2mp/test_ospf_p2mp_non_broadcast.py | 16 ----------- 2 files changed, 43 deletions(-) diff --git a/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py b/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py index 1f0f87959af1..791d7cb09bb9 100644 --- a/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py +++ b/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py @@ -140,22 +140,6 @@ def verify_p2mp_interface(tgen, router, nbr_cnt, nbr_adj_cnt, nbr_filter): "interfaces": { "r1-eth0": { "ospfEnabled": True, - "interfaceIp": { - "10.1.0.1": { - "ipAddress": "10.1.0.1", - "ipAddressPrefixlen": 24, - "ospfIfType": "Broadcast", - "routerId": "1.1.1.1", - "networkType": "POINTOMULTIPOINT", - "cost": 10, - "state": "Point-To-Point", - "nbrCount": nbr_cnt, - "nbrAdjacentCount": nbr_adj_cnt, - "prefixSuppression": False, - "p2mpDelayReflood": False, - "nbrFilterPrefixList": nbr_filter, - } - }, "ipAddress": "10.1.0.1", "ipAddressPrefixlen": 24, "ospfIfType": "Broadcast", @@ -201,17 +185,6 @@ def verify_non_p2mp_interface(tgen): "interfaces": { "r1-eth0": { "ospfEnabled": True, - "interfaceIp": { - "10.1.0.1": { - "ipAddress": "10.1.0.1", - "ipAddressPrefixlen": 24, - "ospfIfType": "Broadcast", - "routerId": "1.1.1.1", - "networkType": "BROADCAST", - "cost": 10, - "prefixSuppression": False, - } - }, "ipAddress": "10.1.0.1", "ipAddressPrefixlen": 24, "ospfIfType": "Broadcast", diff --git a/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py b/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py index 175dca74e7a9..f100aa624a59 100644 --- a/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py +++ b/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py @@ -144,22 +144,6 @@ def verify_p2mp_interface(tgen, router, nbr_cnt, nbr_adj_cnt, non_broadcast): "interfaces": { "r1-eth0": { "ospfEnabled": True, - "interfaceIp": { - "10.1.0.1": { - "ipAddress": "10.1.0.1", - "ipAddressPrefixlen": 24, - "ospfIfType": "Broadcast", - "routerId": "1.1.1.1", - "networkType": "POINTOMULTIPOINT", - "cost": 10, - "state": "Point-To-Point", - "nbrCount": nbr_cnt, - "nbrAdjacentCount": nbr_adj_cnt, - "prefixSuppression": False, - "p2mpDelayReflood": False, - "p2mpNonBroadcast": non_broadcast, - } - }, "ipAddress": "10.1.0.1", "ipAddressPrefixlen": 24, "ospfIfType": "Broadcast", From 59f5dd686a324f888602fa4a56f6da90e844103c Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 11 Jun 2024 11:40:40 +0300 Subject: [PATCH 243/472] tests: Check if BFD notification is sent and session remains in down state Signed-off-by: Donatas Abraitis --- .../r1/bfdd.conf | 4 + .../r1/bgpd.conf | 2 +- .../test_bgp_bfd_down_cease_notification.py | 3 + ...gp_bfd_down_cease_notification_shutdown.py | 122 ++++++++++++++++++ 4 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py diff --git a/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf b/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf index 0ae384eb53ca..1033b27c568d 100644 --- a/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf +++ b/tests/topotests/bgp_bfd_down_cease_notification/r1/bfdd.conf @@ -1,5 +1,9 @@ bfd + profile r1 + exit + ! peer 192.168.255.2 interface r1-eth0 + profile r1 exit ! exit diff --git a/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf b/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf index e855f75c20de..58a90d1a490c 100644 --- a/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf +++ b/tests/topotests/bgp_bfd_down_cease_notification/r1/bgpd.conf @@ -3,7 +3,7 @@ router bgp 65001 neighbor 192.168.255.2 remote-as external neighbor 192.168.255.2 timers 3 10 neighbor 192.168.255.2 timers connect 1 - neighbor 192.168.255.2 bfd + neighbor 192.168.255.2 bfd profile r1 neighbor 192.168.255.2 passive address-family ipv4 redistribute connected diff --git a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py index 00142981c502..3be34300078b 100644 --- a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py +++ b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py @@ -89,6 +89,9 @@ def _bgp_bfd_down_notification(): "192.168.255.1": { "lastNotificationReason": "Cease/BFD Down", "lastNotificationHardReset": True, + "peerBfdInfo": { + "status": "Up", + }, } } return topotest.json_cmp(output, expected) diff --git a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py new file mode 100644 index 000000000000..5ffeed5033ae --- /dev/null +++ b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification_shutdown.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# bgp_bfd_down_cease_notification_shutdown.py +# +# Copyright (c) 2024 by +# Donatas Abraitis +# + +""" +Check if Cease/BFD Down notification message is sent/received +when the BFD is down (administratively). +""" + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.common_config import kill_router_daemons, step + +pytestmark = [pytest.mark.bfdd, pytest.mark.bgpd] + + +def build_topo(tgen): + for routern in range(1, 3): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for i, (rname, router) in enumerate(router_list.items(), 1): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_BFD, os.path.join(CWD, "{}/bfdd.conf".format(rname)) + ) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_bfd_down_notification_shutdown(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _bgp_converge(): + output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "bgpState": "Established", + "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 2}}, + "peerBfdInfo": {"status": "Up"}, + } + } + return topotest.json_cmp(output, expected) + + def _bgp_bfd_down_notification(): + output = json.loads(r2.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json")) + expected = { + "192.168.255.1": { + "lastNotificationReason": "Cease/BFD Down", + "lastNotificationHardReset": True, + "peerBfdInfo": { + "status": "Down", + }, + } + } + return topotest.json_cmp(output, expected) + + step("Initial BGP converge") + test_func = functools.partial(_bgp_converge) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to see BGP convergence on R2" + + r1.vtysh_cmd( + """ + configure + bfd + profile r1 + shutdown + """ + ) + + step("Check if we received Cease/BFD Down notification message") + test_func = functools.partial(_bgp_bfd_down_notification) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Failed to see BGP Cease/BFD Down notification message on R2" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From ae1f3a48513f51c540788a090b05c24750665f55 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 11 Jun 2024 11:41:53 +0300 Subject: [PATCH 244/472] bgpd: Keep last notification's state about hard reset When we receive a hard-reset notification, we always show it if it was a hard, or not. For sending side, we missed that. Let's display it too. Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 1 + 1 file changed, 1 insertion(+) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 3f38790cbda3..8a4453f12472 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -982,6 +982,7 @@ static void bgp_notify_send_internal(struct peer_connection *connection, peer->notify.code = bgp_notify.code; peer->notify.subcode = bgp_notify.subcode; peer->notify.length = bgp_notify.length; + peer->notify.hard_reset = hard_reset; if (bgp_notify.length && data) { bgp_notify.data = XMALLOC(MTYPE_BGP_NOTIFICATION, From 3dad09b228e3c4a4ffa6da260fadda6762a77c58 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 11 Jun 2024 05:08:49 -0400 Subject: [PATCH 245/472] mgmtd: add native session-req (create/delete) messages This addition allows for a limited native-message-only front-end interaction. Signed-off-by: Christian Hopps --- lib/mgmt_msg_native.c | 27 +++++++++ lib/mgmt_msg_native.h | 45 ++++++++++++++- mgmtd/mgmt_fe_adapter.c | 124 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+), 1 deletion(-) diff --git a/lib/mgmt_msg_native.c b/lib/mgmt_msg_native.c index d0a0b72189ba..b85c7d1b6182 100644 --- a/lib/mgmt_msg_native.c +++ b/lib/mgmt_msg_native.c @@ -19,6 +19,33 @@ DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT, "native edit msg"); DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_EDIT_REPLY, "native edit reply msg"); DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_RPC, "native RPC msg"); DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_RPC_REPLY, "native RPC reply msg"); +DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_SESSION_REQ, "native session-req msg"); +DEFINE_MTYPE(MSG_NATIVE, MSG_NATIVE_SESSION_REPLY, "native session-reply msg"); + + +size_t mgmt_msg_min_sizes[] = { + [MGMT_MSG_CODE_ERROR] = sizeof(struct mgmt_msg_error), + [MGMT_MSG_CODE_GET_TREE] = sizeof(struct mgmt_msg_get_tree), + [MGMT_MSG_CODE_TREE_DATA] = sizeof(struct mgmt_msg_tree_data), + [MGMT_MSG_CODE_GET_DATA] = sizeof(struct mgmt_msg_get_data), + [MGMT_MSG_CODE_NOTIFY] = sizeof(struct mgmt_msg_notify_data), + [MGMT_MSG_CODE_EDIT] = sizeof(struct mgmt_msg_edit), + [MGMT_MSG_CODE_EDIT_REPLY] = sizeof(struct mgmt_msg_edit_reply), + [MGMT_MSG_CODE_RPC] = sizeof(struct mgmt_msg_rpc), + [MGMT_MSG_CODE_RPC_REPLY] = sizeof(struct mgmt_msg_rpc_reply), + [MGMT_MSG_CODE_NOTIFY_SELECT] = sizeof(struct mgmt_msg_notify_select), + [MGMT_MSG_CODE_SESSION_REQ] = sizeof(struct mgmt_msg_session_req), + [MGMT_MSG_CODE_SESSION_REPLY] = sizeof(struct mgmt_msg_session_reply), +}; +size_t nmgmt_msg_min_sizes = sizeof(mgmt_msg_min_sizes) / + sizeof(*mgmt_msg_min_sizes); + +size_t mgmt_msg_get_min_size(uint code) +{ + if (code >= nmgmt_msg_min_sizes) + return 0; + return mgmt_msg_min_sizes[code]; +} int vmgmt_msg_native_send_error(struct msg_conn *conn, uint64_t sess_or_txn_id, uint64_t req_id, bool short_circuit_ok, diff --git a/lib/mgmt_msg_native.h b/lib/mgmt_msg_native.h index e61346e6e5d5..76a52658cdee 100644 --- a/lib/mgmt_msg_native.h +++ b/lib/mgmt_msg_native.h @@ -163,6 +163,8 @@ DECLARE_MTYPE(MSG_NATIVE_EDIT); DECLARE_MTYPE(MSG_NATIVE_EDIT_REPLY); DECLARE_MTYPE(MSG_NATIVE_RPC); DECLARE_MTYPE(MSG_NATIVE_RPC_REPLY); +DECLARE_MTYPE(MSG_NATIVE_SESSION_REQ); +DECLARE_MTYPE(MSG_NATIVE_SESSION_REPLY); /* * Native message codes @@ -177,6 +179,8 @@ DECLARE_MTYPE(MSG_NATIVE_RPC_REPLY); #define MGMT_MSG_CODE_RPC 7 /* Public API */ #define MGMT_MSG_CODE_RPC_REPLY 8 /* Public API */ #define MGMT_MSG_CODE_NOTIFY_SELECT 9 /* Public API */ +#define MGMT_MSG_CODE_SESSION_REQ 10 /* Public API */ +#define MGMT_MSG_CODE_SESSION_REPLY 11 /* Public API */ /* * Datastores @@ -434,7 +438,7 @@ _Static_assert(sizeof(struct mgmt_msg_rpc_reply) == * to the front-end client. * * @selectors: the xpath prefixes to selectors notifications through. - * @repalce: if true replace existing selectors with `selectors`. + * @replace: if true replace existing selectors with `selectors`. */ struct mgmt_msg_notify_select { struct mgmt_msg_header; @@ -448,12 +452,51 @@ _Static_assert(sizeof(struct mgmt_msg_notify_select) == offsetof(struct mgmt_msg_notify_select, selectors), "Size mismatch"); +/** + * struct mgmt_msg_session_req - Create or delete a front-end session. + * + * @refer_id: Zero for create, otherwise the session-id to delete. + * @req_id: For create will use as client-id. + * @client_name: For first session request the client name, otherwise empty. + */ +struct mgmt_msg_session_req { + struct mgmt_msg_header; + uint8_t resv2[8]; /* bug in compiler produces error w/o this */ + + alignas(8) char client_name[]; +}; + +_Static_assert(sizeof(struct mgmt_msg_session_req) == + offsetof(struct mgmt_msg_session_req, client_name), + "Size mismatch"); + +/** + * struct mgmt_msg_session_reply - Reply to session request message. + * + * @created: true if this is a reply to a create request, otherwise 0. + * @refer_id: The session-id for the action (create or delete) just taken. + */ +struct mgmt_msg_session_reply { + struct mgmt_msg_header; + uint8_t created; + uint8_t resv2[7]; +}; + /* * Validate that the message ends in a NUL terminating byte */ #define MGMT_MSG_VALIDATE_NUL_TERM(msgp, len) \ ((len) >= sizeof(*msgp) + 1 && ((char *)msgp)[(len)-1] == 0) +/** + * mgmt_msg_get_min_size() - Get minimum message size given the type + * @code: The type of the message (MGMT_MSG_CODE_*) + * + * Return: + * The minimum size of a message of the given type or 0 if the message + * code is unknown. + */ +size_t mgmt_msg_get_min_size(uint code); /** * Send a native message error to the other end of the connection. diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index a076dc72f96b..5f53c928a47e 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -490,6 +490,26 @@ static int fe_adapter_send_get_reply(struct mgmt_fe_session_ctx *session, return fe_adapter_send_msg(session->adapter, &fe_msg, false); } +static int fe_adapter_conn_send_error(struct msg_conn *conn, + uint64_t session_id, uint64_t req_id, + bool short_circuit_ok, int16_t error, + const char *errfmt, ...) PRINTFRR(6, 7); +static int fe_adapter_conn_send_error(struct msg_conn *conn, uint64_t session_id, + uint64_t req_id, bool short_circuit_ok, + int16_t error, const char *errfmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, errfmt); + + ret = vmgmt_msg_native_send_error(conn, session_id, req_id, + short_circuit_ok, error, errfmt, ap); + va_end(ap); + + return ret; +} + static int fe_adapter_send_error(struct mgmt_fe_session_ctx *session, uint64_t req_id, bool short_circuit_ok, int16_t error, const char *errfmt, ...) @@ -1170,6 +1190,88 @@ static int fe_adapter_send_edit_reply(struct mgmt_fe_session_ctx *session, return ret; } +static int +fe_adapter_native_send_session_reply(struct mgmt_fe_client_adapter *adapter, + uint64_t req_id, uint64_t session_id, + bool created) +{ + struct mgmt_msg_session_reply *msg; + int ret; + + msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_session_reply, 0, + MTYPE_MSG_NATIVE_SESSION_REPLY); + msg->refer_id = session_id; + msg->req_id = req_id; + msg->code = MGMT_MSG_CODE_SESSION_REPLY; + msg->created = created; + + __dbg("Sending session-reply from adapter %s to session-id %" PRIu64 + " req-id %" PRIu64 " len %u", + adapter->name, session_id, req_id, + mgmt_msg_native_get_msg_len(msg)); + + ret = fe_adapter_send_native_msg(adapter, msg, + mgmt_msg_native_get_msg_len(msg), + false); + mgmt_msg_native_free_msg(msg); + + return ret; +} + +/** + * fe_adapter_handle_session_req() - Handle a session-req message from a FE client. + * @msg_raw: the message data. + * @msg_len: the length of the message data. + */ +static void fe_adapter_handle_session_req(struct mgmt_fe_client_adapter *adapter, + void *__msg, size_t msg_len) +{ + struct mgmt_msg_session_req *msg = __msg; + struct mgmt_fe_session_ctx *session; + uint64_t client_id; + + __dbg("Got session-req creating: %u for refer-id %" PRIu64 " from '%s'", + msg->refer_id == 0, msg->refer_id, adapter->name); + + if (msg->refer_id) { + uint64_t session_id = msg->refer_id; + + session = mgmt_session_id2ctx(session_id); + if (!session) { + fe_adapter_conn_send_error( + adapter->conn, session_id, msg->req_id, false, + -EINVAL, + "No session to delete for session-id: %" PRIu64, + session_id); + return; + } + fe_adapter_native_send_session_reply(adapter, msg->req_id, + session_id, false); + mgmt_fe_cleanup_session(&session); + return; + } + + client_id = msg->req_id; + + /* See if we have a client name to register */ + if (msg_len > sizeof(*msg)) { + if (!MGMT_MSG_VALIDATE_NUL_TERM(msg, msg_len)) { + fe_adapter_conn_send_error( + adapter->conn, client_id, msg->req_id, false, + -EINVAL, + "Corrupt session-req message rcvd from client-id: %" PRIu64, + client_id); + return; + } + __dbg("Set client-name to '%s'", msg->client_name); + strlcpy(adapter->name, msg->client_name, sizeof(adapter->name)); + } + + session = mgmt_fe_create_session(adapter, client_id); + fe_adapter_native_send_session_reply(adapter, client_id, + session->session_id, true); +} + /** * fe_adapter_handle_get_data() - Handle a get-tree message from a FE client. * @session: the client session. @@ -1529,6 +1631,28 @@ static void fe_adapter_handle_native_msg(struct mgmt_fe_client_adapter *adapter, size_t msg_len) { struct mgmt_fe_session_ctx *session; + size_t min_size = mgmt_msg_get_min_size(msg->code); + + if (msg_len < min_size) { + if (!min_size) + __log_err("adapter %s: recv msg refer-id %" PRIu64 + " unknown message type %u", + adapter->name, msg->refer_id, msg->code); + else + __log_err("adapter %s: recv msg refer-id %" PRIu64 + " short (%zu<%zu) msg for type %u", + adapter->name, msg->refer_id, msg_len, + min_size, msg->code); + return; + } + + if (msg->code == MGMT_MSG_CODE_SESSION_REQ) { + __dbg("adapter %s: session-id %" PRIu64 + " received SESSION_REQ message", + adapter->name, msg->refer_id); + fe_adapter_handle_session_req(adapter, msg, msg_len); + return; + } session = mgmt_session_id2ctx(msg->refer_id); if (!session) { From 27e369487eb602b75ea353e8c21333bd83032a86 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 11 Jun 2024 10:26:08 -0400 Subject: [PATCH 246/472] tests: add native session-req/reply support to fe_client.py Use this to test new native message format for creating sessions. Signed-off-by: Christian Hopps --- tests/topotests/lib/fe_client.py | 61 +++++++++++++++++------- tests/topotests/mgmt_notif/test_notif.py | 2 +- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/tests/topotests/lib/fe_client.py b/tests/topotests/lib/fe_client.py index 019b3239ca99..d61bc850b4d2 100755 --- a/tests/topotests/lib/fe_client.py +++ b/tests/topotests/lib/fe_client.py @@ -84,6 +84,11 @@ MSG_NOTIFY_SELECT_FMT = "=B7x" +MSG_SESSION_REQ_FMT = "=8x" + +MSG_SESSION_REPLY_FMT = "=B7x" +SESSION_REPLY_FIELD_CREATED = 0 + # # Native message codes # @@ -93,6 +98,8 @@ MSG_CODE_GET_DATA = 3 MSG_CODE_NOTIFY = 4 MSG_CODE_NOTIFY_SELECT = 9 +MSG_CODE_SESSION_REQ = 10 +MSG_CODE_SESSION_REPLY = 11 msg_native_formats = { MSG_CODE_ERROR: MSG_ERROR_FMT, @@ -101,6 +108,8 @@ MSG_CODE_GET_DATA: MSG_GET_DATA_FMT, MSG_CODE_NOTIFY: MSG_NOTIFY_FMT, MSG_CODE_NOTIFY_SELECT: MSG_NOTIFY_SELECT_FMT, + MSG_CODE_SESSION_REQ: MSG_SESSION_REQ_FMT, + MSG_CODE_SESSION_REPLY: MSG_SESSION_REPLY_FMT, } @@ -183,27 +192,44 @@ class Session: client_id = 1 - def __init__(self, sock): + def __init__(self, sock, use_protobuf): self.sock = sock self.next_req_id = 1 - req = mgmt_pb2.FeMessage() - req.register_req.client_name = "test-client" - self.send_pb_msg(req) - logging.debug("Sent FeRegisterReq: %s", req) + if use_protobuf: + req = mgmt_pb2.FeMessage() + req.register_req.client_name = "test-client" + self.send_pb_msg(req) + logging.debug("Sent FeRegisterReq: %s", req) - req = mgmt_pb2.FeMessage() - req.session_req.create = 1 - req.session_req.client_conn_id = Session.client_id - Session.client_id += 1 - self.send_pb_msg(req) - logging.debug("Sent FeSessionReq: %s", req) + req = mgmt_pb2.FeMessage() + req.session_req.create = 1 + req.session_req.client_conn_id = Session.client_id + Session.client_id += 1 + self.send_pb_msg(req) + logging.debug("Sent FeSessionReq: %s", req) - reply = self.recv_pb_msg(mgmt_pb2.FeMessage()) - logging.debug("Received FeSessionReply: %s", repr(reply)) + reply = self.recv_pb_msg(mgmt_pb2.FeMessage()) + logging.debug("Received FeSessionReply: %s", repr(reply)) - assert reply.session_reply.success - self.sess_id = reply.session_reply.session_id + assert reply.session_reply.success + self.sess_id = reply.session_reply.session_id + else: + self.sess_id = 0 + mdata, req_id = self.get_native_msg_header(MSG_CODE_SESSION_REQ) + mdata += struct.pack(MSG_SESSION_REQ_FMT) + mdata += "test-client".encode("utf-8") + b"\x00" + + self.send_native_msg(mdata) + logging.debug("Sent native SESSION-REQ") + + mhdr, mfixed, mdata = self.recv_native_msg() + if mhdr[HDR_FIELD_CODE] == MSG_CODE_SESSION_REPLY: + logging.debug("Recv native SESSION-REQ Message: %s: %s", mfixed, mdata) + else: + raise Exception(f"Recv NON-SESSION-REPLY Message: {mfixed}: {mdata}") + assert mfixed[0] + self.sess_id = mhdr[HDR_FIELD_SESS_ID] def close(self, clean=True): if clean: @@ -368,6 +394,9 @@ def __parse_args(): "-q", "--query", nargs="+", metavar="XPATH", help="xpath[s] to query" ) parser.add_argument("-s", "--server", default=MPATH, help="path to server socket") + parser.add_argument( + "--use-protobuf", action="store_true", help="Use protobuf when there's a choice" + ) parser.add_argument("-v", "--verbose", action="store_true", help="Be verbose") args = parser.parse_args() @@ -392,7 +421,7 @@ def __server_connect(spath): def __main(): args = __parse_args() sock = __server_connect(Path(args.server)) - sess = Session(sock) + sess = Session(sock, use_protobuf=args.use_protobuf) if args.query: # Performa an xpath query diff --git a/tests/topotests/mgmt_notif/test_notif.py b/tests/topotests/mgmt_notif/test_notif.py index de984b12e1ec..01466892a880 100644 --- a/tests/topotests/mgmt_notif/test_notif.py +++ b/tests/topotests/mgmt_notif/test_notif.py @@ -69,7 +69,7 @@ def test_frontend_notification(tgen): result = json_cmp(jsout, expected) assert result is None - output = r1.cmd_raises(fe_client_path + " --listen") + output = r1.cmd_raises(fe_client_path + " --use-protobuf --listen") jsout = json.loads(output) expected = {"frr-ripd:authentication-failure": {"interface-name": "r1-eth0"}} From ee8b65f23beb1d7a21bc121fd836cbc9e89805e3 Mon Sep 17 00:00:00 2001 From: Alexander Trotsenko Date: Sun, 9 Jun 2024 01:10:02 +0300 Subject: [PATCH 247/472] doc: Add reloading script into Python dependency section Signed-off-by: Alexander Trotsenko --- doc/user/installation.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/user/installation.rst b/doc/user/installation.rst index d17112d8aa18..e49f10491e4e 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -422,7 +422,12 @@ options to the configuration script. Python dependency, documentation and tests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -FRR's documentation and basic unit tests heavily use code written in Python. +FRR uses Python for these components: + +* configuration reloading (see :ref:`FRR-RELOAD ` for details), +* documentation, +* unit tests. + Additionally, FRR ships Python extensions written in C which are used during its build process. From 1fb48f5d13faf4ec1e6d4c2cdded9ca2dcd6d609 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 12 Jun 2024 08:39:48 +0300 Subject: [PATCH 248/472] bgpd: Do not start BGP session if BFD profile is in shutdown state If we do: ``` bfd profile foo shutdown ``` The session is dropped, but immediately established again because we don't have a proper check on BFD. If BFD is administratively shutdown, ignore starting the session. Fixes: https://github.com/FRRouting/frr/issues/16186 Signed-off-by: Donatas Abraitis --- bgpd/bgpd.c | 6 ++++++ lib/bfd.c | 6 ++++++ lib/bfd.h | 2 ++ 3 files changed, 14 insertions(+) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 81506f4410b1..869d2b455214 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -4507,6 +4507,12 @@ bool peer_active(struct peer *peer) { if (BGP_CONNECTION_SU_UNSPEC(peer->connection)) return false; + + if (peer->bfd_config) { + if (bfd_session_is_down(peer->bfd_config->session)) + return false; + } + if (peer->afc[AFI_IP][SAFI_UNICAST] || peer->afc[AFI_IP][SAFI_MULTICAST] || peer->afc[AFI_IP][SAFI_LABELED_UNICAST] || peer->afc[AFI_IP][SAFI_MPLS_VPN] || peer->afc[AFI_IP][SAFI_ENCAP] diff --git a/lib/bfd.c b/lib/bfd.c index 2222bb954737..4535fc123378 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -1334,3 +1334,9 @@ int bfd_nht_update(const struct prefix *match, const struct zapi_route *route) return 0; } + +bool bfd_session_is_down(const struct bfd_session_params *session) +{ + return session->bss.state == BSS_DOWN || + session->bss.state == BSS_ADMIN_DOWN; +} diff --git a/lib/bfd.h b/lib/bfd.h index bfa5287340f2..48929a95642c 100644 --- a/lib/bfd.h +++ b/lib/bfd.h @@ -464,6 +464,8 @@ extern bool bfd_protocol_integration_shutting_down(void); extern int bfd_nht_update(const struct prefix *match, const struct zapi_route *route); +extern bool bfd_session_is_down(const struct bfd_session_params *session); + #ifdef __cplusplus } #endif From a63bfb75669780df7ce29201c87db77b83c6f60a Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Wed, 12 Jun 2024 13:56:34 +0530 Subject: [PATCH 249/472] tests: supress unused variables at topotests For code maintainability, suppressed unused variables with "_" Signed-off-by: y-bharath14 --- tests/topotests/bfd_topo3/test_bfd_topo3.py | 2 +- .../bfd_vrf_topo1/test_bfd_vrf_topo1.py | 2 +- .../bgp_accept_own/test_bgp_accept_own.py | 2 +- .../test_bgp_addpath_best_selected.py | 2 +- ...test_bgp_aggregate_address_matching_med.py | 2 +- .../test_bgp_aggregate-address_origin.py | 6 +- .../test_bgp_aggregate-address_route-map.py | 2 +- .../test_bgp_aggregator_zero.py | 4 +- tests/topotests/bgp_aigp/test_bgp_aigp.py | 2 +- .../bgp_as_override/test_bgp_as_override.py | 2 +- .../test_bgp_as_wide_bgp_identifier.py | 6 +- .../bgp_asdot_regex/test_bgp_asdot_regex.py | 4 +- .../bgp_aspath_zero/test_bgp_aspath_zero.py | 4 +- tests/topotests/bgp_auth/test_bgp_auth1.py | 2 +- tests/topotests/bgp_auth/test_bgp_auth2.py | 2 +- tests/topotests/bgp_auth/test_bgp_auth3.py | 2 +- tests/topotests/bgp_auth/test_bgp_auth4.py | 2 +- .../test_bgp_bfd_down_cease_notification.py | 2 +- .../test_bgp_blackhole_community.py | 10 ++-- .../test_bgp_comm-list_delete.py | 2 +- .../test_bgp_comm_list_match.py | 2 +- .../test_bgp-community-alias.py | 8 +-- .../test_bgp_community_change_update.py | 8 +-- .../test_bgp_conditional_advertisement.py | 58 +++++++++---------- ...gp_conditional_advertisement_track_peer.py | 2 +- .../test_bgp_confederation_astype.py | 2 +- .../test_bgp-default-afi-safi.py | 2 +- .../test_bgp_default_originate_timer.py | 2 +- .../test_bgp_default_originate_withdraw.py | 2 +- .../test_bgp_default-originate.py | 10 ++-- ...t_bgp_default-originate_route-map_match.py | 6 +- ..._bgp_default-originate_route-map_match2.py | 10 ++-- ...p_default-originate_route-map_match_set.py | 6 +- ...est_bgp_default-originate_route-map_set.py | 2 +- .../test_disable_addpath_rx.py | 6 +- .../test_bgp_distance_change.py | 6 +- .../test_bgp_dont_capability_negotiate.py | 2 +- ...gp-ebgp-common-subnet-nexthop-unchanged.py | 6 +- .../test_bgp_ebgp_requires_policy.py | 14 ++--- .../test_bgp_extcomm-list_delete.py | 2 +- ...bgp_extended_optional_parameters_length.py | 2 +- .../test_bgp_gr_notification.py | 2 +- tests/topotests/bgp_gshut/test_bgp_gshut.py | 2 +- .../test_bgp_ipv4_class_e_peer.py | 2 +- .../test_bgp_ipv6_ll_peering.py | 2 +- .../test_bgp_l3vpn_label_export.py | 2 +- .../test_bgp_labeled_unicast_addpath.py | 2 +- ...t_bgp_labeled_unicast_default_originate.py | 2 +- .../test_bgp_large_comm_list_match.py | 2 +- tests/topotests/bgp_llgr/test_bgp_llgr.py | 2 +- .../bgp_local_as/test_bgp_local_as.py | 2 +- ...est_bgp_local_as_dotplus_private_remove.py | 2 +- .../test_bgp_local_as_private_remove.py | 2 +- .../test_bgp_lu_explicitnull.py | 6 +- .../test_bgp_max_med_on_startup.py | 8 +-- .../test_bgp_maximum_prefix_invalid_update.py | 2 +- .../test_bgp_maximum_prefix_out.py | 4 +- .../test_bgp_minimum_holdtime.py | 4 +- .../test_bgp_node_target_extcommunities.py | 2 +- tests/topotests/bgp_orf/test_bgp_orf.py | 2 +- .../test_bgp_path_selection.py | 2 +- .../test_bgp_peer_graceful_shutdown.py | 2 +- .../bgp_peer_group/test_bgp_peer-group.py | 2 +- .../test_bgp_prefix_list_any.py | 2 +- .../bgp_prefix_sid/test_bgp_prefix_sid.py | 8 +-- .../test_bgp_reject_as_sets.py | 8 +-- .../test_bgp_remove_private_as.py | 2 +- .../test_bgp_remove_private_as_route_map.py | 2 +- .../test_bgp_rmap_extcommunity_none.py | 6 +- .../test_bgp_roles_capability.py | 10 ++-- .../test_bgp_roles_filtering.py | 2 +- .../test_bgp_route_map_delay_timer.py | 2 +- .../test_bgp_route_map_match_ipv6_nexthop.py | 4 +- ...est_bgp_route_map_match_source_protocol.py | 2 +- .../test_bgp_route_map_on_match_next.py | 8 +-- .../test_bgp_route_map_vpn_import.py | 2 +- .../test_bgp_route_server_client.py | 2 +- .../bgp_rpki_topo1/test_bgp_rpki_topo1.py | 2 +- .../test_bgp_sender-as-path-loop-detection.py | 2 +- .../test_bgp_set_aspath_exclude.py | 2 +- .../test_bgp_set_aspath_replace.py | 2 +- ...t_bgp_set_local-preference_add_subtract.py | 6 +- .../test_bgp_software_version.py | 2 +- tests/topotests/bgp_soo/test_bgp_soo.py | 2 +- .../test_bgp_srv6l3vpn_sid.py | 4 +- .../test_bgp_srv6l3vpn_to_bgp_vrf.py | 2 +- .../test_bgp_srv6l3vpn_to_bgp_vrf2.py | 2 +- .../test_bgp_srv6l3vpn_to_bgp_vrf3.py | 2 +- .../bgp_suppress_fib/test_bgp_suppress_fib.py | 2 +- .../topotests/bgp_tcp_mss/test_bgp_tcp_mss.py | 10 ++-- .../test_bgp_tcp_mss_passive.py | 2 +- .../bgp_unnumbered/test_bgp_unnumbered.py | 6 +- .../bgp_update_delay/test_bgp_update_delay.py | 20 +++---- .../test_bgp_vpn_5549_route_map.py | 2 +- .../bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py | 28 ++++----- .../bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py | 14 ++--- .../test_bgp_vpnv4_per_nexthop_label.py | 24 ++++---- .../test_bgp_vpnv6_per_nexthop_label.py | 22 +++---- 98 files changed, 248 insertions(+), 248 deletions(-) diff --git a/tests/topotests/bfd_topo3/test_bfd_topo3.py b/tests/topotests/bfd_topo3/test_bfd_topo3.py index d7b2542f9ffd..a899a2b464d2 100644 --- a/tests/topotests/bfd_topo3/test_bfd_topo3.py +++ b/tests/topotests/bfd_topo3/test_bfd_topo3.py @@ -95,7 +95,7 @@ def expect_route_missing(router, iptype, route): "show {} route json".format(iptype), {route: None}, ) - rv, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) assertmsg = '"{}" convergence failure'.format(router) assert result is None, assertmsg diff --git a/tests/topotests/bfd_vrf_topo1/test_bfd_vrf_topo1.py b/tests/topotests/bfd_vrf_topo1/test_bfd_vrf_topo1.py index 9e5a68f0a313..f6adff61d0ed 100644 --- a/tests/topotests/bfd_vrf_topo1/test_bfd_vrf_topo1.py +++ b/tests/topotests/bfd_vrf_topo1/test_bfd_vrf_topo1.py @@ -61,7 +61,7 @@ def setup_module(mod): router_list = tgen.routers() # check for zebra capability - for rname, router in router_list.items(): + for _, router in router_list.items(): if router.check_capability(TopoRouter.RD_ZEBRA, "--vrfwnetns") == False: return pytest.skip( "Skipping BFD Topo1 VRF NETNS feature. VRF NETNS backend not available on FRR" diff --git a/tests/topotests/bgp_accept_own/test_bgp_accept_own.py b/tests/topotests/bgp_accept_own/test_bgp_accept_own.py index d294da0934b9..11b24baa826c 100644 --- a/tests/topotests/bgp_accept_own/test_bgp_accept_own.py +++ b/tests/topotests/bgp_accept_own/test_bgp_accept_own.py @@ -68,7 +68,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py b/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py index 2a610c901ec3..3d17a2b70977 100644 --- a/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py +++ b/tests/topotests/bgp_addpath_best_selected/test_bgp_addpath_best_selected.py @@ -51,7 +51,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_aggregate_address_matching_med/test_bgp_aggregate_address_matching_med.py b/tests/topotests/bgp_aggregate_address_matching_med/test_bgp_aggregate_address_matching_med.py index 5a4a5fb657cf..0520b5e1369d 100644 --- a/tests/topotests/bgp_aggregate_address_matching_med/test_bgp_aggregate_address_matching_med.py +++ b/tests/topotests/bgp_aggregate_address_matching_med/test_bgp_aggregate_address_matching_med.py @@ -49,7 +49,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_aggregate_address_origin/test_bgp_aggregate-address_origin.py b/tests/topotests/bgp_aggregate_address_origin/test_bgp_aggregate-address_origin.py index 739685d41764..188bbd0b98af 100644 --- a/tests/topotests/bgp_aggregate_address_origin/test_bgp_aggregate-address_origin.py +++ b/tests/topotests/bgp_aggregate_address_origin/test_bgp_aggregate-address_origin.py @@ -49,7 +49,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -89,12 +89,12 @@ def _bgp_aggregate_address_has_metric(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, 'Failed to see bgp convergence in "{}"'.format(router) test_func = functools.partial(_bgp_aggregate_address_has_metric, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert ( result is None diff --git a/tests/topotests/bgp_aggregate_address_route_map/test_bgp_aggregate-address_route-map.py b/tests/topotests/bgp_aggregate_address_route_map/test_bgp_aggregate-address_route-map.py index eeac7146b1fa..2343440aaf25 100644 --- a/tests/topotests/bgp_aggregate_address_route_map/test_bgp_aggregate-address_route-map.py +++ b/tests/topotests/bgp_aggregate_address_route_map/test_bgp_aggregate-address_route-map.py @@ -52,7 +52,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_aggregator_zero/test_bgp_aggregator_zero.py b/tests/topotests/bgp_aggregator_zero/test_bgp_aggregator_zero.py index d9ef3e1ce151..1a52f8c90ee6 100644 --- a/tests/topotests/bgp_aggregator_zero/test_bgp_aggregator_zero.py +++ b/tests/topotests/bgp_aggregator_zero/test_bgp_aggregator_zero.py @@ -73,7 +73,7 @@ def _bgp_converge(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r1"]) @@ -99,7 +99,7 @@ def _bgp_has_correct_aggregator_route_with_good_asn(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_has_correct_aggregator_route_with_good_asn) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Aggregator AS attribute not found in "{}"'.format( tgen.gears["r1"] diff --git a/tests/topotests/bgp_aigp/test_bgp_aigp.py b/tests/topotests/bgp_aigp/test_bgp_aigp.py index 655e9ad18485..e3b32da16476 100644 --- a/tests/topotests/bgp_aigp/test_bgp_aigp.py +++ b/tests/topotests/bgp_aigp/test_bgp_aigp.py @@ -73,7 +73,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_as_override/test_bgp_as_override.py b/tests/topotests/bgp_as_override/test_bgp_as_override.py index 7cb4f81cfc18..dbbdf2c88f8e 100644 --- a/tests/topotests/bgp_as_override/test_bgp_as_override.py +++ b/tests/topotests/bgp_as_override/test_bgp_as_override.py @@ -49,7 +49,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py b/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py index 5c09a6b0e0b9..e8e3b4171a66 100644 --- a/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py +++ b/tests/topotests/bgp_as_wide_bgp_identifier/test_bgp_as_wide_bgp_identifier.py @@ -48,7 +48,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -85,12 +85,12 @@ def _bgp_failed(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, tgen.gears["r1"]) - success, result = topotest.run_and_expect(test_func, None, count=260, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=260, wait=0.5) assert result is None, 'Failed to converge: "{}"'.format(tgen.gears["r1"]) test_func = functools.partial(_bgp_failed, tgen.gears["r3"]) - success, result = topotest.run_and_expect(test_func, None, count=260, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=260, wait=0.5) assert result is None, 'Bad BGP Identifier notification not sent: "{}"'.format( tgen.gears["r3"] diff --git a/tests/topotests/bgp_asdot_regex/test_bgp_asdot_regex.py b/tests/topotests/bgp_asdot_regex/test_bgp_asdot_regex.py index 4883e847c9c7..09803dfa842b 100644 --- a/tests/topotests/bgp_asdot_regex/test_bgp_asdot_regex.py +++ b/tests/topotests/bgp_asdot_regex/test_bgp_asdot_regex.py @@ -60,7 +60,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -97,7 +97,7 @@ def _bgp_converge(router): logger.info("Check if neighbor sessions are up in {}".format(router1.name)) test_func = partial(_bgp_converge, router1) - success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see BGP convergence in "{}"'.format(router1.name) logger.info("BGP neighbor session is up in {}".format(router1.name)) diff --git a/tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py b/tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py index 0f1a08308fd0..fe89a87621ca 100644 --- a/tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py +++ b/tests/topotests/bgp_aspath_zero/test_bgp_aspath_zero.py @@ -73,7 +73,7 @@ def _bgp_converge(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "More than one prefix seen at r1, SHOULD be only one." def _bgp_has_correct_routes_without_asn_0(): @@ -82,7 +82,7 @@ def _bgp_has_correct_routes_without_asn_0(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_has_correct_routes_without_asn_0) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed listing 192.168.100.101/32, SHOULD be accepted." diff --git a/tests/topotests/bgp_auth/test_bgp_auth1.py b/tests/topotests/bgp_auth/test_bgp_auth1.py index 9d47106c072f..c19a740a92b7 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth1.py +++ b/tests/topotests/bgp_auth/test_bgp_auth1.py @@ -156,7 +156,7 @@ def setup_module(mod): router_list = tgen.routers() # For all registered routers, load the zebra configuration file - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") router.load_config(TopoRouter.RD_OSPF, "") router.load_config(TopoRouter.RD_BGP, "") diff --git a/tests/topotests/bgp_auth/test_bgp_auth2.py b/tests/topotests/bgp_auth/test_bgp_auth2.py index 6b920367270f..2551c1c35b7f 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth2.py +++ b/tests/topotests/bgp_auth/test_bgp_auth2.py @@ -156,7 +156,7 @@ def setup_module(mod): router_list = tgen.routers() # For all registered routers, load the zebra configuration file - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") router.load_config(TopoRouter.RD_OSPF, "") router.load_config(TopoRouter.RD_BGP, "") diff --git a/tests/topotests/bgp_auth/test_bgp_auth3.py b/tests/topotests/bgp_auth/test_bgp_auth3.py index 2237c6b1b6dc..dc4f61d3c99d 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth3.py +++ b/tests/topotests/bgp_auth/test_bgp_auth3.py @@ -155,7 +155,7 @@ def setup_module(mod): router_list = tgen.routers() # For all registered routers, load the zebra configuration file - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") router.load_config(TopoRouter.RD_OSPF, "") router.load_config(TopoRouter.RD_BGP, "") diff --git a/tests/topotests/bgp_auth/test_bgp_auth4.py b/tests/topotests/bgp_auth/test_bgp_auth4.py index d6fe42504bc2..afe4441e13ed 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth4.py +++ b/tests/topotests/bgp_auth/test_bgp_auth4.py @@ -155,7 +155,7 @@ def setup_module(mod): router_list = tgen.routers() # For all registered routers, load the zebra configuration file - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") router.load_config(TopoRouter.RD_OSPF, "") router.load_config(TopoRouter.RD_BGP, "") diff --git a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py index 00142981c502..8536b3506f53 100644 --- a/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py +++ b/tests/topotests/bgp_bfd_down_cease_notification/test_bgp_bfd_down_cease_notification.py @@ -45,7 +45,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py b/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py index 9f5c0ef924bd..05a9a1e7f616 100644 --- a/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py +++ b/tests/topotests/bgp_blackhole_community/test_bgp_blackhole_community.py @@ -51,7 +51,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -125,14 +125,14 @@ def _bgp_verify_nexthop_validity(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, 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"]) step("Check if 172.16.255.254/32 is not advertised to eBGP peers") test_func = functools.partial(_bgp_no_advertise_ebgp) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert ( result is None @@ -142,7 +142,7 @@ def _bgp_verify_nexthop_validity(): step("Check if 172.16.255.254/32 is advertised to iBGP peers") test_func = functools.partial(_bgp_no_advertise_ibgp) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert ( result is None @@ -152,7 +152,7 @@ def _bgp_verify_nexthop_validity(): step("Verify if the nexthop set via route-map on r4 is marked valid") test_func = functools.partial(_bgp_verify_nexthop_validity) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Nexthops are not valid "{}"'.format(tgen.gears["r4"]) diff --git a/tests/topotests/bgp_comm_list_delete/test_bgp_comm-list_delete.py b/tests/topotests/bgp_comm_list_delete/test_bgp_comm-list_delete.py index efc8f200a35e..2064dac6e65b 100644 --- a/tests/topotests/bgp_comm_list_delete/test_bgp_comm-list_delete.py +++ b/tests/topotests/bgp_comm_list_delete/test_bgp_comm-list_delete.py @@ -48,7 +48,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py b/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py index de69ea9387ed..d0cab26e1afe 100644 --- a/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py +++ b/tests/topotests/bgp_comm_list_match/test_bgp_comm_list_match.py @@ -56,7 +56,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py index fdae9a3aa748..9df73a51ba8a 100644 --- a/tests/topotests/bgp_community_alias/test_bgp-community-alias.py +++ b/tests/topotests/bgp_community_alias/test_bgp-community-alias.py @@ -40,7 +40,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -92,7 +92,7 @@ def _bgp_converge(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Cannot see BGP community aliases at r1" def _bgp_show_prefixes_by_alias(router): @@ -118,7 +118,7 @@ def _bgp_show_prefixes_by_alias(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_show_prefixes_by_alias, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Cannot see BGP prefixes by community alias at r1" def _bgp_show_prefixes_by_large_community_list(router): @@ -129,7 +129,7 @@ def _bgp_show_prefixes_by_large_community_list(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_show_prefixes_by_large_community_list, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Cannot see BGP prefixes by large community list at r1" diff --git a/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py index 5ad15e064589..c0a92efba9a7 100644 --- a/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py +++ b/tests/topotests/bgp_community_change_update/test_bgp_community_change_update.py @@ -97,7 +97,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -133,7 +133,7 @@ def _bgp_converge_initial(): step("Check if an initial topology is converged") test_func = functools.partial(_bgp_converge_initial) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to see bgp convergence in c1" step("Disable link between y1 and y2") @@ -146,7 +146,7 @@ def _bgp_converge_link_disabled(): step("Check if a topology is converged after a link down between y1 and y2") test_func = functools.partial(_bgp_converge_link_disabled) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to see bgp convergence in y1" def _bgp_check_for_duplicate_updates(): @@ -193,7 +193,7 @@ def _bgp_converge_link_enabled(): step("Check if a topology is converged after a link up between y1 and y2") test_func = functools.partial(_bgp_converge_link_enabled) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to see bgp convergence in y1" step( diff --git a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py index 0128c8834916..577bf9fd7602 100644 --- a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py +++ b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py @@ -159,7 +159,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -426,7 +426,7 @@ def test_bgp_conditional_advertisement_tc_2_1(): ) test_func = functools.partial(exist_map_routes_present, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = 'TC21: exist-map routes present in "router2" BGP table - ' assert result is None, msg + failed @@ -455,7 +455,7 @@ def test_bgp_conditional_advertisement_tc_2_2(): ) test_func = functools.partial(exist_map_routes_not_present, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = 'TC22: exist-map routes not present in "router2" BGP table - ' assert result is None, msg + failed @@ -484,7 +484,7 @@ def test_bgp_conditional_advertisement_tc_2_3(): ) test_func = functools.partial(default_route_withdrawn, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC23: advertise-map with exist-map configuration is removed from peer - " assert result is None, msg + failed @@ -513,7 +513,7 @@ def test_bgp_conditional_advertisement_tc_3_1(): ) test_func = functools.partial(non_exist_map_routes_not_present, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = 'TC31: non-exist-map routes not present in "router2" BGP table - ' assert result is None, msg + failed @@ -542,7 +542,7 @@ def test_bgp_conditional_advertisement_tc_3_2(): ) test_func = functools.partial(non_exist_map_routes_present, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = 'TC32: non-exist-map routes present in "router2" BGP table - ' assert result is None, msg + failed @@ -571,7 +571,7 @@ def test_bgp_conditional_advertisement_tc_3_3(): ) test_func = functools.partial(all_routes_advertised, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = ( "TC33: advertise-map with non-exist-map configuration is removed from a peer - " @@ -603,7 +603,7 @@ def test_bgp_conditional_advertisement_tc_4_1(): ) test_func = functools.partial(non_exist_map_no_condition_route_map, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = 'TC41: non-exist-map route-map removed in "router2" - ' assert result is None, msg + failed @@ -632,7 +632,7 @@ def test_bgp_conditional_advertisement_tc_4_2(): ) test_func = functools.partial(exist_map_no_condition_route_map, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = 'TC42: exist-map route-map removed in "router2" - ' assert result is None, msg + failed @@ -665,7 +665,7 @@ def test_bgp_conditional_advertisement_tc_5_1(): ) test_func = functools.partial(exist_map_routes_present_rmap_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC51: exist-map routes present with route-map filter - " assert result is None, msg + failed @@ -694,7 +694,7 @@ def test_bgp_conditional_advertisement_tc_5_2(): ) test_func = functools.partial(exist_map_routes_present_no_rmap_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC52: exist-map routes present, no route-map filter - " assert result is None, msg + failed @@ -724,7 +724,7 @@ def test_bgp_conditional_advertisement_tc_5_3(): ) test_func = functools.partial(non_exist_map_routes_present_rmap_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC53: non-exist-map routes present, with route-map filter - " assert result is None, msg + failed @@ -753,7 +753,7 @@ def test_bgp_conditional_advertisement_tc_5_4(): ) test_func = functools.partial(non_exist_map_routes_present_no_rmap_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC54: non-exist-map routes present, no route-map filter - " assert result is None, msg + failed @@ -791,7 +791,7 @@ def test_bgp_conditional_advertisement_tc_6_1(): ) test_func = functools.partial(exist_map_routes_not_present_rmap_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC61: exist-map routes not present, route-map filter - " assert result is None, msg + failed @@ -820,7 +820,7 @@ def test_bgp_conditional_advertisement_tc_6_2(): ) test_func = functools.partial(exist_map_routes_not_present_no_rmap_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC62: exist-map routes not present, no route-map filter - " assert result is None, msg + failed @@ -850,7 +850,7 @@ def test_bgp_conditional_advertisement_tc_6_3(): ) test_func = functools.partial(non_exist_map_routes_not_present_rmap_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC63: non-exist-map routes not present, route-map filter - " assert result is None, msg + failed @@ -881,7 +881,7 @@ def test_bgp_conditional_advertisement_tc_6_4(): test_func = functools.partial( non_exist_map_routes_not_present_no_rmap_filter, router3 ) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC64: non-exist-map routes not present, no route-map filter - " assert result is None, msg + failed @@ -919,7 +919,7 @@ def test_bgp_conditional_advertisement_tc_7_1(): ) test_func = functools.partial(exist_map_routes_present_rmap2_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC71: exist-map routes present, route-map filter - " assert result is None, msg + failed @@ -948,7 +948,7 @@ def test_bgp_conditional_advertisement_tc_7_2(): ) test_func = functools.partial(exist_map_routes_present_no_rmap2_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC72: exist-map routes present, no route-map filter - " assert result is None, msg + failed @@ -978,7 +978,7 @@ def test_bgp_conditional_advertisement_tc_7_3(): ) test_func = functools.partial(non_exist_map_routes_present_rmap2_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC73: non-exist-map routes present, route-map filter - " assert result is None, msg + failed @@ -1007,7 +1007,7 @@ def test_bgp_conditional_advertisement_tc_7_4(): ) test_func = functools.partial(non_exist_map_routes_present_no_rmap2_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC74: non-exist-map routes present, no route-map filter - " assert result is None, msg + failed @@ -1045,7 +1045,7 @@ def test_bgp_conditional_advertisement_tc_8_1(): ) test_func = functools.partial(exist_map_routes_not_present_rmap2_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC81: exist-map routes not present, route-map filter - " assert result is None, msg + failed @@ -1074,7 +1074,7 @@ def test_bgp_conditional_advertisement_tc_8_2(): ) test_func = functools.partial(exist_map_routes_not_present_no_rmap2_filter, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC82: exist-map routes not present, no route-map filter - " assert result is None, msg + failed @@ -1106,7 +1106,7 @@ def test_bgp_conditional_advertisement_tc_8_3(): test_func = functools.partial( non_exist_map_routes_not_present_rmap2_filter, router3 ) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC83: non-exist-map routes not present, route-map filter - " assert result is None, msg + failed @@ -1137,7 +1137,7 @@ def test_bgp_conditional_advertisement_tc_8_4(): test_func = functools.partial( non_exist_map_routes_not_present_no_rmap2_filter, router3 ) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC84: non-exist-map routes not present, no route-map filter - " assert result is None, msg + failed @@ -1175,7 +1175,7 @@ def test_bgp_conditional_advertisement_tc_9_1(): ) test_func = functools.partial(exist_map_routes_present_rmap2_network, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC91: exist-map routes present, route-map filter and network - " assert result is None, msg + failed @@ -1204,7 +1204,7 @@ def test_bgp_conditional_advertisement_tc_9_2(): ) test_func = functools.partial(exist_map_routes_present_rmap2_no_network, router3) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC92: exist-map routes present, route-map filter and no network - " assert result is None, msg + failed @@ -1244,7 +1244,7 @@ def test_bgp_conditional_advertisement_tc_9_3(): test_func = functools.partial( non_exist_map_routes_not_present_rmap2_network, router3 ) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC93: non-exist-map routes not present, route-map filter and network - " assert result is None, msg + failed @@ -1275,7 +1275,7 @@ def test_bgp_conditional_advertisement_tc_9_4(): test_func = functools.partial( non_exist_map_routes_not_present_rmap2_no_network, router3 ) - success, result = topotest.run_and_expect(test_func, None, count=90, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=90, wait=1) msg = "TC94: non-exist-map routes not present, route-map filter and no network - " assert result is None, msg + failed diff --git a/tests/topotests/bgp_conditional_advertisement_track_peer/test_bgp_conditional_advertisement_track_peer.py b/tests/topotests/bgp_conditional_advertisement_track_peer/test_bgp_conditional_advertisement_track_peer.py index e76307291e4a..bb98e2fad017 100644 --- a/tests/topotests/bgp_conditional_advertisement_track_peer/test_bgp_conditional_advertisement_track_peer.py +++ b/tests/topotests/bgp_conditional_advertisement_track_peer/test_bgp_conditional_advertisement_track_peer.py @@ -51,7 +51,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_confederation_astype/test_bgp_confederation_astype.py b/tests/topotests/bgp_confederation_astype/test_bgp_confederation_astype.py index 7bc005010943..44b1a2f7041f 100644 --- a/tests/topotests/bgp_confederation_astype/test_bgp_confederation_astype.py +++ b/tests/topotests/bgp_confederation_astype/test_bgp_confederation_astype.py @@ -35,7 +35,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py b/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py index 05e07486aeb8..48dddb464895 100644 --- a/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py +++ b/tests/topotests/bgp_default_afi_safi/test_bgp-default-afi-safi.py @@ -48,7 +48,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_default_originate_timer/test_bgp_default_originate_timer.py b/tests/topotests/bgp_default_originate_timer/test_bgp_default_originate_timer.py index b2ba936fb1f6..c7c40c1bfbbd 100644 --- a/tests/topotests/bgp_default_originate_timer/test_bgp_default_originate_timer.py +++ b/tests/topotests/bgp_default_originate_timer/test_bgp_default_originate_timer.py @@ -50,7 +50,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_default_originate_withdraw/test_bgp_default_originate_withdraw.py b/tests/topotests/bgp_default_originate_withdraw/test_bgp_default_originate_withdraw.py index e25f85af8501..cd4acc9aa42f 100644 --- a/tests/topotests/bgp_default_originate_withdraw/test_bgp_default_originate_withdraw.py +++ b/tests/topotests/bgp_default_originate_withdraw/test_bgp_default_originate_withdraw.py @@ -49,7 +49,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_default_route/test_bgp_default-originate.py b/tests/topotests/bgp_default_route/test_bgp_default-originate.py index 333beb067ce1..e805d06a6ac6 100644 --- a/tests/topotests/bgp_default_route/test_bgp_default-originate.py +++ b/tests/topotests/bgp_default_route/test_bgp_default-originate.py @@ -40,7 +40,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -85,19 +85,19 @@ def _bgp_route_is_valid(router, prefix): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_check_if_received) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "No 0.0.0.0/0 at r2 from r1" test_func = functools.partial(_bgp_check_if_originated) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "No 0.0.0.0/0 from r1 to r2" test_func = functools.partial(_bgp_route_is_valid, tgen.gears["r2"], "0.0.0.0/0") - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "Failed to see 0.0.0.0/0 in r2" test_func = functools.partial(_bgp_route_is_valid, tgen.gears["r2"], "0.0.0.0/1") - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "Failed to see 0.0.0.0/1 in r2" diff --git a/tests/topotests/bgp_default_route_route_map_match/test_bgp_default-originate_route-map_match.py b/tests/topotests/bgp_default_route_route_map_match/test_bgp_default-originate_route-map_match.py index 9dcb5a1eef32..d866b95f7b6f 100644 --- a/tests/topotests/bgp_default_route_route_map_match/test_bgp_default-originate_route-map_match.py +++ b/tests/topotests/bgp_default_route_route_map_match/test_bgp_default-originate_route-map_match.py @@ -40,7 +40,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -80,12 +80,12 @@ def _bgp_default_route_is_valid(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, 'Failed to see bgp convergence in "{}"'.format(router) test_func = functools.partial(_bgp_default_route_is_valid, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert ( result is None diff --git a/tests/topotests/bgp_default_route_route_map_match2/test_bgp_default-originate_route-map_match2.py b/tests/topotests/bgp_default_route_route_map_match2/test_bgp_default-originate_route-map_match2.py index 965d348bd703..5a99878b88c6 100644 --- a/tests/topotests/bgp_default_route_route_map_match2/test_bgp_default-originate_route-map_match2.py +++ b/tests/topotests/bgp_default_route_route_map_match2/test_bgp_default-originate_route-map_match2.py @@ -43,7 +43,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -84,7 +84,7 @@ def _bgp_default_route_is_valid(router): step("Converge network") test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "Failed to see bgp convergence at r2" step("Withdraw 10.0.0.0/22 from R2") @@ -94,7 +94,7 @@ def _bgp_default_route_is_valid(router): step("Check if we don't have 0.0.0.0/0 at R2") test_func = functools.partial(_bgp_default_route_is_valid, router) - success, result = topotest.run_and_expect(test_func, not None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, not None, count=30, wait=0.5) assert result is not None, "0.0.0.0/0 exists at r2" step("Announce 10.0.0.0/22 from R2") @@ -102,7 +102,7 @@ def _bgp_default_route_is_valid(router): step("Check if we have 0.0.0.0/0 at R2") test_func = functools.partial(_bgp_default_route_is_valid, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "0.0.0.0/0 does not exist at r2" step("Withdraw 10.0.0.0/22 from R2 again") @@ -112,7 +112,7 @@ def _bgp_default_route_is_valid(router): step("Check if we don't have 0.0.0.0/0 at R2 again") test_func = functools.partial(_bgp_default_route_is_valid, router) - success, result = topotest.run_and_expect(test_func, not None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, not None, count=30, wait=0.5) assert result is not None, "0.0.0.0/0 exists at r2" diff --git a/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py b/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py index f94620b2c977..3a374c6e9aed 100644 --- a/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py +++ b/tests/topotests/bgp_default_route_route_map_match_set/test_bgp_default-originate_route-map_match_set.py @@ -42,7 +42,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -90,12 +90,12 @@ def _bgp_default_route_has_metric(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, 'Failed to see bgp convergence in "{}"'.format(router) test_func = functools.partial(_bgp_default_route_has_metric, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert ( result is None diff --git a/tests/topotests/bgp_default_route_route_map_set/test_bgp_default-originate_route-map_set.py b/tests/topotests/bgp_default_route_route_map_set/test_bgp_default-originate_route-map_set.py index e633b61d1b03..ba278295a6da 100644 --- a/tests/topotests/bgp_default_route_route_map_set/test_bgp_default-originate_route-map_set.py +++ b/tests/topotests/bgp_default_route_route_map_set/test_bgp_default-originate_route-map_set.py @@ -41,7 +41,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_disable_addpath_rx/test_disable_addpath_rx.py b/tests/topotests/bgp_disable_addpath_rx/test_disable_addpath_rx.py index 70562ce31f3b..6978008740ee 100644 --- a/tests/topotests/bgp_disable_addpath_rx/test_disable_addpath_rx.py +++ b/tests/topotests/bgp_disable_addpath_rx/test_disable_addpath_rx.py @@ -46,7 +46,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -98,7 +98,7 @@ def check_bgp_advertised_routes(router): return topotest.json_cmp(output, expected) test_func = functools.partial(check_bgp_advertised_routes, r2) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "AddPath TX not working." step("Check if AddPath RX is disabled on r1 and we receive only 2 paths.") @@ -120,7 +120,7 @@ def check_bgp_disabled_addpath_rx(router): return topotest.json_cmp(output, expected) test_func = functools.partial(check_bgp_disabled_addpath_rx, r1) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "AddPath RX advertised, but should not." diff --git a/tests/topotests/bgp_distance_change/test_bgp_distance_change.py b/tests/topotests/bgp_distance_change/test_bgp_distance_change.py index 2ca50aa56ead..87802511b5e6 100644 --- a/tests/topotests/bgp_distance_change/test_bgp_distance_change.py +++ b/tests/topotests/bgp_distance_change/test_bgp_distance_change.py @@ -51,7 +51,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -101,14 +101,14 @@ def _bgp_check_distance_change(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see BGP convergence in "{}"'.format(router) _bgp_distance_change(router) test_func = functools.partial(_bgp_check_distance_change, router) - success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see applied BGP distance in RIB "{}"'.format( router diff --git a/tests/topotests/bgp_dont_capability_negotiate/test_bgp_dont_capability_negotiate.py b/tests/topotests/bgp_dont_capability_negotiate/test_bgp_dont_capability_negotiate.py index 826932221539..28d6b56303b2 100644 --- a/tests/topotests/bgp_dont_capability_negotiate/test_bgp_dont_capability_negotiate.py +++ b/tests/topotests/bgp_dont_capability_negotiate/test_bgp_dont_capability_negotiate.py @@ -34,7 +34,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_ebgp_common_subnet_nexthop_unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py b/tests/topotests/bgp_ebgp_common_subnet_nexthop_unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py index d9ccd6979cf0..a4ac249cb747 100644 --- a/tests/topotests/bgp_ebgp_common_subnet_nexthop_unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py +++ b/tests/topotests/bgp_ebgp_common_subnet_nexthop_unchanged/test_bgp-ebgp-common-subnet-nexthop-unchanged.py @@ -52,7 +52,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -90,7 +90,7 @@ def _bgp_converge(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, r3) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Failed bgp convergence in "{}"'.format(r3) @@ -100,7 +100,7 @@ def _bgp_nh_unchanged(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_nh_unchanged, r2) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Wrong next-hop in "{}"'.format(r2) 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 6e3b2859c431..f7c0f70445de 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 @@ -71,7 +71,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -125,31 +125,31 @@ def _bgp_advertised_routes(router): # Scenario 1. logger.info("Scenario 1: r2 receives 192.168.255.1/32 from r1") test_func = functools.partial(_bgp_converge, "r2") - success, result = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assert success is True, "Failed bgp convergence (r2)" test_func = functools.partial(_bgp_has_routes, "r2") - success, result = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assert success is True, "r2 does not receive 192.168.255.1/32" # Scenario 2. logger.info("Scenario 2: r3 must not send 192.168.255.1/32 to r4") test_func = functools.partial(_bgp_converge, "r4") - success, result = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assert success is True, "Failed bgp convergence (r4)" test_func = functools.partial(_bgp_advertised_routes, "r3") - success, result = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assert success is True, "r3 announced 192.168.255.1/32 to r4" # Scenario 3. logger.info("Scenario 3: r6 receives 192.168.255.1/32 from r5 (iBGP)") test_func = functools.partial(_bgp_converge, "r6") - success, result = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assert success is True, "Failed bgp convergence (r6)" test_func = functools.partial(_bgp_has_routes, "r6") - success, result = topotest.run_and_expect(test_func, None, count=120, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assert success is True, "r6 does not receive 192.168.255.1/32" diff --git a/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py b/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py index a5e5bdcee904..5f6eb1726103 100644 --- a/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py +++ b/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py @@ -47,7 +47,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py b/tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py index a5db20e47490..c67bc91f631e 100644 --- a/tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py +++ b/tests/topotests/bgp_extended_optional_parameters_length/test_bgp_extended_optional_parameters_length.py @@ -34,7 +34,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py index 2ffcb723ec42..16459a25a33d 100644 --- a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py +++ b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py @@ -50,7 +50,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_gshut/test_bgp_gshut.py b/tests/topotests/bgp_gshut/test_bgp_gshut.py index 61a0fe63c180..cfe63d20bafd 100644 --- a/tests/topotests/bgp_gshut/test_bgp_gshut.py +++ b/tests/topotests/bgp_gshut/test_bgp_gshut.py @@ -108,7 +108,7 @@ def setup_module(mod): r2.run("ip link set r2-eth3 master vrf1") # Load FRR config and initialize all routers - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_ipv4_class_e_peer/test_bgp_ipv4_class_e_peer.py b/tests/topotests/bgp_ipv4_class_e_peer/test_bgp_ipv4_class_e_peer.py index c7cb213de5d7..66eeeb468daa 100644 --- a/tests/topotests/bgp_ipv4_class_e_peer/test_bgp_ipv4_class_e_peer.py +++ b/tests/topotests/bgp_ipv4_class_e_peer/test_bgp_ipv4_class_e_peer.py @@ -45,7 +45,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_ipv6_ll_peering/test_bgp_ipv6_ll_peering.py b/tests/topotests/bgp_ipv6_ll_peering/test_bgp_ipv6_ll_peering.py index ea974b5302fe..aaa68ea340aa 100644 --- a/tests/topotests/bgp_ipv6_ll_peering/test_bgp_ipv6_ll_peering.py +++ b/tests/topotests/bgp_ipv6_ll_peering/test_bgp_ipv6_ll_peering.py @@ -41,7 +41,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py b/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py index 7c23a3e8990e..84a9c8b72353 100644 --- a/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py +++ b/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py @@ -56,7 +56,7 @@ def setup_module(mod): ) tgen.gears["r{}".format(rtr)].run("sysctl -w net.mpls.conf.vrf1.input=1") - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_labeled_unicast_addpath/test_bgp_labeled_unicast_addpath.py b/tests/topotests/bgp_labeled_unicast_addpath/test_bgp_labeled_unicast_addpath.py index f4bb487e4091..25fd0dbb71a4 100644 --- a/tests/topotests/bgp_labeled_unicast_addpath/test_bgp_labeled_unicast_addpath.py +++ b/tests/topotests/bgp_labeled_unicast_addpath/test_bgp_labeled_unicast_addpath.py @@ -57,7 +57,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py index 34c23d9b6fe7..d1d384182c0f 100644 --- a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py +++ b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py @@ -42,7 +42,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_large_comm_list_match/test_bgp_large_comm_list_match.py b/tests/topotests/bgp_large_comm_list_match/test_bgp_large_comm_list_match.py index 7023e3a503e8..49681c6a690a 100644 --- a/tests/topotests/bgp_large_comm_list_match/test_bgp_large_comm_list_match.py +++ b/tests/topotests/bgp_large_comm_list_match/test_bgp_large_comm_list_match.py @@ -61,7 +61,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_llgr/test_bgp_llgr.py b/tests/topotests/bgp_llgr/test_bgp_llgr.py index d7897cfcb9ed..2a3753e26cbf 100644 --- a/tests/topotests/bgp_llgr/test_bgp_llgr.py +++ b/tests/topotests/bgp_llgr/test_bgp_llgr.py @@ -65,7 +65,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_local_as/test_bgp_local_as.py b/tests/topotests/bgp_local_as/test_bgp_local_as.py index 9e5f146b47cb..e61bb0d1558f 100644 --- a/tests/topotests/bgp_local_as/test_bgp_local_as.py +++ b/tests/topotests/bgp_local_as/test_bgp_local_as.py @@ -46,7 +46,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_local_as_dotplus_private_remove/test_bgp_local_as_dotplus_private_remove.py b/tests/topotests/bgp_local_as_dotplus_private_remove/test_bgp_local_as_dotplus_private_remove.py index 930fd791b0a5..c58322a4c0ab 100644 --- a/tests/topotests/bgp_local_as_dotplus_private_remove/test_bgp_local_as_dotplus_private_remove.py +++ b/tests/topotests/bgp_local_as_dotplus_private_remove/test_bgp_local_as_dotplus_private_remove.py @@ -63,7 +63,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_local_as_private_remove/test_bgp_local_as_private_remove.py b/tests/topotests/bgp_local_as_private_remove/test_bgp_local_as_private_remove.py index 9d22a799a6b5..23eb80f31676 100644 --- a/tests/topotests/bgp_local_as_private_remove/test_bgp_local_as_private_remove.py +++ b/tests/topotests/bgp_local_as_private_remove/test_bgp_local_as_private_remove.py @@ -50,7 +50,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py b/tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py index 0656e1ed41e4..18ffc6a17d9f 100644 --- a/tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py +++ b/tests/topotests/bgp_lu_explicitnull/test_bgp_lu_explicitnull.py @@ -142,7 +142,7 @@ def test_converge_bgplu(): "192.168.2.2/32", "0", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, prefix 192.168.2.2/32 from r2 not present" # Check r2 gets prefix 192.168.2.1/32 @@ -153,7 +153,7 @@ def test_converge_bgplu(): "192.168.2.1/32", "0", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, prefix 192.168.2.1/32 from r1 not present" @@ -178,7 +178,7 @@ def _check_ping(name, dest_addr, src_addr): tgen = get_topogen() func = functools.partial(_check_ping, "r1", "192.168.2.2", "192.168.2.1") # tgen.mininet_cli() - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "r1, ping to 192.168.2.2 from 192.168.2.1 fails" diff --git a/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py b/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py index a9810ba264b3..545d7bd245a9 100644 --- a/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py +++ b/tests/topotests/bgp_max_med_on_startup/test_bgp_max_med_on_startup.py @@ -43,7 +43,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -82,17 +82,17 @@ def _bgp_has_routes(router, metric): # Check session is established test_func = functools.partial(_bgp_converge, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "Failed bgp convergence on r2" # Check metric has value of max-med test_func = functools.partial(_bgp_has_routes, router2, 777) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "r2 does not receive routes with metric 777" # Check that when the max-med timer expires, metric is updated test_func = functools.partial(_bgp_has_routes, router2, 0) - success, result = topotest.run_and_expect(test_func, None, count=16, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=16, wait=0.5) assert result is None, "r2 does not receive routes with metric 0" diff --git a/tests/topotests/bgp_maximum_prefix_invalid_update/test_bgp_maximum_prefix_invalid_update.py b/tests/topotests/bgp_maximum_prefix_invalid_update/test_bgp_maximum_prefix_invalid_update.py index c6bdbc3c1cce..5edc0b55ffc1 100644 --- a/tests/topotests/bgp_maximum_prefix_invalid_update/test_bgp_maximum_prefix_invalid_update.py +++ b/tests/topotests/bgp_maximum_prefix_invalid_update/test_bgp_maximum_prefix_invalid_update.py @@ -50,7 +50,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_maximum_prefix_out/test_bgp_maximum_prefix_out.py b/tests/topotests/bgp_maximum_prefix_out/test_bgp_maximum_prefix_out.py index 0b346f63d51e..aad5f36480e8 100644 --- a/tests/topotests/bgp_maximum_prefix_out/test_bgp_maximum_prefix_out.py +++ b/tests/topotests/bgp_maximum_prefix_out/test_bgp_maximum_prefix_out.py @@ -45,7 +45,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -177,7 +177,7 @@ def _bgp_converge(router, nb_prefixes): router1.vtysh_cmd(cmd) test_func = functools.partial(_bgp_converge, router2, exp_prfxs) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, 'Failed bgp convergence in "{}"'.format(router2) diff --git a/tests/topotests/bgp_minimum_holdtime/test_bgp_minimum_holdtime.py b/tests/topotests/bgp_minimum_holdtime/test_bgp_minimum_holdtime.py index 9f4d9682778a..c9ff2ffc7e7c 100755 --- a/tests/topotests/bgp_minimum_holdtime/test_bgp_minimum_holdtime.py +++ b/tests/topotests/bgp_minimum_holdtime/test_bgp_minimum_holdtime.py @@ -40,7 +40,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -76,7 +76,7 @@ def _bgp_neighbor_check_if_notification_sent(): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_neighbor_check_if_notification_sent) - success, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) assert result is None, "Failed to send notification message\n" diff --git a/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py b/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py index 23e820b4fc39..b53673ad0f2f 100644 --- a/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py +++ b/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py @@ -46,7 +46,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) tgen.start_router() diff --git a/tests/topotests/bgp_orf/test_bgp_orf.py b/tests/topotests/bgp_orf/test_bgp_orf.py index 47c055688477..bc6a85b4b9d3 100644 --- a/tests/topotests/bgp_orf/test_bgp_orf.py +++ b/tests/topotests/bgp_orf/test_bgp_orf.py @@ -37,7 +37,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_path_selection/test_bgp_path_selection.py b/tests/topotests/bgp_path_selection/test_bgp_path_selection.py index 30083b4de274..d486a87e9c89 100644 --- a/tests/topotests/bgp_path_selection/test_bgp_path_selection.py +++ b/tests/topotests/bgp_path_selection/test_bgp_path_selection.py @@ -57,7 +57,7 @@ def setup_module(mod): tgen.gears["r2"].cmd("ip address add dev vrf1 192.0.2.8/32") tgen.gears["r3"].cmd("ip address add dev vrf1 192.0.2.8/32") - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_peer_graceful_shutdown/test_bgp_peer_graceful_shutdown.py b/tests/topotests/bgp_peer_graceful_shutdown/test_bgp_peer_graceful_shutdown.py index 926982623396..c6ee9aa73c4c 100644 --- a/tests/topotests/bgp_peer_graceful_shutdown/test_bgp_peer_graceful_shutdown.py +++ b/tests/topotests/bgp_peer_graceful_shutdown/test_bgp_peer_graceful_shutdown.py @@ -34,7 +34,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_peer_group/test_bgp_peer-group.py b/tests/topotests/bgp_peer_group/test_bgp_peer-group.py index 5cbcd19be92d..7d476b053852 100644 --- a/tests/topotests/bgp_peer_group/test_bgp_peer-group.py +++ b/tests/topotests/bgp_peer_group/test_bgp_peer-group.py @@ -47,7 +47,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_prefix_list_any/test_bgp_prefix_list_any.py b/tests/topotests/bgp_prefix_list_any/test_bgp_prefix_list_any.py index 5d6440ce6add..1871d3efc8ce 100644 --- a/tests/topotests/bgp_prefix_list_any/test_bgp_prefix_list_any.py +++ b/tests/topotests/bgp_prefix_list_any/test_bgp_prefix_list_any.py @@ -33,7 +33,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_prefix_sid/test_bgp_prefix_sid.py b/tests/topotests/bgp_prefix_sid/test_bgp_prefix_sid.py index 1e6e731a1872..fca60e8ceab1 100644 --- a/tests/topotests/bgp_prefix_sid/test_bgp_prefix_sid.py +++ b/tests/topotests/bgp_prefix_sid/test_bgp_prefix_sid.py @@ -93,11 +93,11 @@ def _check_type1_r1(router, prefix, remoteLabel, labelIndex): return topotest.json_cmp(output, expected) test_func = functools.partial(_check_type1_r1, router, "3.0.0.1/32", 800001, 1) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result is None, 'Failed _check_type1_r1 in "{}"'.format(router) test_func = functools.partial(_check_type1_r1, router, "3.0.0.2/32", 800002, 2) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result is None, 'Failed _check_type1_r1 in "{}"'.format(router) @@ -160,11 +160,11 @@ def _check_type1_peer2(prefix, label): return topotest.json_cmp(output, expected) test_func = functools.partial(_check_type1_peer2, "3.0.0.1/32", label=8001) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result is None, 'Failed _check_type1_peer2 in "{}"'.format("peer2") test_func = functools.partial(_check_type1_peer2, "3.0.0.2/32", label=8002) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert result is None, 'Failed _check_type1_peer2 in "{}"'.format("peer2") diff --git a/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py b/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py index 97366ebd5338..b9d8ce681914 100644 --- a/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py +++ b/tests/topotests/bgp_reject_as_sets/test_bgp_reject_as_sets.py @@ -56,7 +56,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -114,19 +114,19 @@ def _bgp_announce_route_without_as_sets(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Failed bgp convergence in "{}"'.format(router) test_func = functools.partial( _bgp_has_aggregated_route_with_stripped_as_set, router ) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Failed to see an aggregated route in "{}"'.format(router) test_func = functools.partial(_bgp_announce_route_without_as_sets, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert ( result is None diff --git a/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py b/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py index e48f81c53dd8..2d8864c34ae1 100644 --- a/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py +++ b/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py @@ -109,7 +109,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, f"{rname}/zebra.conf") ) diff --git a/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py b/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py index d9402f2743a3..e3e4567aeb03 100644 --- a/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py +++ b/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py @@ -41,7 +41,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) tgen.start_router() diff --git a/tests/topotests/bgp_rmap_extcommunity_none/test_bgp_rmap_extcommunity_none.py b/tests/topotests/bgp_rmap_extcommunity_none/test_bgp_rmap_extcommunity_none.py index ef7c94bbab0f..2e5592e2ab92 100644 --- a/tests/topotests/bgp_rmap_extcommunity_none/test_bgp_rmap_extcommunity_none.py +++ b/tests/topotests/bgp_rmap_extcommunity_none/test_bgp_rmap_extcommunity_none.py @@ -43,7 +43,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -86,7 +86,7 @@ def _bgp_converge(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "BGP Converge failed" def _bgp_extcommunity_strip(router): @@ -111,7 +111,7 @@ def _bgp_extcommunity_strip(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_extcommunity_strip, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to strip incoming extended communities from r2" diff --git a/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py b/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py index 52fda695c3cd..29ff1065fd69 100644 --- a/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py +++ b/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py @@ -82,7 +82,7 @@ def test_correct_pair(tgen): check_r2_established = functools.partial( check_session_established, router, neighbor_ip ) - success, result = topotest.run_and_expect( + success, _ = topotest.run_and_expect( check_r2_established, True, count=20, wait=3 ) assert success, "Session with r2 is not Established" @@ -100,7 +100,7 @@ def test_role_pair_mismatch(tgen): router = tgen.gears["r3"] neighbor_ip = "192.168.3.1" check_r3_mismatch = functools.partial(check_role_mismatch, router, neighbor_ip) - success, result = topotest.run_and_expect(check_r3_mismatch, True, count=20, wait=3) + success, _ = topotest.run_and_expect(check_r3_mismatch, True, count=20, wait=3) assert success, "Session between r1 and r3 was not correctly closed" @@ -111,7 +111,7 @@ def test_single_role_advertising(tgen): check_r4_established = functools.partial( check_session_established, router, neighbor_ip ) - success, result = topotest.run_and_expect( + success, _ = topotest.run_and_expect( check_r4_established, True, count=20, wait=3 ) assert success, "Session with r4 is not Established" @@ -129,7 +129,7 @@ def test_single_role_receiving(tgen): check_r1_established = functools.partial( check_session_established, router, neighbor_ip ) - success, result = topotest.run_and_expect( + success, _ = topotest.run_and_expect( check_r1_established, True, count=20, wait=3 ) assert success, "Session with r1 is not Established" @@ -145,7 +145,7 @@ def test_role_strict_mode(tgen): router = tgen.gears["r5"] neighbor_ip = "192.168.5.1" check_r5_mismatch = functools.partial(check_role_mismatch, router, neighbor_ip) - success, result = topotest.run_and_expect(check_r5_mismatch, True, count=20, wait=3) + success, _ = topotest.run_and_expect(check_r5_mismatch, True, count=20, wait=3) assert success, "Session between r1 and r5 was not correctly closed" diff --git a/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py b/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py index b3715863b583..a43518bc8a7d 100644 --- a/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py +++ b/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py @@ -69,7 +69,7 @@ def _routes_half_converged(): ] return output == expected - success, result = topotest.run_and_expect( + success, _ = topotest.run_and_expect( _routes_half_converged, True, count=20, wait=3 ) assert success, "Routes did not converged" diff --git a/tests/topotests/bgp_route_map_delay_timer/test_bgp_route_map_delay_timer.py b/tests/topotests/bgp_route_map_delay_timer/test_bgp_route_map_delay_timer.py index f7a66fdad1bf..d791ef486bf0 100644 --- a/tests/topotests/bgp_route_map_delay_timer/test_bgp_route_map_delay_timer.py +++ b/tests/topotests/bgp_route_map_delay_timer/test_bgp_route_map_delay_timer.py @@ -32,7 +32,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_route_map_match_ipv6_nexthop/test_bgp_route_map_match_ipv6_nexthop.py b/tests/topotests/bgp_route_map_match_ipv6_nexthop/test_bgp_route_map_match_ipv6_nexthop.py index 93a514bf6a5c..35ce0926975e 100644 --- a/tests/topotests/bgp_route_map_match_ipv6_nexthop/test_bgp_route_map_match_ipv6_nexthop.py +++ b/tests/topotests/bgp_route_map_match_ipv6_nexthop/test_bgp_route_map_match_ipv6_nexthop.py @@ -41,7 +41,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -97,7 +97,7 @@ def _bgp_converge(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Can't match routes using ipv6 next-hop access-list" diff --git a/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py b/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py index 2828796405cd..c766f5c1a815 100644 --- a/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py +++ b/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py @@ -46,7 +46,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) tgen.start_router() diff --git a/tests/topotests/bgp_route_map_on_match_next/test_bgp_route_map_on_match_next.py b/tests/topotests/bgp_route_map_on_match_next/test_bgp_route_map_on_match_next.py index 8fe45a349838..5b5256f43d92 100644 --- a/tests/topotests/bgp_route_map_on_match_next/test_bgp_route_map_on_match_next.py +++ b/tests/topotests/bgp_route_map_on_match_next/test_bgp_route_map_on_match_next.py @@ -42,7 +42,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -83,12 +83,12 @@ def _bgp_has_routes(router, metric, weight): # Check thst session is established test_func = functools.partial(_bgp_converge, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "Failed bgp convergence on r2" # Check that metric is 0 and weight is 100 for the received prefix test_func = functools.partial(_bgp_has_routes, router2, 0, 100) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "r2 does not receive routes with metric 0 and weight 100" # Update the route-map and add "on-match next" to entry 10 @@ -102,7 +102,7 @@ def _bgp_has_routes(router, metric, weight): # Check that metric is 20 and weight is 100 for the received prefix test_func = functools.partial(_bgp_has_routes, router2, 20, 100) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) assert result is None, "r2 does not receive routes with metric 20 and weight 100" diff --git a/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py b/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py index 37082b484c71..5ce8b17f249a 100644 --- a/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py +++ b/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py @@ -61,7 +61,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py b/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py index 18b7831a4af6..29d9842d59dd 100644 --- a/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py +++ b/tests/topotests/bgp_route_server_client/test_bgp_route_server_client.py @@ -44,7 +44,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py index f52b28a0620c..7b40bbdae82d 100644 --- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py +++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py @@ -44,7 +44,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py b/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py index db6dbc61d220..6983a35173cb 100644 --- a/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py +++ b/tests/topotests/bgp_sender_as_path_loop_detection/test_bgp_sender-as-path-loop-detection.py @@ -50,7 +50,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py b/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py index d373a749fe87..64cc48e54ff8 100644 --- a/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py +++ b/tests/topotests/bgp_set_aspath_exclude/test_bgp_set_aspath_exclude.py @@ -46,7 +46,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_set_aspath_replace/test_bgp_set_aspath_replace.py b/tests/topotests/bgp_set_aspath_replace/test_bgp_set_aspath_replace.py index c0e19fa35690..fe4eda60f5c0 100644 --- a/tests/topotests/bgp_set_aspath_replace/test_bgp_set_aspath_replace.py +++ b/tests/topotests/bgp_set_aspath_replace/test_bgp_set_aspath_replace.py @@ -48,7 +48,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_set_local_preference_add_subtract/test_bgp_set_local-preference_add_subtract.py b/tests/topotests/bgp_set_local_preference_add_subtract/test_bgp_set_local-preference_add_subtract.py index 292cf70d3617..e201ec9ff74d 100644 --- a/tests/topotests/bgp_set_local_preference_add_subtract/test_bgp_set_local-preference_add_subtract.py +++ b/tests/topotests/bgp_set_local_preference_add_subtract/test_bgp_set_local-preference_add_subtract.py @@ -47,7 +47,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -100,12 +100,12 @@ def _bgp_check_local_preference(router): return topotest.json_cmp(output, expected) test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see BGP convergence in "{}"'.format(router) test_func = functools.partial(_bgp_check_local_preference, router) - success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see applied BGP local-preference in "{}"'.format( router diff --git a/tests/topotests/bgp_software_version/test_bgp_software_version.py b/tests/topotests/bgp_software_version/test_bgp_software_version.py index c867208d3945..9aff53a03082 100644 --- a/tests/topotests/bgp_software_version/test_bgp_software_version.py +++ b/tests/topotests/bgp_software_version/test_bgp_software_version.py @@ -34,7 +34,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_soo/test_bgp_soo.py b/tests/topotests/bgp_soo/test_bgp_soo.py index 967bed021358..b0c70f208ebb 100644 --- a/tests/topotests/bgp_soo/test_bgp_soo.py +++ b/tests/topotests/bgp_soo/test_bgp_soo.py @@ -73,7 +73,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py b/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py index 984cf97e288b..787707cc0f62 100755 --- a/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py +++ b/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py @@ -106,7 +106,7 @@ def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) tgen.start_topology() router_list = tgen.routers() - for i, (rname, router) in enumerate(tgen.routers().items(), 1): + for _, (rname, router) in enumerate(tgen.routers().items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -180,7 +180,7 @@ def _check(name, cmd, expected_file): logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) tgen = get_topogen() func = functools.partial(_check, name, cmd, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py index 4afaeaf78a4e..5d18083fd5e3 100755 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py @@ -147,7 +147,7 @@ def _check(name, cmd, expected_file): logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) tgen = get_topogen() func = functools.partial(_check, name, cmd, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py index 914c29f0c1dd..38baf434426d 100755 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py @@ -109,7 +109,7 @@ def _check(name, dest_addr, match): logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) tgen = get_topogen() func = functools.partial(_check, name, cmd, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py index 8a7b558be360..92a30788fc4b 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py @@ -106,7 +106,7 @@ def _check(name, dest_addr, match): logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) tgen = get_topogen() func = functools.partial(_check, name, cmd, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" diff --git a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py index ec14ef065f83..fa8a88297f3f 100644 --- a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py +++ b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py @@ -47,7 +47,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py b/tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py index 4855d5c7d21a..37949cdc9967 100644 --- a/tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py +++ b/tests/topotests/bgp_tcp_mss/test_bgp_tcp_mss.py @@ -52,7 +52,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -108,7 +108,7 @@ def _bgp_check_neighbor_tcp_mss(router, neigh): logger.info("Check if neighbor sessions are up in {}".format(router1.name)) test_func = functools.partial(_bgp_converge, router1) - success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see BGP convergence in "{}"'.format(router1.name) logger.info("BGP neighbor session is up in {}".format(router1.name)) @@ -129,7 +129,7 @@ def _bgp_check_neighbor_tcp_mss(router, neigh): "Check if neighbor session is up after reset in {}".format(router1.name) ) test_func = functools.partial(_bgp_converge, router1) - success, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=0.5) assert result is None, 'Failed to see BGP convergence after reset in "{}"'.format( router1.name ) @@ -138,7 +138,7 @@ def _bgp_check_neighbor_tcp_mss(router, neigh): "Verify if TCP MSS value is synced with neighbor in {}".format(router1.name) ) test_func = functools.partial(_bgp_check_neighbor_tcp_mss, router1, "192.168.255.2") - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( result is None ), 'Failed to sync TCP MSS value over BGP session in "{}"'.format(router1.name) @@ -148,7 +148,7 @@ def _bgp_check_neighbor_tcp_mss(router, neigh): "Verify if TCP MSS value is synced with neighbor in {}".format(router2.name) ) test_func = functools.partial(_bgp_check_neighbor_tcp_mss, router2, "192.168.255.1") - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( result is None ), 'Failed to sync TCP MSS value over BGP session in "{}"'.format(router2.name) diff --git a/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py b/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py index cd405f7b2289..a2eacc7ab272 100644 --- a/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py +++ b/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py @@ -41,7 +41,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) tgen.start_router() diff --git a/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py b/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py index 2a53547f59bd..4d4e29b2f875 100644 --- a/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py +++ b/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py @@ -42,7 +42,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -84,7 +84,7 @@ def _bgp_converge(): step("Ensure Convergence of BGP") test_func = functools.partial(_bgp_converge) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) assert result is None, 'Failed bgp convergence in "{}"'.format(tgen.gears["r2"]) @@ -109,7 +109,7 @@ def _bgp_converge(): step("Ensure that BGP does not crash") test_func = functools.partial(_bgp_nexthop_cache) - success, result = topotest.run_and_expect(test_func, True, count=10, wait=1) + _, result = topotest.run_and_expect(test_func, True, count=10, wait=1) assert result is True, "BGP did not crash on r1" diff --git a/tests/topotests/bgp_update_delay/test_bgp_update_delay.py b/tests/topotests/bgp_update_delay/test_bgp_update_delay.py index 4e66cf5548ab..59f4bcd38510 100644 --- a/tests/topotests/bgp_update_delay/test_bgp_update_delay.py +++ b/tests/topotests/bgp_update_delay/test_bgp_update_delay.py @@ -90,7 +90,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -169,7 +169,7 @@ def _bgp_check_vrf_update_delay_and_wait(router): # Check r2 initial convergence in default table test_func = functools.partial(_bgp_converge, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, 'Failed bgp convergence in "{}"'.format(router2) @@ -195,7 +195,7 @@ def _bgp_check_vrf_update_delay_and_wait(router): router2.vtysh_cmd("""clear ip bgp *""") test_func = functools.partial(_bgp_check_update_delay_in_progress, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, 'Failed to set update-delay max-delay timer "{}"'.format( router2 @@ -203,7 +203,7 @@ def _bgp_check_vrf_update_delay_and_wait(router): # Check that r2 only installs route learned from r4 after the max-delay timer expires test_func = functools.partial(_bgp_check_route_install, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, 'Failed to install route after update-delay "{}"'.format( router2 @@ -219,7 +219,7 @@ def _bgp_check_vrf_update_delay_and_wait(router): ) test_func = functools.partial(_bgp_check_update_delay_and_wait, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert ( result is None @@ -229,7 +229,7 @@ def _bgp_check_vrf_update_delay_and_wait(router): router2.vtysh_cmd("""clear ip bgp *""") test_func = functools.partial(_bgp_check_route_install, router3) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert ( result is None @@ -250,7 +250,7 @@ def _bgp_check_vrf_update_delay_and_wait(router): router2.vtysh_cmd("""clear ip bgp *""") test_func = functools.partial(_bgp_check_route_install, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, 'Failed to remove update-delay delay timing "{}"'.format( router2 @@ -266,14 +266,14 @@ def _bgp_check_vrf_update_delay_and_wait(router): # Check that r2 default instance and vrf1 have the max-delay and establish set test_func = functools.partial(_bgp_check_update_delay_and_wait, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, 'Failed to set update-delay in default instance "{}"'.format( router2 ) test_func = functools.partial(_bgp_check_vrf_update_delay_and_wait, router2) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, 'Failed to set update-delay in vrf1 "{}"'.format(router2) @@ -281,7 +281,7 @@ def _bgp_check_vrf_update_delay_and_wait(router): router2.vtysh_cmd("""clear ip bgp *""") test_func = functools.partial(_bgp_check_route_install, router3) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert ( result is None diff --git a/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py b/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py index eb29875d5036..695cfc3d25d6 100644 --- a/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py +++ b/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py @@ -67,7 +67,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) diff --git a/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py index 39865eb189bb..8e2e4017df8d 100644 --- a/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py +++ b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py @@ -203,7 +203,7 @@ def _check(router, prefix, rd, label, nexthop): ) func = functools.partial(_check, router, prefix, rd, label, nexthop) - success, result = topotest.run_and_expect(func, None, count=20, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=20, wait=0.5) assert_msg = "{}, show bgp ipv4 vpn {}, rd {}, label {} nexthop {}".format( router.name, prefix, rd, label, nexthop ) @@ -324,7 +324,7 @@ def _check_nexthop_available(router, prefix): for prefix, rname_to_test in vpnv4_entries.items(): func = functools.partial(_check_nexthop_available, router, prefix) - success, result = topotest.run_and_expect(func, None, count=20, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=20, wait=0.5) assert result is None, "Failed to detect prefix {} on router {}".format( prefix, router.name ) @@ -456,7 +456,7 @@ def test_r3_prefixes_removed(): prefix, "444:3", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still present".format(router.name, prefix) # diagnostic @@ -491,7 +491,7 @@ def test_r3_prefixes_removed(): prefix, "444:3", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still present".format(router.name, prefix) logger.info( @@ -502,7 +502,7 @@ def test_r3_prefixes_removed(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, label_ip_entries[prefix] ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with in_label {} still present".format( label_ip_entries[prefix] ) @@ -536,7 +536,7 @@ def test_r3_prefixes_added_back(): prefix, "444:3", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} not present".format(router.name, prefix) logger.info( @@ -564,7 +564,7 @@ def test_r3_prefixes_added_back(): prefix, "444:3", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} not present".format(router.name, prefix) # diagnostic @@ -611,7 +611,7 @@ def test_unconfigure_nexthop_change_nexthop_self(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, label ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry for {} with in_label {} still present".format( prefix, label ) @@ -626,7 +626,7 @@ def test_unconfigure_nexthop_change_nexthop_self(): "444:3", label=label, ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, mpls vpn update {} label {} is present".format( router.name, prefix, label ) @@ -639,7 +639,7 @@ def test_unconfigure_nexthop_change_nexthop_self(): "444:3", nexthop="192.168.1.3", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, mpls vpn update {} label {} is present".format( router.name, prefix, label ) @@ -727,7 +727,7 @@ def test_declare_vpn_network_with_different_label(): label=label, nexthop="192.168.1.3", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {}, label {} not present".format( router.name, prefix, label ) @@ -787,7 +787,7 @@ def test_filter_vpn_network_from_r1(): "172.31.0.0/24", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {}, is still present".format( router.name, prefix ) @@ -804,7 +804,7 @@ def test_filter_vpn_network_from_r1(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, int(label) ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry for {} with in_label {} still present".format( prefix, label ) @@ -833,7 +833,7 @@ def test_unfilter_vpn_network_from_r1(): test_func = functools.partial( check_show_bgp_vpn_prefix_found, router, "ipv4", prefix, "444:1" ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {}, is not present".format(router.name, prefix) vpnv4_checks = { diff --git a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py index 189824311dfe..dd9d54742b71 100644 --- a/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py +++ b/tests/topotests/bgp_vpnv4_ebgp/test_bgp_vpnv4_ebgp.py @@ -245,7 +245,7 @@ def test_export_route_target_empty(): prefix, "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still present".format(router.name, prefix) @@ -279,7 +279,7 @@ def test_export_route_target_with_routemap_with_export_route_target(): prefix, "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still not present".format(router.name, prefix) @@ -309,7 +309,7 @@ def test_export_route_target_with_routemap_without_export_route_target(): prefix, "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still present".format(router.name, prefix) @@ -339,7 +339,7 @@ def test_export_route_target_with_default_command(): prefix, "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still not present".format(router.name, prefix) @@ -371,7 +371,7 @@ def test_export_suppress_route_target_with_route_map_command(): prefix, "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still present".format(router.name, prefix) @@ -400,7 +400,7 @@ def test_export_add_route_target_to_route_map_command(): prefix, "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, vpnv4 update {} still not present".format(router.name, prefix) @@ -482,7 +482,7 @@ def test_adj_rib_in_label_change(): expected, exact=True, ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, vpnv4 update 172.31.0.1 still present" diff --git a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py index d4c355a44a1d..b0178805456b 100644 --- a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py @@ -174,7 +174,7 @@ def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=N stored_label_inited = False for prefix in group: test_func = functools.partial(check_bgp_vpnv4_prefix_presence, router, prefix) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, prefix ipv4 vpn {} is not installed yet".format( router.name, prefix ) @@ -305,7 +305,7 @@ def mpls_table_check(router, blacklist=None, label_list=None, whitelist=None): test_func = functools.partial( check_show_mpls_table, router, blacklist, label_list, whitelist ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, MPLS labels check fail: {}".format(router.name, result) @@ -450,7 +450,7 @@ def _bgp_prefix_not_found(router, vrf, ipversion, prefix): test_func = functools.partial( _bgp_prefix_not_found, tgen.gears["r1"], "vrf1", "ipv4", "172.31.0.11/32" ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( success ), "r1, prefix 172.31.0.11/32 from r11 did not disappear. r11 still connected to rr ?" @@ -488,7 +488,7 @@ def test_flapping_bgp_vrf_up(): "172.31.0.11/32", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( success ), "r2, prefix 172.31.0.11/32 from r11 not present. r11 still disconnected from rr ?" @@ -518,7 +518,7 @@ def test_recursive_route(): "172.31.0.30/32", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, vpnv4 update 172.31.0.30 not found" bgp_vpnv4_table_check(tgen.gears["r2"], group=PREFIXES_R11 + ["172.31.0.30/32"]) @@ -544,7 +544,7 @@ def test_recursive_route(): "172.31.0.30/32", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, vpnv4 update 172.31.0.30 still present" @@ -570,7 +570,7 @@ def test_prefix_changes_interface(): "172.31.0.50/32", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, vpnv4 update 172.31.0.50 not found" # diagnostic @@ -616,7 +616,7 @@ def test_prefix_changes_interface(): "444:1", label=oldlabel, ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( success ), "r2, vpnv4 update 172.31.0.50 with old label {0} still present".format(oldlabel) @@ -633,7 +633,7 @@ def test_prefix_changes_interface(): "172.31.0.50/32", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, vpnv4 update 172.31.0.50 not found" label_list = set() @@ -699,7 +699,7 @@ def test_changing_default_label_value(): test_func = functools.partial( check_show_mpls_table_entry_label_found, router, 222, "vrf1" ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with label 222 not found" # check label repartition is ok @@ -746,7 +746,7 @@ def test_unconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with label 17 still present" # Check vpnv4 routes from r1 @@ -794,7 +794,7 @@ def test_reconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with label 17 still present" # Check vpnv4 routes from r1 diff --git a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py index 3d5f8f643bc6..3879687aac8e 100644 --- a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py @@ -173,7 +173,7 @@ def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=N stored_label_inited = False for prefix in group: test_func = functools.partial(check_bgp_vpnv6_prefix_presence, router, prefix) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, prefix ipv6 vpn {} is not installed yet".format( router.name, prefix ) @@ -300,7 +300,7 @@ def mpls_table_check(router, blacklist=None, label_list=None, whitelist=None): test_func = functools.partial( check_show_mpls_table, router, blacklist, label_list, whitelist ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, MPLS labels check fail: {}".format(router.name, result) @@ -446,7 +446,7 @@ def _bgp_prefix_not_found(router, vrf, ipversion, prefix): test_func = functools.partial( _bgp_prefix_not_found, tgen.gears["r1"], "vrf1", "ipv6", "172:31::11/128" ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( success ), "r1, prefix 172:31::11/128 from r11 did not disappear. r11 still connected to rr ?" @@ -488,7 +488,7 @@ def test_flapping_bgp_vrf_up(): "172:31::11/128", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( success ), "r2, prefix 172:31::11/128 from r11 not present. r11 still disconnected from rr ?" @@ -526,7 +526,7 @@ def _prefix30_found(router): # Check r2 received vpnv6 update with 172:31::30 test_func = functools.partial(_prefix30_found, tgen.gears["r2"]) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, VPNv6 update 172:31::30 not found" # that route should be sent along with label for 192::2:11 @@ -549,7 +549,7 @@ def _prefix30_found(router): # Check r2 removed 172:31::30 vpnv6 update test_func = functools.partial(_prefix30_not_found, tgen.gears["r2"]) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, VPNv6 update 172:31::30 still present" @@ -575,7 +575,7 @@ def test_prefix_changes_interface(): "172:31::50/128", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, VPNv6 update 172:31::50 not found" # diagnostic @@ -621,7 +621,7 @@ def test_prefix_changes_interface(): "444:1", label=oldlabel, ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert ( success ), "r2, vpnv6 update 172:31::50 with old label {0} still present".format(oldlabel) @@ -638,7 +638,7 @@ def test_prefix_changes_interface(): "172:31::50/128", "444:1", ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r2, vpnv6 update 172:31::50 not found" label_list = set() @@ -704,7 +704,7 @@ def test_changing_default_label_value(): test_func = functools.partial( check_show_mpls_table_entry_label_found, router, 222, "vrf1" ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with label 222 not found" # check label repartition is ok @@ -750,7 +750,7 @@ def test_unconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with label 17 still present" # Check vpnv6 routes from r1 From e8f5caa21bde40148bc5a8f6cecfe2ca78016fe2 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 12 Jun 2024 16:28:38 +0300 Subject: [PATCH 250/472] ospfd: Fix memory leak after cleaning cleaning up interfaceIp JSON field ``` ================================================================= ==6717==ERROR: LeakSanitizer: detected memory leaks Direct leak of 1008 byte(s) in 14 object(s) allocated from: 0 0x7f9ea0dc7d28 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded28) 1 0x7f9ea034d51f in json_object_new_object (/lib/x86_64-linux-gnu/libjson-c.so.3+0x351f) 2 0x564b56d0fed6 in show_ip_ospf_interface_common ospfd/ospf_vty.c:4011 3 0x564b56d1068c in show_ip_ospf_interface ospfd/ospf_vty.c:4285 4 0x7f9ea06fe1c0 in cmd_execute_command_real lib/command.c:1002 5 0x7f9ea06fe684 in cmd_execute_command lib/command.c:1060 6 0x7f9ea06feb03 in cmd_execute lib/command.c:1227 7 0x7f9ea08415b2 in vty_command lib/vty.c:616 8 0x7f9ea0841a5d in vty_execute lib/vty.c:1379 9 0x7f9ea084b367 in vtysh_read lib/vty.c:2374 10 0x7f9ea08350cd in event_call lib/event.c:2011 11 0x7f9ea0764386 in frr_run lib/libfrr.c:1217 12 0x564b56c25b18 in main ospfd/ospf_main.c:295 13 0x7f9e9fd5bc86 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21c86) Indirect leak of 7168 byte(s) in 14 object(s) allocated from: 0 0x7f9ea0dc7d28 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded28) 1 0x7f9ea0350fa4 in lh_table_new (/lib/x86_64-linux-gnu/libjson-c.so.3+0x6fa4) Indirect leak of 1232 byte(s) in 14 object(s) allocated from: 0 0x7f9ea0dc7d28 in __interceptor_calloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xded28) 1 0x7f9ea0350f82 in lh_table_new (/lib/x86_64-linux-gnu/libjson-c.so.3+0x6f82) SUMMARY: AddressSanitizer: 9408 byte(s) leaked in 42 allocation(s). *********************************************************************************** ``` Fixes: e24ff4c275f0729f75be9f68d08be80ac1e0ec56 ("ospfd: Drop `interfaceIp` from `show ip ospf neigh json") Signed-off-by: Donatas Abraitis --- ospfd/ospf_vty.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 21acd402f489..3a11b2123210 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3576,7 +3576,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, struct route_node *rn; uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed; struct ospf_if_params *params; - json_object *json_oi = NULL; /* Is interface up? */ if (use_json) { @@ -3633,12 +3632,9 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, if (oi == NULL) continue; - if (use_json) - json_oi = json_object_new_object(); - if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) { if (use_json) - json_object_boolean_true_add(json_oi, + json_object_boolean_true_add(json_interface_sub, "ifUnnumbered"); else vty_out(vty, " This interface is UNNUMBERED,"); @@ -3932,8 +3928,6 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, /* OSPF Authentication information */ ospf_interface_auth_show(vty, oi, json_interface_sub, use_json); - ospf_interface_auth_show(vty, oi, json_oi, use_json); - /* Point-to-Multipoint Interface options. */ if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) { if (use_json) From d8e3121cb8470fe9a934100de9170b4ef48b17a6 Mon Sep 17 00:00:00 2001 From: Jafar Al-Gharaibeh Date: Wed, 12 Jun 2024 12:03:21 -0500 Subject: [PATCH 251/472] build: FRR 10.2 development version Signed-off-by: Jafar Al-Gharaibeh --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index cad8ea12c06b..ec409aaf1d60 100644 --- a/configure.ac +++ b/configure.ac @@ -7,7 +7,7 @@ ## AC_PREREQ([2.69]) -AC_INIT([frr], [10.1-dev], [https://github.com/frrouting/frr/issues]) +AC_INIT([frr], [10.2-dev], [https://github.com/frrouting/frr/issues]) PACKAGE_URL="https://frrouting.org/" AC_SUBST([PACKAGE_URL]) PACKAGE_FULLNAME="FRRouting" From 5d7af51c4f7980507135babd94d392ca179c1bf7 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 12 Jun 2024 22:54:45 +0300 Subject: [PATCH 252/472] bgpd: Check if we have really enough data before doing memcpy for software version If we receive CAPABILITY message (software-version), we SHOULD check if we really have enough data before doing memcpy(), that could also lead to buffer overflow. (data + len > end) is not enough, because after this check we do data++ and later memcpy(..., data, len). That means we have one more byte. Hit this through fuzzing by ``` 0 0xaaaaaadf872c in __asan_memcpy (/home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/.libs/bgpd+0x35872c) (BuildId: 9c6e455d0d9a20f5a4d2f035b443f50add9564d7) 1 0xaaaaab06bfbc in bgp_dynamic_capability_software_version /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:3713:3 2 0xaaaaab05ccb4 in bgp_capability_msg_parse /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:3839:4 3 0xaaaaab05c074 in bgp_capability_receive /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:3980:9 4 0xaaaaab05e48c in bgp_process_packet /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:4109:11 5 0xaaaaaae36150 in LLVMFuzzerTestOneInput /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_main.c:582:3 ``` Hit this again by Iggy \m/ Reported-by: Iggy Frankovic Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 3f38790cbda3..5d9789432646 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -3694,7 +3694,7 @@ static void bgp_dynamic_capability_software_version(uint8_t *pnt, int action, char soft_version[BGP_MAX_SOFT_VERSION + 1] = {}; if (action == CAPABILITY_ACTION_SET) { - if (data + len > end) { + if (data + len + 1 > end) { zlog_err("%pBP: Received invalid Software Version capability length %d", peer, len); return; From b685ab5e1bdec0848502c20e9596b9716b236639 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 13 Jun 2024 08:12:10 +0300 Subject: [PATCH 253/472] bgpd: Check if we have really enough data before doing memcpy for FQDN capability We advance data pointer (data++), but we do memcpy() with the length that is 1-byte over, which is technically heap overflow. ``` ==411461==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50600011da1a at pc 0xc4f45a9786f0 bp 0xffffed1e2740 sp 0xffffed1e1f30 READ of size 4 at 0x50600011da1a thread T0 0 0xc4f45a9786ec in __asan_memcpy (/home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/.libs/bgpd+0x3586ec) (BuildId: e794c5f796eee20c8973d7efb9bf5735e54d44cd) 1 0xc4f45abf15f8 in bgp_dynamic_capability_fqdn /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:3457:4 2 0xc4f45abdd408 in bgp_capability_msg_parse /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:3911:4 3 0xc4f45abdbeb4 in bgp_capability_receive /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:3980:9 4 0xc4f45abde2cc in bgp_process_packet /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_packet.c:4109:11 5 0xc4f45a9b6110 in LLVMFuzzerTestOneInput /home/ubuntu/frr-public/frr_public_private-libfuzzer/bgpd/bgp_main.c:582:3 ``` Found by fuzzing. Reported-by: Iggy Frankovic Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 3f38790cbda3..e54766aa3958 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -3437,7 +3437,7 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action, } len = *data; - if (data + len > end) { + if (data + len + 1 > end) { zlog_err("%pBP: Received invalid FQDN capability length (host name) %d", peer, hdr->length); return; @@ -3468,7 +3468,7 @@ static void bgp_dynamic_capability_fqdn(uint8_t *pnt, int action, /* domainname */ len = *data; - if (data + len > end) { + if (data + len + 1 > end) { zlog_err("%pBP: Received invalid FQDN capability length (domain name) %d", peer, len); return; From 34b209f0ae2caca0d1ebcde9d4095375ac31b562 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 13 Jun 2024 08:43:21 +0300 Subject: [PATCH 254/472] bgpd: Adjust the length of tunnel encap sub-tlv by sub-tlv type Fixes: 79563af564ad0fe5b9c8d95bf080d570f87b1859 ("bgpd: Get 1 or 2 octets for Sub-TLV length (Tunnel Encap attr)") Signed-off-by: Donatas Abraitis --- bgpd/bgp_attr.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index da4701d069db..9f377589e960 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2728,10 +2728,13 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args) if (BGP_ATTR_ENCAP == type) { subtype = stream_getc(BGP_INPUT(peer)); - sublength = (subtype < 128) - ? stream_getc(BGP_INPUT(peer)) - : stream_getw(BGP_INPUT(peer)); - length -= 2; + if (subtype < 128) { + sublength = stream_getc(BGP_INPUT(peer)); + length -= 2; + } else { + sublength = stream_getw(BGP_INPUT(peer)); + length -= 3; + } #ifdef ENABLE_BGP_VNC } else { subtype = stream_getw(BGP_INPUT(peer)); From 9929486d6bdb28469a5b626a17d5bc9991c83ce3 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 13 Jun 2024 09:00:21 +0300 Subject: [PATCH 255/472] bgpd: Check if we have real stream data for tunnel encapsulation sub-tlvs When the packet is malformed it can use whatever values it wants. Let's check what the real data we have in a stream instead of relying on malformed values. Reported-by: Iggy Frankovic Signed-off-by: Donatas Abraitis --- bgpd/bgp_attr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 9f377589e960..18c7b13535d0 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2721,7 +2721,7 @@ static int bgp_attr_encap(struct bgp_attr_parser_args *args) } } - while (length >= 4) { + while (STREAM_READABLE(BGP_INPUT(peer)) >= 4) { uint16_t subtype = 0; uint16_t sublength = 0; struct bgp_attr_encap_subtlv *tlv; From 021386a34eb49893ce6b7df16c2fe1096a8fedf6 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 22 Mar 2024 15:13:00 +0100 Subject: [PATCH 256/472] lib: Add support for SRv6 SID formats Add functionalities to manage SRv6 SID formats (allocate / free). Signed-off-by: Carmine Scarpitta --- lib/srv6.c | 148 +++++++++++++++++++++++++++++++++++++++++------------ lib/srv6.h | 61 ++++++++++++++++++++++ 2 files changed, 175 insertions(+), 34 deletions(-) diff --git a/lib/srv6.c b/lib/srv6.c index a82103e423e9..abaff7eab830 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -10,8 +10,10 @@ #include "log.h" DEFINE_QOBJ_TYPE(srv6_locator); +DEFINE_QOBJ_TYPE(srv6_sid_format); DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR, "SRV6 locator"); DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk"); +DEFINE_MTYPE_STATIC(LIB, SRV6_SID_FORMAT, "SRv6 SID format"); const char *seg6local_action2str(uint32_t action) { @@ -154,6 +156,36 @@ void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk) XFREE(MTYPE_SRV6_LOCATOR_CHUNK, *chunk); } +struct srv6_sid_format *srv6_sid_format_alloc(const char *name) +{ + struct srv6_sid_format *format = NULL; + + format = XCALLOC(MTYPE_SRV6_SID_FORMAT, sizeof(struct srv6_sid_format)); + strlcpy(format->name, name, sizeof(format->name)); + + QOBJ_REG(format, srv6_sid_format); + return format; +} + +void srv6_sid_format_free(struct srv6_sid_format *format) +{ + if (!format) + return; + + QOBJ_UNREG(format); + XFREE(MTYPE_SRV6_SID_FORMAT, format); +} + +/** + * Free an SRv6 SID format. + * + * @param val SRv6 SID format to be freed + */ +void delete_srv6_sid_format(void *val) +{ + srv6_sid_format_free((struct srv6_sid_format *)val); +} + json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk) { json_object *jo_root = NULL; @@ -223,23 +255,47 @@ json_object *srv6_locator_json(const struct srv6_locator *loc) /* set prefix */ json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix); - /* set block_bits_length */ - json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length); - - /* set node_bits_length */ - json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length); - - /* set function_bits_length */ - json_object_int_add(jo_root, "functionBitsLength", - loc->function_bits_length); - - /* set argument_bits_length */ - json_object_int_add(jo_root, "argumentBitsLength", - loc->argument_bits_length); - - /* set true if the locator is a Micro-segment (uSID) locator */ - if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID)) - json_object_string_add(jo_root, "behavior", "usid"); + if (loc->sid_format) { + /* set block_bits_length */ + json_object_int_add(jo_root, "blockBitsLength", + loc->sid_format->block_len); + + /* set node_bits_length */ + json_object_int_add(jo_root, "nodeBitsLength", + loc->sid_format->node_len); + + /* set function_bits_length */ + json_object_int_add(jo_root, "functionBitsLength", + loc->sid_format->function_len); + + /* set argument_bits_length */ + json_object_int_add(jo_root, "argumentBitsLength", + loc->sid_format->argument_len); + + /* set true if the locator is a Micro-segment (uSID) locator */ + if (loc->sid_format->type == SRV6_SID_FORMAT_TYPE_USID) + json_object_string_add(jo_root, "behavior", "usid"); + } else { + /* set block_bits_length */ + json_object_int_add(jo_root, "blockBitsLength", + loc->block_bits_length); + + /* set node_bits_length */ + json_object_int_add(jo_root, "nodeBitsLength", + loc->node_bits_length); + + /* set function_bits_length */ + json_object_int_add(jo_root, "functionBitsLength", + loc->function_bits_length); + + /* set argument_bits_length */ + json_object_int_add(jo_root, "argumentBitsLength", + loc->argument_bits_length); + + /* set true if the locator is a Micro-segment (uSID) locator */ + if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID)) + json_object_string_add(jo_root, "behavior", "usid"); + } /* set status_up */ json_object_boolean_add(jo_root, "statusUp", @@ -272,23 +328,47 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc) /* set prefix */ json_object_string_addf(jo_root, "prefix", "%pFX", &loc->prefix); - /* set block_bits_length */ - json_object_int_add(jo_root, "blockBitsLength", loc->block_bits_length); - - /* set node_bits_length */ - json_object_int_add(jo_root, "nodeBitsLength", loc->node_bits_length); - - /* set function_bits_length */ - json_object_int_add(jo_root, "functionBitsLength", - loc->function_bits_length); - - /* set argument_bits_length */ - json_object_int_add(jo_root, "argumentBitsLength", - loc->argument_bits_length); - - /* set true if the locator is a Micro-segment (uSID) locator */ - if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID)) - json_object_string_add(jo_root, "behavior", "usid"); + if (loc->sid_format) { + /* set block_bits_length */ + json_object_int_add(jo_root, "blockBitsLength", + loc->sid_format->block_len); + + /* set node_bits_length */ + json_object_int_add(jo_root, "nodeBitsLength", + loc->sid_format->node_len); + + /* set function_bits_length */ + json_object_int_add(jo_root, "functionBitsLength", + loc->sid_format->function_len); + + /* set argument_bits_length */ + json_object_int_add(jo_root, "argumentBitsLength", + loc->sid_format->argument_len); + + /* set true if the locator is a Micro-segment (uSID) locator */ + if (loc->sid_format->type == SRV6_SID_FORMAT_TYPE_USID) + json_object_string_add(jo_root, "behavior", "usid"); + } else { + /* set block_bits_length */ + json_object_int_add(jo_root, "blockBitsLength", + loc->block_bits_length); + + /* set node_bits_length */ + json_object_int_add(jo_root, "nodeBitsLength", + loc->node_bits_length); + + /* set function_bits_length */ + json_object_int_add(jo_root, "functionBitsLength", + loc->function_bits_length); + + /* set argument_bits_length */ + json_object_int_add(jo_root, "argumentBitsLength", + loc->argument_bits_length); + + /* set true if the locator is a Micro-segment (uSID) locator */ + if (CHECK_FLAG(loc->flags, SRV6_LOCATOR_USID)) + json_object_string_add(jo_root, "behavior", "usid"); + } /* set algonum */ json_object_int_add(jo_root, "algoNum", loc->algonum); diff --git a/lib/srv6.h b/lib/srv6.h index 433c5c14fdca..04f560b26780 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -20,6 +20,8 @@ #define SRH_BASE_HEADER_LENGTH 8 #define SRH_SEGMENT_LENGTH 16 +#define SRV6_SID_FORMAT_NAME_SIZE 512 + #ifdef __cplusplus extern "C" { #endif @@ -183,6 +185,61 @@ struct nexthop_srv6 { struct seg6_seg_stack *seg6_segs; }; +/* SID format type */ +enum srv6_sid_format_type { + SRV6_SID_FORMAT_TYPE_UNSPEC = 0, + /* SRv6 SID uncompressed format */ + SRV6_SID_FORMAT_TYPE_UNCOMPRESSED = 1, + /* SRv6 SID compressed uSID format */ + SRV6_SID_FORMAT_TYPE_USID = 2, +}; + +/* SRv6 SID format */ +struct srv6_sid_format { + /* Name of the format */ + char name[SRV6_SID_FORMAT_NAME_SIZE]; + + /* Format type: uncompressed vs compressed */ + enum srv6_sid_format_type type; + + /* + * Lengths of block/node/function/argument parts of the SIDs allocated + * using this format + */ + uint8_t block_len; + uint8_t node_len; + uint8_t function_len; + uint8_t argument_len; + + union { + /* Configuration settings for compressed uSID format type */ + struct { + /* Start of the Local ID Block (LIB) range */ + uint32_t lib_start; + + /* Start/End of the Explicit LIB range */ + uint32_t elib_start; + uint32_t elib_end; + + /* Start/End of the Wide LIB range */ + uint32_t wlib_start; + uint32_t wlib_end; + + /* Start/End of the Explicit Wide LIB range */ + uint32_t ewlib_start; + } usid; + + /* Configuration settings for uncompressed format type */ + struct { + /* Start of the Explicit range */ + uint32_t explicit_start; + } uncompressed; + } config; + + QOBJ_FIELDS; +}; +DECLARE_QOBJ_TYPE(srv6_sid_format); + static inline const char *seg6_mode2str(enum seg6_mode_t mode) { switch (mode) { @@ -260,6 +317,10 @@ json_object *srv6_locator_detailed_json(const struct srv6_locator *loc); json_object * srv6_locator_chunk_detailed_json(const struct srv6_locator_chunk *chunk); +extern struct srv6_sid_format *srv6_sid_format_alloc(const char *name); +extern void srv6_sid_format_free(struct srv6_sid_format *format); +extern void delete_srv6_sid_format(void *format); + #ifdef __cplusplus } #endif From 1298867671f7fe76c65730afbb9ae54dcd7264be Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 6 Jun 2024 17:23:11 +0200 Subject: [PATCH 257/472] zebra: Add support for SRv6 SID formats Add functionalities to manage SRv6 SID formats (register / unregister / lookup) and create two SID formats upon SRv6 Manager initialization: `uncompressed-f4024` and `usid-f3216`. In future commits, we will add the CLI to allow the user to choose between the two formats. Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 132 ++++++++++++++++++++++++++++++++++++++--- zebra/zebra_srv6.h | 29 +++++++++ zebra/zebra_srv6_vty.c | 35 ++++++++--- 3 files changed, 180 insertions(+), 16 deletions(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index bb872ef91c62..dffc6ca091bb 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -90,6 +90,98 @@ static int zebra_srv6_cleanup(struct zserv *client) return 0; } +/* --- Zebra SRv6 SID format management functions --------------------------- */ + +void zebra_srv6_sid_format_register(struct zebra_srv6_sid_format *format) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + + /* Ensure that the format is registered only once */ + assert(!zebra_srv6_sid_format_lookup(format->name)); + + listnode_add(srv6->sid_formats, format); +} + +void zebra_srv6_sid_format_unregister(struct zebra_srv6_sid_format *format) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + + listnode_delete(srv6->sid_formats, format); +} + +struct zebra_srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_format *format; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(srv6->sid_formats, node, format)) + if (!strncmp(name, format->name, sizeof(format->name))) + return format; + + return NULL; +} + +/* + * Helper function to create the SRv6 compressed format `usid-f3216`. + */ +static struct zebra_srv6_sid_format *create_srv6_sid_format_usid_f3216(void) +{ + struct zebra_srv6_sid_format *format = NULL; + + format = zebra_srv6_sid_format_alloc( + ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME); + + format->type = SRV6_SID_FORMAT_TYPE_USID; + + /* Define block/node/function length */ + format->block_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN; + format->node_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_NODE_LEN; + format->function_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN; + format->argument_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN; + + /* Define the ranges from which the SID function can be allocated */ + format->config.usid.lib_start = + ZEBRA_SRV6_SID_FORMAT_USID_F3216_LIB_START; + format->config.usid.elib_start = + ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_START; + format->config.usid.elib_end = ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_END; + format->config.usid.wlib_start = + ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_START; + format->config.usid.wlib_end = ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_END; + format->config.usid.ewlib_start = + ZEBRA_SRV6_SID_FORMAT_USID_F3216_EWLIB_START; + + return format; +} + +/* + * Helper function to create the SRv6 uncompressed format. + */ +static struct zebra_srv6_sid_format *create_srv6_sid_format_uncompressed(void) +{ + struct zebra_srv6_sid_format *format = NULL; + + format = zebra_srv6_sid_format_alloc( + ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME); + + format->type = ZEBRA_SRV6_SID_FORMAT_TYPE_UNCOMPRESSED; + + /* Define block/node/function length */ + format->block_len = ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN; + format->node_len = ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN; + format->function_len = + ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN; + format->argument_len = + ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN; + + /* Define the ranges from which the SID function can be allocated */ + format->config.uncompressed.explicit_start = + ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START; + + return format; +} + void zebra_srv6_locator_add(struct srv6_locator *locator) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); @@ -222,10 +314,24 @@ struct zebra_srv6 srv6; struct zebra_srv6 *zebra_srv6_get_default(void) { static bool first_execution = true; + struct zebra_srv6_sid_format *format_usidf3216; + struct zebra_srv6_sid_format *format_uncompressed; if (first_execution) { first_execution = false; srv6.locators = list_new(); + + /* Initialize list of SID formats */ + srv6.sid_formats = list_new(); + srv6.sid_formats->del = delete_zebra_srv6_sid_format; + + /* Create SID format `usid-f3216` */ + format_usidf3216 = create_srv6_sid_format_usid_f3216(); + zebra_srv6_sid_format_register(format_usidf3216); + + /* Create SID format `uncompressed` */ + format_uncompressed = create_srv6_sid_format_uncompressed(); + zebra_srv6_sid_format_register(format_uncompressed); } return &srv6; } @@ -430,18 +536,30 @@ void zebra_srv6_encap_src_addr_unset(void) void zebra_srv6_terminate(void) { struct srv6_locator *locator; + struct zebra_srv6_sid_format *format; - if (!srv6.locators) - return; + if (srv6.locators) { + while (listcount(srv6.locators)) { + locator = listnode_head(srv6.locators); - while (listcount(srv6.locators)) { - locator = listnode_head(srv6.locators); + listnode_delete(srv6.locators, locator); + srv6_locator_free(locator); + } - listnode_delete(srv6.locators, locator); - srv6_locator_free(locator); + list_delete(&srv6.locators); } - list_delete(&srv6.locators); + /* Free SRv6 SID formats */ + if (srv6.sid_formats) { + while (listcount(srv6.sid_formats)) { + format = listnode_head(srv6.sid_formats); + + zebra_srv6_sid_format_unregister(format); + zebra_srv6_sid_format_free(format); + } + + list_delete(&srv6.sid_formats); + } } void zebra_srv6_init(void) diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 21936c332354..a645c5cc0d49 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -16,12 +16,37 @@ #include #include +/* Default config for SRv6 SID `usid-f3216` format */ +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME "usid-f3216" +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN 32 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_NODE_LEN 16 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN 16 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN 0 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_LIB_START 0xE000 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_START 0xFE00 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_END 0xFEFF +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_START 0xFFF0 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_END 0xFFF7 +#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_EWLIB_START 0xFFF7 + +/* Default config for SRv6 SID `uncompressed` format */ +#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME "uncompressed-f4024" +#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN 40 +#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN 24 +#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN 16 +#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN 0 +#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START 0xFF00 +#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNC_UNRESERVED_MIN 0x40 + /* SRv6 instance structure. */ struct zebra_srv6 { struct list *locators; /* Source address for SRv6 encapsulation */ struct in6_addr encap_src_addr; + + /* SRv6 SID formats */ + struct list *sid_formats; }; /* declare hooks for the basic API, so that it can be specialized or served @@ -74,4 +99,8 @@ extern int release_daemon_srv6_locator_chunks(struct zserv *client); extern void zebra_srv6_encap_src_addr_set(struct in6_addr *src_addr); extern void zebra_srv6_encap_src_addr_unset(void); +void zebra_srv6_sid_format_register(struct zebra_srv6_sid_format *format); +void zebra_srv6_sid_format_unregister(struct zebra_srv6_sid_format *format); +struct zebra_srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name); + #endif /* _ZEBRA_SRV6_H */ diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index d5cd30e64bfc..ddb092247510 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -198,15 +198,32 @@ DEFUN (show_srv6_locator_detail, prefix2str(&locator->prefix, str, sizeof(str)); vty_out(vty, "Name: %s\n", locator->name); vty_out(vty, "Prefix: %s\n", str); - vty_out(vty, "Block-Bit-Len: %u\n", locator->block_bits_length); - vty_out(vty, "Node-Bit-Len: %u\n", locator->node_bits_length); - vty_out(vty, "Function-Bit-Len: %u\n", - locator->function_bits_length); - vty_out(vty, "Argument-Bit-Len: %u\n", - locator->argument_bits_length); - - if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) - vty_out(vty, "Behavior: uSID\n"); + if (locator->sid_format) { + vty_out(vty, "Block-Bit-Len: %u\n", + locator->sid_format->block_len); + vty_out(vty, "Node-Bit-Len: %u\n", + locator->sid_format->node_len); + vty_out(vty, "Function-Bit-Len: %u\n", + locator->sid_format->function_len); + vty_out(vty, "Argument-Bit-Len: %u\n", + locator->sid_format->argument_len); + + if (locator->sid_format->type == + SRV6_SID_FORMAT_TYPE_USID) + vty_out(vty, "Behavior: uSID\n"); + } else { + vty_out(vty, "Block-Bit-Len: %u\n", + locator->block_bits_length); + vty_out(vty, "Node-Bit-Len: %u\n", + locator->node_bits_length); + vty_out(vty, "Function-Bit-Len: %u\n", + locator->function_bits_length); + vty_out(vty, "Argument-Bit-Len: %u\n", + locator->argument_bits_length); + + if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) + vty_out(vty, "Behavior: uSID\n"); + } vty_out(vty, "Chunks:\n"); for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node, From 35f4bedfa3a5017a69878b2a2b37f06149f94adf Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 22 Mar 2024 15:56:15 +0100 Subject: [PATCH 258/472] lib: Add CLI nodes to support SRv6 SID format Add CLI commands to support overriding default configuration of the SID format. Signed-off-by: Carmine Scarpitta --- lib/command.h | 3 +++ zebra/zebra_srv6.c | 31 +++++++++++++++---------------- zebra/zebra_srv6.h | 6 +++--- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/lib/command.h b/lib/command.h index e4c575e8d787..6f819c7e3693 100644 --- a/lib/command.h +++ b/lib/command.h @@ -161,6 +161,9 @@ enum node_type { SRV6_LOCS_NODE, /* SRv6 locators node */ SRV6_LOC_NODE, /* SRv6 locator node */ SRV6_ENCAP_NODE, /* SRv6 encapsulation node */ + SRV6_SID_FORMATS_NODE, /* SRv6 SID formats config node */ + SRV6_SID_FORMAT_USID_F3216_NODE, /* SRv6 uSID f3216 format config node */ + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, /* SRv6 uncompressed f4024 format config node */ VTY_NODE, /* Vty node. */ FPM_NODE, /* Dataplane FPM node. */ LINK_PARAMS_NODE, /* Link-parameters node */ diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index dffc6ca091bb..fa3b4a733b89 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -92,7 +92,7 @@ static int zebra_srv6_cleanup(struct zserv *client) /* --- Zebra SRv6 SID format management functions --------------------------- */ -void zebra_srv6_sid_format_register(struct zebra_srv6_sid_format *format) +void zebra_srv6_sid_format_register(struct srv6_sid_format *format) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); @@ -102,17 +102,17 @@ void zebra_srv6_sid_format_register(struct zebra_srv6_sid_format *format) listnode_add(srv6->sid_formats, format); } -void zebra_srv6_sid_format_unregister(struct zebra_srv6_sid_format *format) +void zebra_srv6_sid_format_unregister(struct srv6_sid_format *format) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); listnode_delete(srv6->sid_formats, format); } -struct zebra_srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name) +struct srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); - struct zebra_srv6_sid_format *format; + struct srv6_sid_format *format; struct listnode *node; for (ALL_LIST_ELEMENTS_RO(srv6->sid_formats, node, format)) @@ -125,12 +125,11 @@ struct zebra_srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name) /* * Helper function to create the SRv6 compressed format `usid-f3216`. */ -static struct zebra_srv6_sid_format *create_srv6_sid_format_usid_f3216(void) +static struct srv6_sid_format *create_srv6_sid_format_usid_f3216(void) { - struct zebra_srv6_sid_format *format = NULL; + struct srv6_sid_format *format = NULL; - format = zebra_srv6_sid_format_alloc( - ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME); + format = srv6_sid_format_alloc(ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME); format->type = SRV6_SID_FORMAT_TYPE_USID; @@ -158,11 +157,11 @@ static struct zebra_srv6_sid_format *create_srv6_sid_format_usid_f3216(void) /* * Helper function to create the SRv6 uncompressed format. */ -static struct zebra_srv6_sid_format *create_srv6_sid_format_uncompressed(void) +static struct srv6_sid_format *create_srv6_sid_format_uncompressed(void) { - struct zebra_srv6_sid_format *format = NULL; + struct srv6_sid_format *format = NULL; - format = zebra_srv6_sid_format_alloc( + format = srv6_sid_format_alloc( ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME); format->type = ZEBRA_SRV6_SID_FORMAT_TYPE_UNCOMPRESSED; @@ -314,8 +313,8 @@ struct zebra_srv6 srv6; struct zebra_srv6 *zebra_srv6_get_default(void) { static bool first_execution = true; - struct zebra_srv6_sid_format *format_usidf3216; - struct zebra_srv6_sid_format *format_uncompressed; + struct srv6_sid_format *format_usidf3216; + struct srv6_sid_format *format_uncompressed; if (first_execution) { first_execution = false; @@ -323,7 +322,7 @@ struct zebra_srv6 *zebra_srv6_get_default(void) /* Initialize list of SID formats */ srv6.sid_formats = list_new(); - srv6.sid_formats->del = delete_zebra_srv6_sid_format; + srv6.sid_formats->del = delete_srv6_sid_format; /* Create SID format `usid-f3216` */ format_usidf3216 = create_srv6_sid_format_usid_f3216(); @@ -536,7 +535,7 @@ void zebra_srv6_encap_src_addr_unset(void) void zebra_srv6_terminate(void) { struct srv6_locator *locator; - struct zebra_srv6_sid_format *format; + struct srv6_sid_format *format; if (srv6.locators) { while (listcount(srv6.locators)) { @@ -555,7 +554,7 @@ void zebra_srv6_terminate(void) format = listnode_head(srv6.sid_formats); zebra_srv6_sid_format_unregister(format); - zebra_srv6_sid_format_free(format); + srv6_sid_format_free(format); } list_delete(&srv6.sid_formats); diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index a645c5cc0d49..57f9d83825ae 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -99,8 +99,8 @@ extern int release_daemon_srv6_locator_chunks(struct zserv *client); extern void zebra_srv6_encap_src_addr_set(struct in6_addr *src_addr); extern void zebra_srv6_encap_src_addr_unset(void); -void zebra_srv6_sid_format_register(struct zebra_srv6_sid_format *format); -void zebra_srv6_sid_format_unregister(struct zebra_srv6_sid_format *format); -struct zebra_srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name); +void zebra_srv6_sid_format_register(struct srv6_sid_format *format); +void zebra_srv6_sid_format_unregister(struct srv6_sid_format *format); +struct srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name); #endif /* _ZEBRA_SRV6_H */ From b3ca230a8f02291961219eda7969f1e43aba931c Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Tue, 26 Mar 2024 08:53:17 +0100 Subject: [PATCH 259/472] vtysh: CLI to override default SID format config Add CLI commands to support overriding default configuration of the SID format. Signed-off-by: Carmine Scarpitta --- vtysh/vtysh.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index b1c957d043a3..573320667c33 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1344,6 +1344,27 @@ static struct cmd_node srv6_encap_node = { .prompt = "%s(config-srv6-encap)# " }; +static struct cmd_node srv6_sid_formats_node = { + .name = "srv6-formats", + .node = SRV6_SID_FORMATS_NODE, + .parent_node = SRV6_NODE, + .prompt = "%s(config-srv6-formats)# ", +}; + +static struct cmd_node srv6_sid_format_usid_f3216_node = { + .name = "srv6-format-usid-f3216", + .node = SRV6_SID_FORMAT_USID_F3216_NODE, + .parent_node = SRV6_SID_FORMATS_NODE, + .prompt = "%s(config-srv6-format)# " +}; + +static struct cmd_node srv6_sid_format_uncompressed_f4024_node = { + .name = "srv6-format-uncompressed-f4024", + .node = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, + .parent_node = SRV6_SID_FORMATS_NODE, + .prompt = "%s(config-srv6-format)# " +}; + #ifdef HAVE_PBRD static struct cmd_node pbr_map_node = { .name = "pbr-map", @@ -1715,6 +1736,31 @@ DEFUNSH(VTYSH_ZEBRA, srv6_encap, srv6_encap_cmd, return CMD_SUCCESS; } +DEFUNSH(VTYSH_ZEBRA, srv6_sid_formats, srv6_sid_formats_cmd, "formats", + "Segment Routing SRv6 SID formats\n") +{ + vty->node = SRV6_SID_FORMATS_NODE; + return CMD_SUCCESS; +} + +DEFUNSH(VTYSH_ZEBRA, srv6_sid_format_f3216_usid, srv6_sid_format_f3216_usid_cmd, + "format usid-f3216", + "Configure SRv6 SID format\n" + "Configure the uSID f3216 format\n") +{ + vty->node = SRV6_SID_FORMAT_USID_F3216_NODE; + return CMD_SUCCESS; +} + +DEFUNSH(VTYSH_ZEBRA, srv6_sid_format_f4024_uncompressed, srv6_sid_format_f4024_uncompressed_cmd, + "format uncompressed-f4024", + "Configure SRv6 SID format\n" + "Configure the uncompressed f4024 format\n") +{ + vty->node = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE; + return CMD_SUCCESS; +} + #ifdef HAVE_BGPD DEFUNSH(VTYSH_BGPD, router_bgp, router_bgp_cmd, "router bgp [ASNUM [ VIEWVRFNAME] [as-notation ]]", @@ -2515,6 +2561,23 @@ DEFUNSH(VTYSH_ZEBRA, exit_srv6_encap, exit_srv6_encap_cmd, "exit", return CMD_SUCCESS; } +DEFUNSH(VTYSH_ZEBRA, exit_srv6_sid_formats, exit_srv6_sid_formats_cmd, "exit", + "Exit from SRv6 SID formats configuration mode\n") +{ + if (vty->node == SRV6_SID_FORMATS_NODE) + vty->node = SRV6_NODE; + return CMD_SUCCESS; +} + +DEFUNSH(VTYSH_ZEBRA, exit_srv6_sid_format, exit_srv6_sid_format_cmd, + "exit", "Exit from SRv6 SID format configuration mode\n") +{ + if (vty->node == SRV6_SID_FORMAT_USID_F3216_NODE || + vty->node == SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE) + vty->node = SRV6_SID_FORMATS_NODE; + return CMD_SUCCESS; +} + #ifdef HAVE_RIPD DEFUNSH(VTYSH_MGMTD, vtysh_exit_ripd, vtysh_exit_ripd_cmd, "exit", "Exit current mode and down to previous mode\n") @@ -5304,6 +5367,7 @@ void vtysh_init_vty(void) install_node(&srv6_node); install_element(SEGMENT_ROUTING_NODE, &srv6_cmd); install_element(SRV6_NODE, &srv6_locators_cmd); + install_element(SRV6_NODE, &srv6_sid_formats_cmd); install_element(SRV6_NODE, &exit_srv6_config_cmd); install_element(SRV6_NODE, &vtysh_end_all_cmd); install_element(SRV6_NODE, &srv6_encap_cmd); @@ -5321,6 +5385,24 @@ void vtysh_init_vty(void) install_element(SRV6_ENCAP_NODE, &exit_srv6_encap_cmd); install_element(SRV6_ENCAP_NODE, &vtysh_end_all_cmd); + install_node(&srv6_sid_formats_node); + install_element(SRV6_SID_FORMATS_NODE, &srv6_sid_format_f3216_usid_cmd); + install_element(SRV6_SID_FORMATS_NODE, + &srv6_sid_format_f4024_uncompressed_cmd); + install_element(SRV6_SID_FORMATS_NODE, &exit_srv6_sid_formats_cmd); + install_element(SRV6_SID_FORMATS_NODE, &vtysh_end_all_cmd); + + install_node(&srv6_sid_format_usid_f3216_node); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &exit_srv6_sid_format_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, &vtysh_end_all_cmd); + + install_node(&srv6_sid_format_uncompressed_f4024_node); + install_element(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, + &exit_srv6_sid_format_cmd); + install_element(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, + &vtysh_end_all_cmd); + install_element(ENABLE_NODE, &vtysh_show_running_config_cmd); install_element(ENABLE_NODE, &vtysh_copy_running_config_cmd); install_element(ENABLE_NODE, &vtysh_copy_to_running_cmd); From 51d3cd8a007d5c2ad6bb27af404f2d95164cf4c2 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Tue, 26 Mar 2024 08:53:55 +0100 Subject: [PATCH 260/472] zebra: CLI to override default SID format config Add CLI commands to support overriding default configuration of the SID format. Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 57 +++---- zebra/zebra_srv6.h | 42 ++--- zebra/zebra_srv6_vty.c | 365 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 411 insertions(+), 53 deletions(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index fa3b4a733b89..825f0f7fc214 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -92,24 +92,24 @@ static int zebra_srv6_cleanup(struct zserv *client) /* --- Zebra SRv6 SID format management functions --------------------------- */ -void zebra_srv6_sid_format_register(struct srv6_sid_format *format) +void srv6_sid_format_register(struct srv6_sid_format *format) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); /* Ensure that the format is registered only once */ - assert(!zebra_srv6_sid_format_lookup(format->name)); + assert(!srv6_sid_format_lookup(format->name)); listnode_add(srv6->sid_formats, format); } -void zebra_srv6_sid_format_unregister(struct srv6_sid_format *format) +void srv6_sid_format_unregister(struct srv6_sid_format *format) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); listnode_delete(srv6->sid_formats, format); } -struct srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name) +struct srv6_sid_format *srv6_sid_format_lookup(const char *name) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); struct srv6_sid_format *format; @@ -129,27 +129,23 @@ static struct srv6_sid_format *create_srv6_sid_format_usid_f3216(void) { struct srv6_sid_format *format = NULL; - format = srv6_sid_format_alloc(ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME); + format = srv6_sid_format_alloc(SRV6_SID_FORMAT_USID_F3216_NAME); format->type = SRV6_SID_FORMAT_TYPE_USID; /* Define block/node/function length */ - format->block_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN; - format->node_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_NODE_LEN; - format->function_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN; - format->argument_len = ZEBRA_SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN; + format->block_len = SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN; + format->node_len = SRV6_SID_FORMAT_USID_F3216_NODE_LEN; + format->function_len = SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN; + format->argument_len = SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN; /* Define the ranges from which the SID function can be allocated */ - format->config.usid.lib_start = - ZEBRA_SRV6_SID_FORMAT_USID_F3216_LIB_START; - format->config.usid.elib_start = - ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_START; - format->config.usid.elib_end = ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_END; - format->config.usid.wlib_start = - ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_START; - format->config.usid.wlib_end = ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_END; - format->config.usid.ewlib_start = - ZEBRA_SRV6_SID_FORMAT_USID_F3216_EWLIB_START; + format->config.usid.lib_start = SRV6_SID_FORMAT_USID_F3216_LIB_START; + format->config.usid.elib_start = SRV6_SID_FORMAT_USID_F3216_ELIB_START; + format->config.usid.elib_end = SRV6_SID_FORMAT_USID_F3216_ELIB_END; + format->config.usid.wlib_start = SRV6_SID_FORMAT_USID_F3216_WLIB_START; + format->config.usid.wlib_end = SRV6_SID_FORMAT_USID_F3216_WLIB_END; + format->config.usid.ewlib_start = SRV6_SID_FORMAT_USID_F3216_EWLIB_START; return format; } @@ -161,22 +157,19 @@ static struct srv6_sid_format *create_srv6_sid_format_uncompressed(void) { struct srv6_sid_format *format = NULL; - format = srv6_sid_format_alloc( - ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME); + format = srv6_sid_format_alloc(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME); - format->type = ZEBRA_SRV6_SID_FORMAT_TYPE_UNCOMPRESSED; + format->type = SRV6_SID_FORMAT_TYPE_UNCOMPRESSED; /* Define block/node/function length */ - format->block_len = ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN; - format->node_len = ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN; - format->function_len = - ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN; - format->argument_len = - ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN; + format->block_len = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN; + format->node_len = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN; + format->function_len = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN; + format->argument_len = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN; /* Define the ranges from which the SID function can be allocated */ format->config.uncompressed.explicit_start = - ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START; + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START; return format; } @@ -326,11 +319,11 @@ struct zebra_srv6 *zebra_srv6_get_default(void) /* Create SID format `usid-f3216` */ format_usidf3216 = create_srv6_sid_format_usid_f3216(); - zebra_srv6_sid_format_register(format_usidf3216); + srv6_sid_format_register(format_usidf3216); /* Create SID format `uncompressed` */ format_uncompressed = create_srv6_sid_format_uncompressed(); - zebra_srv6_sid_format_register(format_uncompressed); + srv6_sid_format_register(format_uncompressed); } return &srv6; } @@ -553,7 +546,7 @@ void zebra_srv6_terminate(void) while (listcount(srv6.sid_formats)) { format = listnode_head(srv6.sid_formats); - zebra_srv6_sid_format_unregister(format); + srv6_sid_format_unregister(format); srv6_sid_format_free(format); } diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 57f9d83825ae..92e4fcf9126f 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -17,26 +17,26 @@ #include /* Default config for SRv6 SID `usid-f3216` format */ -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_NAME "usid-f3216" -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN 32 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_NODE_LEN 16 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN 16 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN 0 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_LIB_START 0xE000 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_START 0xFE00 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_ELIB_END 0xFEFF -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_START 0xFFF0 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_WLIB_END 0xFFF7 -#define ZEBRA_SRV6_SID_FORMAT_USID_F3216_EWLIB_START 0xFFF7 +#define SRV6_SID_FORMAT_USID_F3216_NAME "usid-f3216" +#define SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN 32 +#define SRV6_SID_FORMAT_USID_F3216_NODE_LEN 16 +#define SRV6_SID_FORMAT_USID_F3216_FUNCTION_LEN 16 +#define SRV6_SID_FORMAT_USID_F3216_ARGUMENT_LEN 0 +#define SRV6_SID_FORMAT_USID_F3216_LIB_START 0xE000 +#define SRV6_SID_FORMAT_USID_F3216_ELIB_START 0xFE00 +#define SRV6_SID_FORMAT_USID_F3216_ELIB_END 0xFEFF +#define SRV6_SID_FORMAT_USID_F3216_WLIB_START 0xFFF0 +#define SRV6_SID_FORMAT_USID_F3216_WLIB_END 0xFFF7 +#define SRV6_SID_FORMAT_USID_F3216_EWLIB_START 0xFFF7 /* Default config for SRv6 SID `uncompressed` format */ -#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME "uncompressed-f4024" -#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN 40 -#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN 24 -#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN 16 -#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN 0 -#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START 0xFF00 -#define ZEBRA_SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNC_UNRESERVED_MIN 0x40 +#define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME "uncompressed-f4024" +#define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN 40 +#define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN 24 +#define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNCTION_LEN 16 +#define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_ARGUMENT_LEN 0 +#define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START 0xFF00 +#define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNC_UNRESERVED_MIN 0x40 /* SRv6 instance structure. */ struct zebra_srv6 { @@ -99,8 +99,8 @@ extern int release_daemon_srv6_locator_chunks(struct zserv *client); extern void zebra_srv6_encap_src_addr_set(struct in6_addr *src_addr); extern void zebra_srv6_encap_src_addr_unset(void); -void zebra_srv6_sid_format_register(struct srv6_sid_format *format); -void zebra_srv6_sid_format_unregister(struct srv6_sid_format *format); -struct srv6_sid_format *zebra_srv6_sid_format_lookup(const char *name); +void srv6_sid_format_register(struct srv6_sid_format *format); +void srv6_sid_format_unregister(struct srv6_sid_format *format); +struct srv6_sid_format *srv6_sid_format_lookup(const char *name); #endif /* _ZEBRA_SRV6_H */ diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index ddb092247510..e5fe0d58a95e 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -68,6 +68,27 @@ static struct cmd_node srv6_encap_node = { .prompt = "%s(config-srv6-encap)# " }; +static struct cmd_node srv6_sid_formats_node = { + .name = "srv6-formats", + .node = SRV6_SID_FORMATS_NODE, + .parent_node = SRV6_NODE, + .prompt = "%s(config-srv6-formats)# ", +}; + +static struct cmd_node srv6_sid_format_usid_f3216_node = { + .name = "srv6-format-usid-f3216", + .node = SRV6_SID_FORMAT_USID_F3216_NODE, + .parent_node = SRV6_SID_FORMATS_NODE, + .prompt = "%s(config-srv6-format)# " +}; + +static struct cmd_node srv6_sid_format_uncompressed_f4024_node = { + .name = "srv6-format-uncompressed-f4024", + .node = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, + .parent_node = SRV6_SID_FORMATS_NODE, + .prompt = "%s(config-srv6-format)# " +}; + DEFPY (show_srv6_manager, show_srv6_manager_cmd, "show segment-routing srv6 manager [json]", @@ -486,11 +507,276 @@ DEFPY (no_srv6_src_addr, return CMD_SUCCESS; } +DEFUN_NOSH(srv6_sid_formats, + srv6_sid_formats_cmd, + "formats", + "Segment Routing SRv6 SID formats\n") +{ + vty->node = SRV6_SID_FORMATS_NODE; + return CMD_SUCCESS; +} + +DEFUN_NOSH (srv6_sid_format_f3216_usid, + srv6_sid_format_f3216_usid_cmd, + "format usid-f3216", + "Configure SRv6 SID format\n" + "Configure the uSID f3216 format\n") +{ + struct srv6_sid_format *format; + + format = srv6_sid_format_lookup(SRV6_SID_FORMAT_USID_F3216_NAME); + assert(format); + + VTY_PUSH_CONTEXT(SRV6_SID_FORMAT_USID_F3216_NODE, format); + return CMD_SUCCESS; +} + +DEFUN(no_srv6_sid_format_f3216_usid, + no_srv6_sid_format_f3216_usid_cmd, + "no format usid-f3216", + NO_STR + "Configure SRv6 SID format\n" + "Configure the uSID f3216 format\n") +{ + struct srv6_sid_format *format; + + format = srv6_sid_format_lookup(SRV6_SID_FORMAT_USID_F3216_NAME); + assert(format); + + format->config.usid.lib_start = SRV6_SID_FORMAT_USID_F3216_LIB_START; + format->config.usid.elib_start = SRV6_SID_FORMAT_USID_F3216_ELIB_START; + format->config.usid.elib_end = SRV6_SID_FORMAT_USID_F3216_ELIB_END; + format->config.usid.wlib_start = SRV6_SID_FORMAT_USID_F3216_WLIB_START; + format->config.usid.wlib_end = SRV6_SID_FORMAT_USID_F3216_WLIB_END; + format->config.usid.ewlib_start = SRV6_SID_FORMAT_USID_F3216_EWLIB_START; + + return CMD_SUCCESS; +} + +DEFUN_NOSH (srv6_sid_format_f4024_uncompressed, + srv6_sid_format_uncompressed_cmd, + "format uncompressed-f4024", + "Configure SRv6 SID format\n" + "Configure the uncompressed f4024 format\n") +{ + struct srv6_sid_format *format; + + format = srv6_sid_format_lookup(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME); + assert(format); + + VTY_PUSH_CONTEXT(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, format); + return CMD_SUCCESS; +} + +DEFUN(no_srv6_sid_format_f4024_uncompressed, + no_srv6_sid_format_f4024_uncompressed_cmd, + "no format uncompressed-f4024", + NO_STR + "Configure SRv6 SID format\n" + "Configure the uncompressed f4024 format\n") +{ + struct srv6_sid_format *format; + + format = srv6_sid_format_lookup(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME); + assert(format); + + format->config.uncompressed.explicit_start = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START; + + return CMD_SUCCESS; +} + +DEFPY(srv6_sid_format_usid_lib, + srv6_sid_format_usid_lib_cmd, + "local-id-block start (0-4294967295)$start", + "Configure LIB\n" + "Configure the start value for the LIB\n" + "Specify the start value for the LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + format->config.usid.lib_start = start; + + return CMD_SUCCESS; +} + +DEFPY(no_srv6_sid_format_usid_lib, + no_srv6_sid_format_usid_lib_cmd, + "no local-id-block [start (0-4294967295)]", + NO_STR + "Configure LIB\n" + "Configure the start value for the LIB\n" + "Specify the start value for the LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + if (strmatch(format->name, SRV6_SID_FORMAT_USID_F3216_NAME)) + format->config.usid.lib_start = + SRV6_SID_FORMAT_USID_F3216_LIB_START; + else + assert(0); + + return CMD_SUCCESS; +} + +DEFPY(srv6_sid_format_usid_lib_explicit, + srv6_sid_format_usid_lib_explicit_cmd, + "local-id-block explicit start (0-4294967295)$start end (0-4294967295)$end", + "Configure LIB\n" + "Configure the Explicit LIB\n" + "Configure the start value for the Explicit LIB\n" + "Specify the start value for the Explicit LIB\n" + "Configure the end value for the Explicit LIB\n" + "Specify the end value for the Explicit LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + format->config.usid.elib_start = start; + format->config.usid.elib_end = end; + + return CMD_SUCCESS; +} + +DEFPY(no_srv6_sid_format_usid_lib_explicit, + no_srv6_sid_format_usid_lib_explicit_cmd, + "no local-id-block explicit [start (0-4294967295) end (0-4294967295)]", + NO_STR + "Configure LIB\n" + "Configure the Explicit LIB\n" + "Configure the start value for the Explicit LIB\n" + "Specify the start value for the Explicit LIB\n" + "Configure the end value for the Explicit LIB\n" + "Specify the end value for the Explicit LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + if (strmatch(format->name, SRV6_SID_FORMAT_USID_F3216_NAME)) { + format->config.usid.elib_start = + SRV6_SID_FORMAT_USID_F3216_ELIB_START; + format->config.usid.elib_end = + SRV6_SID_FORMAT_USID_F3216_ELIB_END; + } else { + assert(0); + } + + return CMD_SUCCESS; +} + +DEFPY(srv6_sid_format_usid_wlib, + srv6_sid_format_usid_wlib_cmd, + "wide-local-id-block start (0-4294967295)$start end (0-4294967295)$end", + "Configure Wide LIB\n" + "Configure the start value for the Wide LIB\n" + "Specify the start value for the Wide LIB\n" + "Configure the end value for the Wide LIB\n" + "Specify the end value for the Wide LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + format->config.usid.wlib_start = start; + format->config.usid.wlib_end = end; + + return CMD_SUCCESS; +} + +DEFPY(no_srv6_sid_format_usid_wlib, + no_srv6_sid_format_usid_wlib_cmd, + "no wide-local-id-block [start (0-4294967295) end (0-4294967295)]", + NO_STR + "Configure Wide LIB\n" + "Configure the start value for the Wide LIB\n" + "Specify the start value for the Wide LIB\n" + "Configure the end value for the Wide LIB\n" + "Specify the end value for the Wide LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + if (strmatch(format->name, SRV6_SID_FORMAT_USID_F3216_NAME)) { + format->config.usid.wlib_start = + SRV6_SID_FORMAT_USID_F3216_WLIB_START; + format->config.usid.wlib_end = + SRV6_SID_FORMAT_USID_F3216_WLIB_END; + } else { + assert(0); + } + + return CMD_SUCCESS; +} + +DEFPY(srv6_sid_format_usid_wide_lib_explicit, + srv6_sid_format_usid_wide_lib_explicit_cmd, + "wide-local-id-block explicit start (0-4294967295)$start", + "Configure Wide LIB\n" + "Configure Explicit Wide LIB\n" + "Configure the start value for the Explicit Wide LIB\n" + "Specify the start value for the Explicit Wide LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + format->config.usid.ewlib_start = start; + + return CMD_SUCCESS; +} + +DEFPY(no_srv6_sid_format_usid_wide_lib_explicit, + no_srv6_sid_format_usid_wide_lib_explicit_cmd, + "no wide-local-id-block explicit [start (0-4294967295)]", + NO_STR + "Configure Wide LIB\n" + "Configure Explicit Wide LIB\n" + "Configure the start value for the Explicit Wide LIB\n" + "Specify the start value for the Explicit Wide LIB\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + if (strmatch(format->name, SRV6_SID_FORMAT_USID_F3216_NAME)) + format->config.usid.ewlib_start = + SRV6_SID_FORMAT_USID_F3216_EWLIB_START; + else + assert(0); + + return CMD_SUCCESS; +} + +DEFPY(srv6_sid_format_explicit, + srv6_sid_format_explicit_cmd, + "explicit start (0-4294967295)$start", + "Configure Explicit range\n" + "Configure the start value for the Explicit range\n" + "Specify the start value for the Explicit range\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + format->config.uncompressed.explicit_start = start; + + return CMD_SUCCESS; +} + +DEFPY(no_srv6_sid_format_explicit, + no_srv6_sid_format_explicit_cmd, + "no explicit [start (0-4294967295)$start]", + NO_STR + "Configure Explicit range\n" + "Configure the start value for the Explicit range\n" + "Specify the start value for the Explicit range\n") +{ + VTY_DECLVAR_CONTEXT(srv6_sid_format, format); + + if (strmatch(format->name, SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME)) + format->config.usid.ewlib_start = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START; + else + assert(0); + + return CMD_SUCCESS; +} + static int zebra_sr_config(struct vty *vty) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); struct listnode *node; struct srv6_locator *locator; + struct srv6_sid_format *format; char str[256]; bool display_source_srv6 = false; @@ -537,6 +823,51 @@ static int zebra_sr_config(struct vty *vty) } vty_out(vty, " exit\n"); vty_out(vty, " !\n"); + vty_out(vty, " formats\n"); + for (ALL_LIST_ELEMENTS_RO(srv6->sid_formats, node, format)) { + if (format->type == SRV6_SID_FORMAT_TYPE_UNCOMPRESSED) { + vty_out(vty, " format %s\n", format->name); + if (format->config.uncompressed.explicit_start != + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START) + vty_out(vty, " explicit start %u\n", + format->config.uncompressed + .explicit_start); + } + if (format->type == + SRV6_SID_FORMAT_TYPE_COMPRESSED_USID) { + vty_out(vty, " format %s\n", format->name); + if (format->config.usid.lib_start != + SRV6_SID_FORMAT_USID_F3216_LIB_START) + vty_out(vty, + " local-id-block start %u\n", + format->config.usid.lib_start); + if (format->config.usid.elib_start != + SRV6_SID_FORMAT_USID_F3216_ELIB_START || + format->config.usid.elib_end != + SRV6_SID_FORMAT_USID_F3216_ELIB_END) + vty_out(vty, + " local-id-block explicit start %u end %u\n", + format->config.usid.elib_start, + format->config.usid.elib_end); + if (format->config.usid.wlib_start != + SRV6_SID_FORMAT_USID_F3216_WLIB_START || + format->config.usid.wlib_end != + SRV6_SID_FORMAT_USID_F3216_WLIB_END) + vty_out(vty, + " wide-local-id-block start %u end %u\n", + format->config.usid.wlib_start, + format->config.usid.wlib_end); + if (format->config.usid.ewlib_start != + SRV6_SID_FORMAT_USID_F3216_EWLIB_START) + vty_out(vty, + " wide-local-id-block explicit start %u\n", + format->config.usid.ewlib_start); + } + vty_out(vty, " exit\n"); + vty_out(vty, " !\n"); + } + vty_out(vty, " exit\n"); + vty_out(vty, " !\n"); vty_out(vty, " exit\n"); vty_out(vty, " !\n"); } @@ -555,11 +886,17 @@ void zebra_srv6_vty_init(void) install_node(&srv6_locs_node); install_node(&srv6_loc_node); install_node(&srv6_encap_node); + install_node(&srv6_sid_formats_node); + install_node(&srv6_sid_format_usid_f3216_node); + install_node(&srv6_sid_format_uncompressed_f4024_node); install_default(SEGMENT_ROUTING_NODE); install_default(SRV6_NODE); install_default(SRV6_LOCS_NODE); install_default(SRV6_LOC_NODE); install_default(SRV6_ENCAP_NODE); + install_default(SRV6_SID_FORMATS_NODE); + install_default(SRV6_SID_FORMAT_USID_F3216_NODE); + install_default(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE); /* Command for change node */ install_element(CONFIG_NODE, &segment_routing_cmd); @@ -567,14 +904,42 @@ void zebra_srv6_vty_init(void) install_element(SEGMENT_ROUTING_NODE, &no_srv6_cmd); install_element(SRV6_NODE, &srv6_locators_cmd); install_element(SRV6_NODE, &srv6_encap_cmd); + install_element(SRV6_NODE, &srv6_sid_formats_cmd); install_element(SRV6_LOCS_NODE, &srv6_locator_cmd); install_element(SRV6_LOCS_NODE, &no_srv6_locator_cmd); + install_element(SRV6_SID_FORMATS_NODE, &srv6_sid_format_f3216_usid_cmd); + install_element(SRV6_SID_FORMATS_NODE, + &srv6_sid_format_uncompressed_cmd); + install_element(SRV6_SID_FORMATS_NODE, + &no_srv6_sid_format_f3216_usid_cmd); + install_element(SRV6_SID_FORMATS_NODE, + &no_srv6_sid_format_f4024_uncompressed_cmd); /* Command for configuration */ install_element(SRV6_LOC_NODE, &locator_prefix_cmd); install_element(SRV6_LOC_NODE, &locator_behavior_cmd); install_element(SRV6_ENCAP_NODE, &srv6_src_addr_cmd); install_element(SRV6_ENCAP_NODE, &no_srv6_src_addr_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &srv6_sid_format_usid_lib_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &no_srv6_sid_format_usid_lib_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &srv6_sid_format_usid_lib_explicit_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &no_srv6_sid_format_usid_lib_explicit_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &srv6_sid_format_usid_wlib_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &no_srv6_sid_format_usid_wlib_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &srv6_sid_format_usid_wide_lib_explicit_cmd); + install_element(SRV6_SID_FORMAT_USID_F3216_NODE, + &no_srv6_sid_format_usid_wide_lib_explicit_cmd); + install_element(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, + &srv6_sid_format_explicit_cmd); + install_element(SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE, + &no_srv6_sid_format_explicit_cmd); /* Command for operation */ install_element(VIEW_NODE, &show_srv6_locator_cmd); From bf10e4437e476c8550f4f146d34cce0828445a5e Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 22 Mar 2024 18:19:36 +0100 Subject: [PATCH 261/472] zebra: Add support for SRv6 SID blocks An SRv6 block is an IPv6 prefix from which SIDs are allocated. This commit adds support for SRv6 SID blocks. Specifically, it adds a data structure to store information about an SRv6 block (e.g., its occupancy status, which SIDs have been allocated and which are available, which SID format is used for that block, etc.). It also adds some functions to manage the block (allocate / free / lookup). These functions will be used in the next commits to support the allocation of SIDs from a block in the SID Manager. Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 191 +++++++++++++++++++++++++++++++++++++++++ zebra/zebra_srv6.h | 79 +++++++++++++++++ zebra/zebra_srv6_vty.c | 3 +- 3 files changed, 271 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 825f0f7fc214..2e5c499838d8 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -33,6 +33,10 @@ DEFINE_MGROUP(SRV6_MGR, "SRv6 Manager"); DEFINE_MTYPE_STATIC(SRV6_MGR, SRV6M_CHUNK, "SRv6 Manager Chunk"); +DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_BLOCK, "SRv6 SID block"); +DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_FUNC, "SRv6 SID function"); +DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_USID_WLIB, + "SRv6 uSID Wide LIB information"); /* define hooks for the basic API, so that it can be specialized or served * externally @@ -174,6 +178,176 @@ static struct srv6_sid_format *create_srv6_sid_format_uncompressed(void) return format; } +/* --- Zebra SRv6 SID function management functions ---------------------------- */ + +uint32_t *zebra_srv6_sid_func_alloc(uint32_t func) +{ + uint32_t *sid_func_ptr; + + sid_func_ptr = XCALLOC(MTYPE_ZEBRA_SRV6_SID_FUNC, sizeof(uint32_t)); + *sid_func_ptr = func; + + return sid_func_ptr; +} + +void zebra_srv6_sid_func_free(uint32_t *func) +{ + XFREE(MTYPE_ZEBRA_SRV6_SID_FUNC, func); +} + +/** + * Free an SRv6 SID function. + * + * @param val SRv6 SID function to be freed + */ +void delete_zebra_srv6_sid_func(void *val) +{ + zebra_srv6_sid_func_free((uint32_t *)val); +} + +/* --- Zebra SRv6 SID block management functions ---------------------------- */ + +static struct zebra_srv6_sid_block *zebra_srv6_sid_block_alloc_internal(void) +{ + struct zebra_srv6_sid_block *block = NULL; + + block = XCALLOC(MTYPE_ZEBRA_SRV6_SID_BLOCK, + sizeof(struct zebra_srv6_sid_block)); + + return block; +} + +struct zebra_srv6_sid_block * +zebra_srv6_sid_block_alloc(struct srv6_sid_format *format, + struct prefix_ipv6 *prefix) +{ + struct zebra_srv6_sid_block *block; + + block = zebra_srv6_sid_block_alloc_internal(); + block->sid_format = format; + block->prefix = *prefix; + + if (format) { + if (format->type == SRV6_SID_FORMAT_TYPE_USID) { + uint32_t wlib_start, wlib_end, func; + + /* Init uSID LIB */ + block->u.usid.lib.func_allocated = list_new(); + block->u.usid.lib.func_allocated->del = + delete_zebra_srv6_sid_func; + block->u.usid.lib.func_released = list_new(); + block->u.usid.lib.func_released->del = + delete_zebra_srv6_sid_func; + block->u.usid.lib.first_available_func = + format->config.usid.lib_start; + + /* Init uSID Wide LIB */ + wlib_start = block->sid_format->config.usid.wlib_start; + wlib_end = block->sid_format->config.usid.wlib_end; + block->u.usid.wide_lib = + XCALLOC(MTYPE_ZEBRA_SRV6_USID_WLIB, + (wlib_end - wlib_start + 1) * + sizeof(struct wide_lib)); + for (func = 0; func < wlib_end - wlib_start + 1; + func++) { + block->u.usid.wide_lib[func].func_allocated = + list_new(); + block->u.usid.wide_lib[func].func_allocated->del = + delete_zebra_srv6_sid_func; + block->u.usid.wide_lib[func].func_released = + list_new(); + block->u.usid.wide_lib[func].func_released->del = + delete_zebra_srv6_sid_func; + block->u.usid.wide_lib[func].func = func; + } + } else if (format->type == SRV6_SID_FORMAT_TYPE_UNCOMPRESSED) { + block->u.uncompressed.func_allocated = list_new(); + block->u.uncompressed.func_allocated->del = + delete_zebra_srv6_sid_func; + block->u.uncompressed.func_released = list_new(); + block->u.uncompressed.func_released->del = + delete_zebra_srv6_sid_func; + block->u.uncompressed.first_available_func = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNC_UNRESERVED_MIN; + } else { + /* We should never arrive here */ + assert(0); + } + } else { + block->u.uncompressed.func_allocated = list_new(); + block->u.uncompressed.func_allocated->del = + delete_zebra_srv6_sid_func; + block->u.uncompressed.func_released = list_new(); + block->u.uncompressed.func_released->del = + delete_zebra_srv6_sid_func; + block->u.uncompressed.first_available_func = 1; + } + + return block; +} + +void zebra_srv6_sid_block_free(struct zebra_srv6_sid_block *block) +{ + if (block->sid_format) { + if (block->sid_format->type == SRV6_SID_FORMAT_TYPE_USID) { + uint32_t wlib_start, wlib_end, func; + + /* Free uSID LIB */ + list_delete(&block->u.usid.lib.func_allocated); + list_delete(&block->u.usid.lib.func_released); + + /* Free uSID Wide LIB */ + wlib_start = block->sid_format->config.usid.wlib_start; + wlib_end = block->sid_format->config.usid.wlib_end; + for (func = 0; func < wlib_end - wlib_start + 1; + func++) { + list_delete(&block->u.usid.wide_lib[func] + .func_allocated); + list_delete(&block->u.usid.wide_lib[func] + .func_released); + } + XFREE(MTYPE_ZEBRA_SRV6_USID_WLIB, + block->u.usid.wide_lib); + } else if (block->sid_format->type == + SRV6_SID_FORMAT_TYPE_UNCOMPRESSED) { + list_delete(&block->u.uncompressed.func_allocated); + list_delete(&block->u.uncompressed.func_released); + } else { + /* We should never arrive here */ + assert(0); + } + } else { + list_delete(&block->u.uncompressed.func_allocated); + list_delete(&block->u.uncompressed.func_released); + } + + XFREE(MTYPE_ZEBRA_SRV6_SID_BLOCK, block); +} + +/** + * Free an SRv6 SID block. + * + * @param val SRv6 SID block to be freed + */ +void delete_zebra_srv6_sid_block(void *val) +{ + zebra_srv6_sid_block_free((struct zebra_srv6_sid_block *)val); +} + +struct zebra_srv6_sid_block * +zebra_srv6_sid_block_lookup(struct prefix_ipv6 *prefix) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_block *block; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(srv6->sid_blocks, node, block)) + if (prefix_match(prefix, &block->prefix)) + return block; + + return NULL; +} + void zebra_srv6_locator_add(struct srv6_locator *locator) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); @@ -324,6 +498,10 @@ struct zebra_srv6 *zebra_srv6_get_default(void) /* Create SID format `uncompressed` */ format_uncompressed = create_srv6_sid_format_uncompressed(); srv6_sid_format_register(format_uncompressed); + + /* Init list to store SRv6 SID blocks */ + srv6.sid_blocks = list_new(); + srv6.sid_blocks->del = delete_zebra_srv6_sid_block; } return &srv6; } @@ -529,6 +707,7 @@ void zebra_srv6_terminate(void) { struct srv6_locator *locator; struct srv6_sid_format *format; + struct zebra_srv6_sid_block *block; if (srv6.locators) { while (listcount(srv6.locators)) { @@ -541,6 +720,18 @@ void zebra_srv6_terminate(void) list_delete(&srv6.locators); } + /* Free SRv6 SID blocks */ + if (srv6.sid_blocks) { + while (listcount(srv6.sid_blocks)) { + block = listnode_head(srv6.sid_blocks); + + listnode_delete(srv6.sid_blocks, block); + zebra_srv6_sid_block_free(block); + } + + list_delete(&srv6.sid_blocks); + } + /* Free SRv6 SID formats */ if (srv6.sid_formats) { while (listcount(srv6.sid_formats)) { diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 92e4fcf9126f..e81d182419ef 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -38,6 +38,70 @@ #define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START 0xFF00 #define SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNC_UNRESERVED_MIN 0x40 +/* uSID Wide LIB */ +struct wide_lib { + uint32_t func; + uint32_t num_func_allocated; + uint32_t first_available_func; + struct list *func_allocated; + struct list *func_released; +}; + +/* + * SRv6 SID block. + * + * A SID block is an IPv6 prefix from which SRv6 SIDs are allocated. + * Example: + * SID block = fc00:0::/32 + * SID 1 = fc00:0:1:e000:: + * SID 2 = fc00:0:1:fe00:: + * ... + */ +struct zebra_srv6_sid_block { + /* Prefix of this block, e.g. fc00:0::/32 */ + struct prefix_ipv6 prefix; + + /* Reference counter */ + unsigned long refcnt; + + /* + * Pointer to the SID format that defines the structure of the SIDs + * allocated from this block + */ + struct zebra_srv6_sid_format *sid_format; + + /* + * Run-time information/state of this SID block. + * + * This includes stuff like how many SID functions have been allocated + * from this block, which functions are still available to be allocated + * and so on... + */ + union { + /* Information/state for compressed uSID format */ + struct { + /* uSID Local ID Block (LIB) */ + struct { + uint32_t num_func_allocated; + uint32_t first_available_func; + struct list *func_allocated; + struct list *func_released; + } lib; + + /* uSID Wide LIB */ + struct wide_lib *wide_lib; + } usid; + + /* Information/state for uncompressed SID format */ + struct { + uint32_t num_func_allocated; + uint32_t first_available_func; + struct list *func_allocated; + struct list *func_released; + } uncompressed; + } u; +}; + /* SRv6 instance structure. */ struct zebra_srv6 { struct list *locators; @@ -47,6 +111,9 @@ struct zebra_srv6 { /* SRv6 SID formats */ struct list *sid_formats; + + /* SRv6 SID blocks */ + struct list *sid_blocks; }; /* declare hooks for the basic API, so that it can be specialized or served @@ -103,4 +170,16 @@ void srv6_sid_format_register(struct srv6_sid_format *format); void srv6_sid_format_unregister(struct srv6_sid_format *format); struct srv6_sid_format *srv6_sid_format_lookup(const char *name); +uint32_t *zebra_srv6_sid_func_alloc(uint32_t func); +void zebra_srv6_sid_func_free(uint32_t *func); +void delete_zebra_srv6_sid_func(void *val); + +extern struct zebra_srv6_sid_block * +zebra_srv6_sid_block_alloc(struct zebra_srv6_sid_format *format, + struct prefix_ipv6 *prefix); +extern void zebra_srv6_sid_block_free(struct zebra_srv6_sid_block *block); +extern void delete_zebra_srv6_sid_block(void *val); +extern struct zebra_srv6_sid_block * +zebra_srv6_sid_block_lookup(struct prefix_ipv6 *prefix); + #endif /* _ZEBRA_SRV6_H */ diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index e5fe0d58a95e..963b528b8692 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -833,8 +833,7 @@ static int zebra_sr_config(struct vty *vty) format->config.uncompressed .explicit_start); } - if (format->type == - SRV6_SID_FORMAT_TYPE_COMPRESSED_USID) { + if (format->type == SRV6_SID_FORMAT_TYPE_USID) { vty_out(vty, " format %s\n", format->name); if (format->config.usid.lib_start != SRV6_SID_FORMAT_USID_F3216_LIB_START) From f00554ed563b8a4ce0cc7fff7ea107d3ae8aa6b1 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 8 May 2024 16:41:05 +0200 Subject: [PATCH 262/472] lib: Add function to copy an SRv6 locator Add a new function to copy an SRv6 locator. Signed-off-by: Carmine Scarpitta --- lib/srv6.c | 15 +++++++++++++++ lib/srv6.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/lib/srv6.c b/lib/srv6.c index abaff7eab830..1f485fb8ac8d 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -141,6 +141,21 @@ struct srv6_locator_chunk *srv6_locator_chunk_alloc(void) return chunk; } +void srv6_locator_copy(struct srv6_locator *copy, + const struct srv6_locator *locator) +{ + strlcpy(copy->name, locator->name, sizeof(locator->name)); + copy->prefix = locator->prefix; + copy->block_bits_length = locator->block_bits_length; + copy->node_bits_length = locator->node_bits_length; + copy->function_bits_length = locator->function_bits_length; + copy->argument_bits_length = locator->argument_bits_length; + copy->algonum = locator->algonum; + copy->current = locator->current; + copy->status_up = locator->status_up; + copy->flags = locator->flags; +} + void srv6_locator_free(struct srv6_locator *locator) { if (locator) { diff --git a/lib/srv6.h b/lib/srv6.h index 04f560b26780..66f1854dabda 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -311,6 +311,8 @@ extern struct srv6_locator_chunk *srv6_locator_chunk_alloc(void); extern void srv6_locator_free(struct srv6_locator *locator); extern void srv6_locator_chunk_list_free(void *data); extern void srv6_locator_chunk_free(struct srv6_locator_chunk **chunk); +extern void srv6_locator_copy(struct srv6_locator *copy, + const struct srv6_locator *locator); json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk); json_object *srv6_locator_json(const struct srv6_locator *loc); json_object *srv6_locator_detailed_json(const struct srv6_locator *loc); From 779d4c2702ac446cc4b96a1a9d2d62d1b0bbe232 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 22 Mar 2024 19:31:01 +0100 Subject: [PATCH 263/472] zebra: CLI to specify format of an SRv6 locator Add the CLI to choose the SID format of a locator. When the SID format of a locator is changed, the SIDs allocated from that locator might no longer be valid (for example, because the new format might involve a different SID allocation schema). In such a case, it is necessary to notify all the zclients so that they can withdraw/uninstall the old SIDs that use the previous format and allocate/install/advertise the new SIDs based on the new format. Signed-off-by: Carmine Scarpitta --- lib/srv6.h | 6 ++ zebra/zapi_msg.c | 18 +++- zebra/zebra_srv6.c | 133 +++++++++++++++++++++++++++ zebra/zebra_srv6.h | 7 +- zebra/zebra_srv6_vty.c | 200 ++++++++++++++++++++++++++++++++++++++--- 5 files changed, 351 insertions(+), 13 deletions(-) diff --git a/lib/srv6.h b/lib/srv6.h index 66f1854dabda..4a6ea5c72bea 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -129,6 +129,12 @@ struct srv6_locator { uint8_t flags; #define SRV6_LOCATOR_USID (1 << 0) /* The SRv6 Locator is a uSID Locator */ + /* Pointer to the SID format. */ + struct srv6_sid_format *sid_format; + + /* Pointer to the parent SID block of the locator. */ + void *sid_block; + QOBJ_FIELDS; }; DECLARE_QOBJ_TYPE(srv6_locator); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index d585ef996bf0..2d580e2972ed 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1136,9 +1136,25 @@ static int zsend_table_manager_connect_response(struct zserv *client, int zsend_zebra_srv6_locator_add(struct zserv *client, struct srv6_locator *loc) { struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); + struct srv6_locator locator = {}; + struct srv6_sid_format *format = loc->sid_format; + + /* + * Copy the locator and fill locator block/node/func/arg length from the format + * before sending the locator to the zclient + */ + srv6_locator_copy(&locator, loc); + if (format) { + locator.block_bits_length = format->block_len; + locator.node_bits_length = format->node_len; + locator.function_bits_length = format->function_len; + locator.argument_bits_length = format->argument_len; + if (format->type == ZEBRA_SRV6_SID_FORMAT_TYPE_USID) + SET_FLAG(locator.flags, SRV6_LOCATOR_USID); + } zclient_create_header(s, ZEBRA_SRV6_LOCATOR_ADD, VRF_DEFAULT); - zapi_srv6_locator_encode(s, loc); + zapi_srv6_locator_encode(s, &locator); stream_putw_at(s, 0, stream_get_endp(s)); return zserv_send_message(client, s); diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 2e5c499838d8..e6b3c2a2522a 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -126,6 +126,139 @@ struct srv6_sid_format *srv6_sid_format_lookup(const char *name) return NULL; } +/* + * Called to change the SID format of a locator. + * + * After switching the locator to a different format, the SIDs allocated + * from the locator may no longer be valid; we need to notify the + * interested zclient that the locator has changed, so that the + * zclients can withdraw/uninstall the old SIDs, allocate/advertise/program + * the new SIDs. + */ +void zebra_srv6_locator_format_set(struct srv6_locator *locator, + struct srv6_sid_format *format) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_block *block_old, *block_new; + struct prefix_ipv6 block_pfx_new; + struct listnode *node, *nnode; + struct zebra_srv6_sid_ctx *ctx; + + if (!locator) + return; + + locator->sid_format = format; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: Locator %s format has changed, old=%s new=%s", + __func__, locator->name, + locator->sid_format ? ((struct srv6_sid_format *) + locator->sid_format) + ->name + : NULL, + format ? format->name : NULL); + + /* Notify zclients that the locator is no longer valid */ + zebra_notify_srv6_locator_delete(locator); + + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, ctx)) { + if (!ctx->sid || ctx->sid->locator != locator) + continue; + + if (ctx->sid) + zebra_srv6_sid_free(ctx->sid); + + listnode_delete(srv6->sids, ctx); + zebra_srv6_sid_ctx_free(ctx); + } + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: Locator %s format has changed, send SRV6_LOCATOR_DEL notification to zclients", + __func__, locator->name); + + /* Release the current parent block */ + block_old = locator->sid_block; + if (block_old) { + block_old->refcnt--; + if (block_old->refcnt == 0) { + listnode_delete(srv6->sid_blocks, block_old); + zebra_srv6_sid_block_free(block_old); + } + } + locator->sid_block = NULL; + + block_pfx_new = locator->prefix; + if (format) + block_pfx_new.prefixlen = format->block_len; + else + block_pfx_new.prefixlen = locator->block_bits_length; + apply_mask(&block_pfx_new); + + /* Allocate the new parent block */ + block_new = zebra_srv6_sid_block_lookup(&block_pfx_new); + if (!block_new) { + block_new = zebra_srv6_sid_block_alloc(format, &block_pfx_new); + listnode_add(srv6->sid_blocks, block_new); + } + + block_new->refcnt++; + locator->sid_block = block_new; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: Locator %s format has changed, send SRV6_LOCATOR_ADD notification to zclients", + __func__, locator->name); + + /* Notify zclients about the updated locator */ + zebra_srv6_locator_add(locator); +} + +/* + * Called when a SID format is modified by the user. + * + * After modifying a SID format, the SIDs that are using that format may no + * longer be valid. + * This function walks through the list of locators that are using the SID format + * and notifies the zclients that the locator has changed, so that the zclients + * can withdraw/uninstall the old SIDs, allocate/program/advertise the new SIDs. + */ +void zebra_srv6_sid_format_changed_cb(struct srv6_sid_format *format) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct srv6_locator *locator; + struct listnode *node, *nnode; + struct zebra_srv6_sid_ctx *ctx; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: SID format %s has changed. Notifying zclients.", + __func__, format->name); + + for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) { + if (locator->sid_format == format) { + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: Locator %s has changed because its format (%s) has been modified. Notifying zclients.", + __func__, locator->name, + format->name); + + /* Notify zclients that the locator is no longer valid */ + zebra_notify_srv6_locator_delete(locator); + + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, ctx)) { + if (!ctx->sid || ctx->sid->locator != locator) + continue; + + if (ctx->sid) + zebra_srv6_sid_free(ctx->sid); + + listnode_delete(srv6->sids, ctx); + zebra_srv6_sid_ctx_free(ctx); + } + + /* Notify zclients about the updated locator */ + zebra_notify_srv6_locator_add(locator); + } + } +} + /* * Helper function to create the SRv6 compressed format `usid-f3216`. */ diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index e81d182419ef..0a8b58ce6183 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -68,7 +68,7 @@ struct zebra_srv6_sid_block { * Pointer to the SID format that defines the structure of the SIDs * allocated from this block */ - struct zebra_srv6_sid_format *sid_format; + struct srv6_sid_format *sid_format; /* * Run-time information/state of this SID block. @@ -169,13 +169,16 @@ extern void zebra_srv6_encap_src_addr_unset(void); void srv6_sid_format_register(struct srv6_sid_format *format); void srv6_sid_format_unregister(struct srv6_sid_format *format); struct srv6_sid_format *srv6_sid_format_lookup(const char *name); +void zebra_srv6_locator_format_set(struct srv6_locator *locator, + struct srv6_sid_format *format); +void zebra_srv6_sid_format_changed_cb(struct srv6_sid_format *format); uint32_t *zebra_srv6_sid_func_alloc(uint32_t func); void zebra_srv6_sid_func_free(uint32_t *func); void delete_zebra_srv6_sid_func(void *val); extern struct zebra_srv6_sid_block * -zebra_srv6_sid_block_alloc(struct zebra_srv6_sid_format *format, +zebra_srv6_sid_block_alloc(struct srv6_sid_format *format, struct prefix_ipv6 *prefix); extern void zebra_srv6_sid_block_free(struct zebra_srv6_sid_block *block); extern void delete_zebra_srv6_sid_block(void *val); diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index 963b528b8692..c664a9c69f1e 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -232,7 +232,7 @@ DEFUN (show_srv6_locator_detail, if (locator->sid_format->type == SRV6_SID_FORMAT_TYPE_USID) vty_out(vty, "Behavior: uSID\n"); - } else { + } else { vty_out(vty, "Block-Bit-Len: %u\n", locator->block_bits_length); vty_out(vty, "Node-Bit-Len: %u\n", @@ -244,7 +244,7 @@ DEFUN (show_srv6_locator_detail, if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) vty_out(vty, "Behavior: uSID\n"); - } + } vty_out(vty, "Chunks:\n"); for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node, @@ -286,9 +286,30 @@ DEFUN (no_srv6, struct zebra_srv6 *srv6 = zebra_srv6_get_default(); struct srv6_locator *locator; struct listnode *node, *nnode; + struct zebra_srv6_sid_block *block; + struct zebra_srv6_sid_ctx *ctx; + + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, ctx)) { + if (ctx->sid) + zebra_srv6_sid_free(ctx->sid); + + listnode_delete(srv6->sids, ctx); + zebra_srv6_sid_ctx_free(ctx); + } + + for (ALL_LIST_ELEMENTS(srv6->locators, node, nnode, locator)) { + block = locator->sid_block; + if (block) { + block->refcnt--; + if (block->refcnt == 0) { + listnode_delete(srv6->sid_blocks, block); + zebra_srv6_sid_block_free(block); + } + locator->sid_block = NULL; + } - for (ALL_LIST_ELEMENTS(srv6->locators, node, nnode, locator)) zebra_srv6_locator_delete(locator); + } return CMD_SUCCESS; } @@ -335,12 +356,37 @@ DEFUN (no_srv6_locator, "Segment Routing SRv6 locator\n" "Specify locator-name\n") { + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_block *block; + struct listnode *node, *nnode; + struct zebra_srv6_sid_ctx *ctx; struct srv6_locator *locator = zebra_srv6_locator_lookup(argv[2]->arg); if (!locator) { vty_out(vty, "%% Can't find SRv6 locator\n"); return CMD_WARNING_CONFIG_FAILED; } + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, ctx)) { + if (!ctx->sid || ctx->sid->locator != locator) + continue; + + if (ctx->sid) + zebra_srv6_sid_free(ctx->sid); + + listnode_delete(srv6->sids, ctx); + zebra_srv6_sid_ctx_free(ctx); + } + + block = locator->sid_block; + if (block) { + block->refcnt--; + if (block->refcnt == 0) { + listnode_delete(srv6->sid_blocks, block); + zebra_srv6_sid_block_free(block); + } + locator->sid_block = NULL; + } + zebra_srv6_locator_delete(locator); return CMD_SUCCESS; } @@ -361,14 +407,37 @@ DEFPY (locator_prefix, VTY_DECLVAR_CONTEXT(srv6_locator, locator); struct srv6_locator_chunk *chunk = NULL; struct listnode *node = NULL; + uint8_t expected_prefixlen; + struct srv6_sid_format *format; locator->prefix = *prefix; func_bit_len = func_bit_len ?: ZEBRA_SRV6_FUNCTION_LENGTH; + expected_prefixlen = prefix->prefixlen; + format = locator->sid_format; + if (format) { + if (strmatch(format->name, SRV6_SID_FORMAT_USID_F3216_NAME)) + expected_prefixlen = + SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN + + SRV6_SID_FORMAT_USID_F3216_NODE_LEN; + else if (strmatch(format->name, + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME)) + expected_prefixlen = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN + + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN; + } + + if (prefix->prefixlen != expected_prefixlen) { + vty_out(vty, + "%% Locator prefix length '%u' inconsistent with configured format '%s'. Please either use a prefix length that is consistent with the format or change the format.\n", + prefix->prefixlen, format->name); + return CMD_WARNING_CONFIG_FAILED; + } + /* Resolve optional arguments */ if (block_bit_len == 0 && node_bit_len == 0) { - block_bit_len = - prefix->prefixlen - ZEBRA_SRV6_LOCATOR_NODE_LENGTH; + block_bit_len = prefix->prefixlen - + ZEBRA_SRV6_LOCATOR_NODE_LENGTH; node_bit_len = ZEBRA_SRV6_LOCATOR_NODE_LENGTH; } else if (block_bit_len == 0) { block_bit_len = prefix->prefixlen - node_bit_len; @@ -439,7 +508,8 @@ DEFPY (locator_prefix, } } - zebra_srv6_locator_add(locator); + zebra_srv6_locator_format_set(locator, locator->sid_format); + return CMD_SUCCESS; } @@ -460,8 +530,9 @@ DEFPY (locator_behavior, /* SRv6 locator uSID flag already set, nothing to do */ return CMD_SUCCESS; - /* Remove old locator from zclients */ - zebra_notify_srv6_locator_delete(locator); + if (!locator->sid_format) + /* Remove old locator from zclients */ + zebra_notify_srv6_locator_delete(locator); /* Set/Unset the SRV6_LOCATOR_USID */ if (no) @@ -469,8 +540,75 @@ DEFPY (locator_behavior, else SET_FLAG(locator->flags, SRV6_LOCATOR_USID); - /* Notify the new locator to zclients */ - zebra_notify_srv6_locator_add(locator); + if (!locator->sid_format) + /* Notify the new locator to zclients */ + zebra_srv6_locator_add(locator); + + return CMD_SUCCESS; +} + +DEFPY(locator_sid_format, + locator_sid_format_cmd, + "format $format", + "Configure SRv6 SID format\n" + "Specify usid-f3216 format\n" + "Specify uncompressed-f4024 format\n") +{ + VTY_DECLVAR_CONTEXT(srv6_locator, locator); + struct srv6_sid_format *sid_format = NULL; + uint8_t expected_prefixlen; + + expected_prefixlen = locator->prefix.prefixlen; + if (strmatch(format, SRV6_SID_FORMAT_USID_F3216_NAME)) + expected_prefixlen = SRV6_SID_FORMAT_USID_F3216_BLOCK_LEN + + SRV6_SID_FORMAT_USID_F3216_NODE_LEN; + else if (strmatch(format, SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NAME)) + expected_prefixlen = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_BLOCK_LEN + + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_NODE_LEN; + + if (IPV6_ADDR_SAME(&locator->prefix, &in6addr_any)) { + vty_out(vty, + "%% Unexpected configuration sequence: the prefix of the locator is required before configuring the format. Please configure the prefix first and then configure the format.\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (locator->prefix.prefixlen != expected_prefixlen) { + vty_out(vty, + "%% Locator prefix length '%u' inconsistent with configured format '%s'. Please either use a prefix length that is consistent with the format or change the format.\n", + locator->prefix.prefixlen, format); + return CMD_WARNING_CONFIG_FAILED; + } + + sid_format = srv6_sid_format_lookup(format); + if (!sid_format) { + vty_out(vty, "%% Cannot find SRv6 SID format '%s'\n", format); + return CMD_WARNING_CONFIG_FAILED; + } + + if (sid_format == locator->sid_format) + /* Format has not changed, nothing to do */ + return CMD_SUCCESS; + + zebra_srv6_locator_format_set(locator, sid_format); + + return CMD_SUCCESS; +} + +DEFPY (no_locator_sid_format, + no_locator_sid_format_cmd, + "no format [WORD]", + NO_STR + "Configure SRv6 SID format\n" + "Specify SRv6 SID format\n") +{ + VTY_DECLVAR_CONTEXT(srv6_locator, locator); + + if (!locator->sid_format) + /* SID format already unset, nothing to do */ + return CMD_SUCCESS; + + zebra_srv6_locator_format_set(locator, NULL); return CMD_SUCCESS; } @@ -550,6 +688,9 @@ DEFUN(no_srv6_sid_format_f3216_usid, format->config.usid.wlib_end = SRV6_SID_FORMAT_USID_F3216_WLIB_END; format->config.usid.ewlib_start = SRV6_SID_FORMAT_USID_F3216_EWLIB_START; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -583,6 +724,9 @@ DEFUN(no_srv6_sid_format_f4024_uncompressed, format->config.uncompressed.explicit_start = SRV6_SID_FORMAT_UNCOMPRESSED_F4024_EXPLICIT_RANGE_START; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -597,6 +741,9 @@ DEFPY(srv6_sid_format_usid_lib, format->config.usid.lib_start = start; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -616,6 +763,9 @@ DEFPY(no_srv6_sid_format_usid_lib, else assert(0); + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -634,6 +784,9 @@ DEFPY(srv6_sid_format_usid_lib_explicit, format->config.usid.elib_start = start; format->config.usid.elib_end = end; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -659,6 +812,9 @@ DEFPY(no_srv6_sid_format_usid_lib_explicit, assert(0); } + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -676,6 +832,9 @@ DEFPY(srv6_sid_format_usid_wlib, format->config.usid.wlib_start = start; format->config.usid.wlib_end = end; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -700,6 +859,9 @@ DEFPY(no_srv6_sid_format_usid_wlib, assert(0); } + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -715,6 +877,9 @@ DEFPY(srv6_sid_format_usid_wide_lib_explicit, format->config.usid.ewlib_start = start; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -735,6 +900,9 @@ DEFPY(no_srv6_sid_format_usid_wide_lib_explicit, else assert(0); + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -749,6 +917,9 @@ DEFPY(srv6_sid_format_explicit, format->config.uncompressed.explicit_start = start; + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -768,6 +939,9 @@ DEFPY(no_srv6_sid_format_explicit, else assert(0); + /* Notify zclients that the format has changed */ + zebra_srv6_sid_format_changed_cb(format); + return CMD_SUCCESS; } @@ -818,6 +992,10 @@ static int zebra_sr_config(struct vty *vty) vty_out(vty, "\n"); if (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) vty_out(vty, " behavior usid\n"); + if (locator->sid_format) { + format = locator->sid_format; + vty_out(vty, " format %s\n", format->name); + } vty_out(vty, " exit\n"); vty_out(vty, " !\n"); } @@ -917,6 +1095,8 @@ void zebra_srv6_vty_init(void) /* Command for configuration */ install_element(SRV6_LOC_NODE, &locator_prefix_cmd); install_element(SRV6_LOC_NODE, &locator_behavior_cmd); + install_element(SRV6_LOC_NODE, &locator_sid_format_cmd); + install_element(SRV6_LOC_NODE, &no_locator_sid_format_cmd); install_element(SRV6_ENCAP_NODE, &srv6_src_addr_cmd); install_element(SRV6_ENCAP_NODE, &no_srv6_src_addr_cmd); install_element(SRV6_SID_FORMAT_USID_F3216_NODE, From 3cb88e69848d607a8d069b0858798e2de324fd43 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Mon, 6 May 2024 17:44:18 +0200 Subject: [PATCH 264/472] lib: Add support for SRv6 SIDs Add a data structure to represent an SRv6 SID context and the related management functions (allocate/free). Signed-off-by: Carmine Scarpitta --- lib/srv6.c | 24 ++++++++++++++++++++ lib/srv6.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/lib/srv6.c b/lib/srv6.c index 1f485fb8ac8d..883d429b621a 100644 --- a/lib/srv6.c +++ b/lib/srv6.c @@ -14,6 +14,7 @@ DEFINE_QOBJ_TYPE(srv6_sid_format); DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR, "SRV6 locator"); DEFINE_MTYPE_STATIC(LIB, SRV6_LOCATOR_CHUNK, "SRV6 locator chunk"); DEFINE_MTYPE_STATIC(LIB, SRV6_SID_FORMAT, "SRv6 SID format"); +DEFINE_MTYPE_STATIC(LIB, SRV6_SID_CTX, "SRv6 SID context"); const char *seg6local_action2str(uint32_t action) { @@ -201,6 +202,29 @@ void delete_srv6_sid_format(void *val) srv6_sid_format_free((struct srv6_sid_format *)val); } +struct srv6_sid_ctx *srv6_sid_ctx_alloc(enum seg6local_action_t behavior, + struct in_addr *nh4, + struct in6_addr *nh6, vrf_id_t vrf_id) +{ + struct srv6_sid_ctx *ctx = NULL; + + ctx = XCALLOC(MTYPE_SRV6_SID_CTX, sizeof(struct srv6_sid_ctx)); + ctx->behavior = behavior; + if (nh4) + ctx->nh4 = *nh4; + if (nh6) + ctx->nh6 = *nh6; + if (vrf_id) + ctx->vrf_id = vrf_id; + + return ctx; +} + +void srv6_sid_ctx_free(struct srv6_sid_ctx *ctx) +{ + XFREE(MTYPE_SRV6_SID_CTX, ctx); +} + json_object *srv6_locator_chunk_json(const struct srv6_locator_chunk *chunk) { json_object *jo_root = NULL; diff --git a/lib/srv6.h b/lib/srv6.h index 4a6ea5c72bea..01b082013346 100644 --- a/lib/srv6.h +++ b/lib/srv6.h @@ -246,6 +246,17 @@ struct srv6_sid_format { }; DECLARE_QOBJ_TYPE(srv6_sid_format); +/* Context for an SRv6 SID */ +struct srv6_sid_ctx { + /* Behavior associated with the SID */ + enum seg6local_action_t behavior; + + /* Behavior-specific attributes */ + struct in_addr nh4; + struct in6_addr nh6; + vrf_id_t vrf_id; +}; + static inline const char *seg6_mode2str(enum seg6_mode_t mode) { switch (mode) { @@ -309,6 +320,54 @@ const char *seg6local_context2str(char *str, size_t size, const struct seg6local_context *ctx, uint32_t action); +static inline const char *srv6_sid_ctx2str(char *str, size_t size, + const struct srv6_sid_ctx *ctx) +{ + int len = 0; + + len += snprintf(str + len, size - len, "%s", + seg6local_action2str(ctx->behavior)); + + switch (ctx->behavior) { + case ZEBRA_SEG6_LOCAL_ACTION_UNSPEC: + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END: + len += snprintf(str + len, size - len, " USP"); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_X: + case ZEBRA_SEG6_LOCAL_ACTION_END_DX6: + len += snprintfrr(str + len, size - len, " nh6 %pI6", &ctx->nh6); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_DX4: + len += snprintfrr(str + len, size - len, " nh4 %pI4", &ctx->nh4); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_T: + case ZEBRA_SEG6_LOCAL_ACTION_END_DT6: + case ZEBRA_SEG6_LOCAL_ACTION_END_DT4: + case ZEBRA_SEG6_LOCAL_ACTION_END_DT46: + len += snprintf(str + len, size - len, " vrf_id %u", + ctx->vrf_id); + break; + + case ZEBRA_SEG6_LOCAL_ACTION_END_DX2: + case ZEBRA_SEG6_LOCAL_ACTION_END_B6: + case ZEBRA_SEG6_LOCAL_ACTION_END_B6_ENCAP: + case ZEBRA_SEG6_LOCAL_ACTION_END_BM: + case ZEBRA_SEG6_LOCAL_ACTION_END_S: + case ZEBRA_SEG6_LOCAL_ACTION_END_AS: + case ZEBRA_SEG6_LOCAL_ACTION_END_AM: + case ZEBRA_SEG6_LOCAL_ACTION_END_BPF: + default: + len += snprintf(str + len, size - len, " unknown(%s)", __func__); + } + + return str; +} + int snprintf_seg6_segs(char *str, size_t size, const struct seg6_segs *segs); @@ -329,6 +388,12 @@ extern struct srv6_sid_format *srv6_sid_format_alloc(const char *name); extern void srv6_sid_format_free(struct srv6_sid_format *format); extern void delete_srv6_sid_format(void *format); +extern struct srv6_sid_ctx *srv6_sid_ctx_alloc(enum seg6local_action_t behavior, + struct in_addr *nh4, + struct in6_addr *nh6, + vrf_id_t vrf_id); +extern void srv6_sid_ctx_free(struct srv6_sid_ctx *ctx); + #ifdef __cplusplus } #endif From 8b3f3785467acc27268579d34746d504b00b800f Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 13:42:19 +0100 Subject: [PATCH 265/472] zebra: Add support for SRv6 SIDs Add a data structure to represent an SRv6 SID context and the related management functions (allocate/free). Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 98 ++++++++++++++++++++++++++++++++++++++++++ zebra/zebra_srv6.h | 105 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index e6b3c2a2522a..6e7244027486 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -37,6 +37,8 @@ DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_BLOCK, "SRv6 SID block"); DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_FUNC, "SRv6 SID function"); DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_USID_WLIB, "SRv6 uSID Wide LIB information"); +DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID, "SRv6 SID"); +DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_CTX, "SRv6 SID context"); /* define hooks for the basic API, so that it can be specialized or served * externally @@ -94,6 +96,33 @@ static int zebra_srv6_cleanup(struct zserv *client) return 0; } +/* --- Zebra SRv6 SID context management functions -------------------------- */ + +struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void) +{ + struct zebra_srv6_sid_ctx *ctx = NULL; + + ctx = XCALLOC(MTYPE_ZEBRA_SRV6_SID_CTX, + sizeof(struct zebra_srv6_sid_ctx)); + + return ctx; +} + +void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx) +{ + XFREE(MTYPE_ZEBRA_SRV6_SID_CTX, ctx); +} + +/** + * Free an SRv6 SID context. + * + * @param val SRv6 SID context to be freed + */ +void delete_zebra_srv6_sid_ctx(void *val) +{ + zebra_srv6_sid_ctx_free((struct zebra_srv6_sid_ctx *)val); +} + /* --- Zebra SRv6 SID format management functions --------------------------- */ void srv6_sid_format_register(struct srv6_sid_format *format) @@ -481,6 +510,58 @@ zebra_srv6_sid_block_lookup(struct prefix_ipv6 *prefix) return NULL; } +/* --- Zebra SRv6 SID management functions ---------------------------------- */ + +/** + * Alloc and fill an SRv6 SID. + * + * @param ctx Context associated with the SID to be created + * @param sid_value IPv6 address associated with the SID to be created + * @param locator Parent locator of the SID to be created + * @param sid_block Block from which the SID value has been allocated + * @param sid_func Function part of the SID to be created + * @param alloc_mode Allocation mode of the Function (dynamic vs explicit) + * @return The requested SID + */ +struct zebra_srv6_sid * +zebra_srv6_sid_alloc(struct zebra_srv6_sid_ctx *ctx, struct in6_addr *sid_value, + struct srv6_locator *locator, + struct zebra_srv6_sid_block *sid_block, uint32_t sid_func, + enum srv6_sid_alloc_mode alloc_mode) +{ + struct zebra_srv6_sid *sid; + + if (!ctx || !sid_value) + return NULL; + + sid = XCALLOC(MTYPE_ZEBRA_SRV6_SID, sizeof(struct zebra_srv6_sid)); + sid->ctx = ctx; + sid->value = *sid_value; + sid->locator = locator; + sid->block = sid_block; + sid->func = sid_func; + sid->alloc_mode = alloc_mode; + sid->client_list = list_new(); + + return sid; +} + +void zebra_srv6_sid_free(struct zebra_srv6_sid *sid) +{ + list_delete(&sid->client_list); + XFREE(MTYPE_ZEBRA_SRV6_SID, sid); +} + +/** + * Free an SRv6 SID. + * + * @param val SRv6 SID to be freed + */ +void delete_zebra_srv6_sid(void *val) +{ + zebra_srv6_sid_free((struct zebra_srv6_sid *)val); +} + void zebra_srv6_locator_add(struct srv6_locator *locator) { struct zebra_srv6 *srv6 = zebra_srv6_get_default(); @@ -632,6 +713,10 @@ struct zebra_srv6 *zebra_srv6_get_default(void) format_uncompressed = create_srv6_sid_format_uncompressed(); srv6_sid_format_register(format_uncompressed); + /* Init list to store SRv6 SIDs */ + srv6.sids = list_new(); + srv6.sids->del = delete_zebra_srv6_sid_ctx; + /* Init list to store SRv6 SID blocks */ srv6.sid_blocks = list_new(); srv6.sid_blocks->del = delete_zebra_srv6_sid_block; @@ -841,6 +926,7 @@ void zebra_srv6_terminate(void) struct srv6_locator *locator; struct srv6_sid_format *format; struct zebra_srv6_sid_block *block; + struct zebra_srv6_sid_ctx *sid_ctx; if (srv6.locators) { while (listcount(srv6.locators)) { @@ -853,6 +939,18 @@ void zebra_srv6_terminate(void) list_delete(&srv6.locators); } + /* Free SRv6 SIDs */ + if (srv6.sids) { + while (listcount(srv6.sids)) { + sid_ctx = listnode_head(srv6.sids); + + listnode_delete(srv6.sids, sid_ctx); + zebra_srv6_sid_ctx_free(sid_ctx); + } + + list_delete(&srv6.sids); + } + /* Free SRv6 SID blocks */ if (srv6.sid_blocks) { while (listcount(srv6.sid_blocks)) { diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 0a8b58ce6183..ad100925755f 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -102,6 +102,96 @@ struct zebra_srv6_sid_block { } u; }; +/** + * The function part of an SRv6 SID can be allocated in one + * of the following ways: + * - dynamic: allocate any available function + * - explicit: allocate a specific function + */ +enum srv6_sid_alloc_mode { + SRV6_SID_ALLOC_MODE_UNSPEC = 0, + /* Dynamic SID allocation */ + SRV6_SID_ALLOC_MODE_DYNAMIC = 1, + /* Explicit SID allocation */ + SRV6_SID_ALLOC_MODE_EXPLICIT = 2, + SRV6_SID_ALLOC_MODE_MAX = 3, +}; + +/** + * Convert SID allocation mode to string. + * + * @param alloc_mode SID allocation mode + * @return String representing the allocation mode + */ +static inline const char * +srv6_sid_alloc_mode2str(enum srv6_sid_alloc_mode alloc_mode) +{ + switch (alloc_mode) { + case SRV6_SID_ALLOC_MODE_EXPLICIT: + return "explicit"; + case SRV6_SID_ALLOC_MODE_DYNAMIC: + return "dynamic"; + case SRV6_SID_ALLOC_MODE_UNSPEC: + return "unspec"; + case SRV6_SID_ALLOC_MODE_MAX: + default: + return "unknown"; + } +} + +/* SRv6 SID instance. */ +struct zebra_srv6_sid { + /* + * SID context associated with the SID. + * Defines behavior and attributes of the SID. + */ + struct zebra_srv6_sid_ctx *ctx; + + /* SID value (e.g. fc00:0:1:e000::) */ + struct in6_addr value; + + /* Pointer to the SRv6 locator from which the SID has been allocated */ + struct srv6_locator *locator; + + /* Pointer to the SRv6 block from which the SID has been allocated */ + struct zebra_srv6_sid_block *block; + + /* + * Function part of the SID + * Example: + * SID = fc00:0:1:e000:: => func = e000 + */ + uint32_t func; + + /* SID wide function. */ + uint32_t wide_func; + + /* SID allocation mode: dynamic or explicit */ + enum srv6_sid_alloc_mode alloc_mode; + + /* List of clients that are using the SID */ + struct list *client_list; +}; + +/* + * Zebra SRv6 SID context. + * A context defines a behavior and (optionally) some behavior-specific + * attributes. Client daemons (bgp, isis, ...) ask SRv6 Manager to allocate + * a SID for a particular context. SRv6 Manager is responsible for allocating + * a SID from a given SID block and associating with the context. + * + * Example: + * bgp asks to associate a SID to the context {behavior=End.DT46 vrf=Vrf10}. + * SRv6 Manager allocate SID fc00:0:1:e000:: for that context. + */ +struct zebra_srv6_sid_ctx { + /* SRv6 SID context information. */ + struct srv6_sid_ctx ctx; + + /* SID associated with the context. */ + struct zebra_srv6_sid *sid; +}; + /* SRv6 instance structure. */ struct zebra_srv6 { struct list *locators; @@ -112,6 +202,9 @@ struct zebra_srv6 { /* SRv6 SID formats */ struct list *sid_formats; + /* SRv6 SIDs */ + struct list *sids; + /* SRv6 SID blocks */ struct list *sid_blocks; }; @@ -185,4 +278,16 @@ extern void delete_zebra_srv6_sid_block(void *val); extern struct zebra_srv6_sid_block * zebra_srv6_sid_block_lookup(struct prefix_ipv6 *prefix); +extern struct zebra_srv6_sid * +zebra_srv6_sid_alloc(struct zebra_srv6_sid_ctx *ctx, struct in6_addr *sid_value, + struct srv6_locator *locator, + struct zebra_srv6_sid_block *sid_block, uint32_t sid_func, + enum srv6_sid_alloc_mode alloc_mode); +extern void zebra_srv6_sid_free(struct zebra_srv6_sid *sid); +extern void delete_zebra_srv6_sid(void *val); + +extern struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void); +extern void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx); +extern void delete_zebra_srv6_sid_ctx(void *val); + #endif /* _ZEBRA_SRV6_H */ From ded79d7013f00a61b19e029a5104b453f696253a Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 15:49:43 +0100 Subject: [PATCH 266/472] lib: Add ZAPI operation get SRv6 locator Add a new ZAPI operation, ZEBRA_SRV6_MANAGER_GET_LOCATOR, which allows a daemon to request information about a specific locator from the SRv6 SID Manager. Signed-off-by: Carmine Scarpitta --- lib/log.c | 1 + lib/zclient.c | 41 +++++++++++++++++++++++++++++++++++++++++ lib/zclient.h | 3 +++ 3 files changed, 45 insertions(+) diff --git a/lib/log.c b/lib/log.c index 969ca7925660..427e72703c16 100644 --- a/lib/log.c +++ b/lib/log.c @@ -436,6 +436,7 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_SRV6_LOCATOR_DELETE), DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK), DESC_ENTRY(ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK), + DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_LOCATOR), DESC_ENTRY(ZEBRA_ERROR), DESC_ENTRY(ZEBRA_CLIENT_CAPABILITIES), DESC_ENTRY(ZEBRA_OPAQUE_MESSAGE), diff --git a/lib/zclient.c b/lib/zclient.c index 1aab7b48ba8f..90ec02415561 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -3268,6 +3268,47 @@ int srv6_manager_release_locator_chunk(struct zclient *zclient, return zclient_send_message(zclient); } +/** + * Function to request a SRv6 locator in an asynchronous way + * + * @param zclient The zclient used to connect to SRv6 Manager (zebra) + * @param locator_name Name of SRv6 locator + * @return 0 on success, -1 otherwise + */ +int srv6_manager_get_locator(struct zclient *zclient, const char *locator_name) +{ + struct stream *s; + size_t len; + + if (!locator_name) + return -1; + + if (zclient->sock < 0) { + flog_err(EC_LIB_ZAPI_SOCKET, "%s: invalid zclient socket", + __func__); + return -1; + } + + if (zclient_debug) + zlog_debug("Getting SRv6 Locator %s", locator_name); + + len = strlen(locator_name); + + /* Send request */ + s = zclient->obuf; + stream_reset(s); + zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_LOCATOR, VRF_DEFAULT); + + /* Locator name */ + stream_putw(s, len); + stream_put(s, locator_name, len); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + return zclient_send_message(zclient); +} + /* * Asynchronous label chunk request * diff --git a/lib/zclient.h b/lib/zclient.h index 3759f94542ea..87617003d8f2 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -209,6 +209,7 @@ typedef enum { ZEBRA_SRV6_LOCATOR_DELETE, ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK, + ZEBRA_SRV6_MANAGER_GET_LOCATOR, ZEBRA_ERROR, ZEBRA_CLIENT_CAPABILITIES, ZEBRA_OPAQUE_MESSAGE, @@ -1074,6 +1075,8 @@ extern int srv6_manager_get_locator_chunk(struct zclient *zclient, const char *locator_name); extern int srv6_manager_release_locator_chunk(struct zclient *zclient, const char *locator_name); +extern int srv6_manager_get_locator(struct zclient *zclient, + const char *locator_name); extern enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd, From ee1d20879b0cb44abb77954190a55a07e1921435 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 18:31:12 +0100 Subject: [PATCH 267/472] lib: Add ZAPI operations to get/release SRv6 SIDs Add two new ZAPI operations: `ZEBRA_SRV6_MANAGER_GET_SRV6_SID` and `ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID`. These APIs allow a daemon to get and release an SRv6 SID, respectively. Signed-off-by: Carmine Scarpitta --- lib/log.c | 2 + lib/zclient.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/zclient.h | 13 +++++++ 3 files changed, 118 insertions(+) diff --git a/lib/log.c b/lib/log.c index 427e72703c16..fa8a8734a4e7 100644 --- a/lib/log.c +++ b/lib/log.c @@ -437,6 +437,8 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK), DESC_ENTRY(ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK), DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_LOCATOR), + DESC_ENTRY(ZEBRA_SRV6_MANAGER_GET_SRV6_SID), + DESC_ENTRY(ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID), DESC_ENTRY(ZEBRA_ERROR), DESC_ENTRY(ZEBRA_CLIENT_CAPABILITIES), DESC_ENTRY(ZEBRA_OPAQUE_MESSAGE), diff --git a/lib/zclient.c b/lib/zclient.c index 90ec02415561..8308215de987 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -3309,6 +3309,109 @@ int srv6_manager_get_locator(struct zclient *zclient, const char *locator_name) return zclient_send_message(zclient); } +/** + * Function to request an SRv6 SID in an asynchronous way + * + * @param zclient The zclient used to connect to SRv6 manager (zebra) + * @param ctx Context associated with the SRv6 SID + * @param sid_value SRv6 SID value for explicit SID allocation + * @param locator_name Name of the parent locator for dynamic SID allocation + * @param sid_func SID function assigned by the SRv6 Manager + * @result 0 on success, -1 otherwise + */ +int srv6_manager_get_sid(struct zclient *zclient, const struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, const char *locator_name, + uint32_t *sid_func) +{ + struct stream *s; + uint8_t flags = 0; + size_t len; + char buf[256]; + + if (zclient->sock < 0) { + flog_err(EC_LIB_ZAPI_SOCKET, "%s: invalid zclient socket", + __func__); + return ZCLIENT_SEND_FAILURE; + } + + if (zclient_debug) + zlog_debug("Getting SRv6 SID: %s", + srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + /* send request */ + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_SRV6_MANAGER_GET_SRV6_SID, VRF_DEFAULT); + + /* Context associated with the SRv6 SID */ + stream_put(s, ctx, sizeof(struct srv6_sid_ctx)); + + /* Flags */ + if (!sid_zero_ipv6(sid_value)) + SET_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_SID_VALUE); + if (locator_name) + SET_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_LOCATOR); + stream_putc(s, flags); + + /* SRv6 SID value */ + if (CHECK_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_SID_VALUE)) + stream_put(s, sid_value, sizeof(struct in6_addr)); + + /* SRv6 locator */ + if (CHECK_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_LOCATOR)) { + len = strlen(locator_name); + stream_putw(s, len); + stream_put(s, locator_name, len); + } + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + /* Send the request to SRv6 Manager */ + return zclient_send_message(zclient); +} + +/** + * Function to release an SRv6 SID + * + * @param zclient Zclient used to connect to SRv6 manager (zebra) + * @param ctx Context associated with the SRv6 SID to be removed + * @result 0 on success, -1 otherwise + */ +int srv6_manager_release_sid(struct zclient *zclient, + const struct srv6_sid_ctx *ctx) +{ + struct stream *s; + char buf[256]; + + if (zclient->sock < 0) { + flog_err(EC_LIB_ZAPI_SOCKET, "%s: invalid zclient socket", + __func__); + return -1; + } + + if (zclient_debug) + zlog_debug("Releasing SRv6 SID: %s", + srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + /* send request */ + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID, + VRF_DEFAULT); + + /* Context associated with the SRv6 SID */ + stream_put(s, ctx, sizeof(struct srv6_sid_ctx)); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + /* Send the SID release message */ + return zclient_send_message(zclient); +} + /* * Asynchronous label chunk request * diff --git a/lib/zclient.h b/lib/zclient.h index 87617003d8f2..bb527f0b41b6 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -210,6 +210,8 @@ typedef enum { ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK, ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK, ZEBRA_SRV6_MANAGER_GET_LOCATOR, + ZEBRA_SRV6_MANAGER_GET_SRV6_SID, + ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID, ZEBRA_ERROR, ZEBRA_CLIENT_CAPABILITIES, ZEBRA_OPAQUE_MESSAGE, @@ -1071,12 +1073,23 @@ extern int tm_get_table_chunk(struct zclient *zclient, uint32_t chunk_size, uint32_t *start, uint32_t *end); extern int tm_release_table_chunk(struct zclient *zclient, uint32_t start, uint32_t end); + +/* Zebra SRv6 Manager flags */ +#define ZAPI_SRV6_MANAGER_SID_FLAG_HAS_SID_VALUE 0x01 +#define ZAPI_SRV6_MANAGER_SID_FLAG_HAS_LOCATOR 0x02 + extern int srv6_manager_get_locator_chunk(struct zclient *zclient, const char *locator_name); extern int srv6_manager_release_locator_chunk(struct zclient *zclient, const char *locator_name); extern int srv6_manager_get_locator(struct zclient *zclient, const char *locator_name); +extern int srv6_manager_get_sid(struct zclient *zclient, + const struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, + const char *locator_name, uint32_t *sid_func); +extern int srv6_manager_release_sid(struct zclient *zclient, + const struct srv6_sid_ctx *ctx); extern enum zclient_send_status zebra_send_sr_policy(struct zclient *zclient, int cmd, From 164117f2ec3d85c7ed63bb81413fb0d28651bc84 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Mon, 6 May 2024 17:46:44 +0200 Subject: [PATCH 268/472] lib: Add missing info to locator encode/decode Include block/node/function/argument lengthi when encoding/decoding an SRv6 locator. Signed-off-by: Carmine Scarpitta --- lib/zclient.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/zclient.c b/lib/zclient.c index 8308215de987..b0e97b0f126c 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1125,6 +1125,10 @@ int zapi_srv6_locator_encode(struct stream *s, const struct srv6_locator *l) stream_put(s, l->name, strlen(l->name)); stream_putw(s, l->prefix.prefixlen); stream_put(s, &l->prefix.prefix, sizeof(l->prefix.prefix)); + stream_putc(s, l->block_bits_length); + stream_putc(s, l->node_bits_length); + stream_putc(s, l->function_bits_length); + stream_putc(s, l->argument_bits_length); stream_putc(s, l->flags); return 0; } @@ -1141,6 +1145,10 @@ int zapi_srv6_locator_decode(struct stream *s, struct srv6_locator *l) STREAM_GETW(s, l->prefix.prefixlen); STREAM_GET(&l->prefix.prefix, s, sizeof(l->prefix.prefix)); l->prefix.family = AF_INET6; + STREAM_GETC(s, l->block_bits_length); + STREAM_GETC(s, l->node_bits_length); + STREAM_GETC(s, l->function_bits_length); + STREAM_GETC(s, l->argument_bits_length); STREAM_GETC(s, l->flags); return 0; From f8da4a29e58ec301c72a17f238686a59b62edef0 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 15:50:24 +0100 Subject: [PATCH 269/472] zebra: Repond to `GET_LOCATOR` ZAPI request The previous commits introduced a new operation, `ZEBRA_SRV6_MANAGER_GET_LOCATOR`, allowing a daemon to request information about a specific SRv6 locator from the SRv6 SID Manager. This commit extends the SID Manager to respond to a `ZEBRA_SRV6_MANAGER_GET_LOCATOR` request and provide the requested locator information. Signed-off-by: Carmine Scarpitta --- zebra/zapi_msg.c | 29 +++++++++++++++++++++++++++++ zebra/zapi_msg.h | 3 +++ zebra/zebra_srv6.c | 37 +++++++++++++++++++++++++++++++++++++ zebra/zebra_srv6.h | 8 ++++++++ 4 files changed, 77 insertions(+) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 2d580e2972ed..21c18a144594 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3006,6 +3006,31 @@ static void zread_srv6_manager_release_locator_chunk(struct zserv *client, return; } +/** + * Handle SRv6 locator get request received from a client daemon protocol. + * + * @param client The client zapi session + * @param msg The request message + */ +static void zread_srv6_manager_get_locator(struct zserv *client, + struct stream *msg) +{ + struct stream *s = msg; + uint16_t len; + char locator_name[SRV6_LOCNAME_SIZE] = { 0 }; + struct srv6_locator *locator = NULL; + + /* Get data */ + STREAM_GETW(s, len); + STREAM_GET(locator_name, s, len); + + /* Call hook to get the locator info using wrapper */ + srv6_manager_get_locator_call(&locator, client, locator_name); + +stream_failure: + return; +} + static void zread_srv6_manager_request(ZAPI_HANDLER_ARGS) { switch (hdr->command) { @@ -3017,6 +3042,9 @@ static void zread_srv6_manager_request(ZAPI_HANDLER_ARGS) zread_srv6_manager_release_locator_chunk(client, msg, zvrf_id(zvrf)); break; + case ZEBRA_SRV6_MANAGER_GET_LOCATOR: + zread_srv6_manager_get_locator(client, msg); + break; default: zlog_err("%s: unknown SRv6 Manager command", __func__); break; @@ -3965,6 +3993,7 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_MLAG_FORWARD_MSG] = zebra_mlag_forward_client_msg, [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] = zread_srv6_manager_request, [ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK] = zread_srv6_manager_request, + [ZEBRA_SRV6_MANAGER_GET_LOCATOR] = zread_srv6_manager_request, [ZEBRA_CLIENT_CAPABILITIES] = zread_client_capabilities, [ZEBRA_NEIGH_DISCOVER] = zread_neigh_discover, [ZEBRA_NHG_ADD] = zread_nhg_add, diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 43f734d26e6d..c7123e2593f2 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -110,6 +110,9 @@ extern int zsend_zebra_srv6_locator_delete(struct zserv *client, extern int zsend_srv6_manager_get_locator_chunk_response(struct zserv *client, vrf_id_t vrf_id, struct srv6_locator *loc); +extern int zsend_srv6_manager_get_locator_response(struct zserv *client, + struct srv6_locator *locator); + #ifdef __cplusplus } #endif diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 6e7244027486..0217be8c7f55 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -61,6 +61,11 @@ DEFINE_HOOK(srv6_manager_release_chunk, vrf_id_t vrf_id), (client, locator_name, vrf_id)); +DEFINE_HOOK(srv6_manager_get_locator, + (struct srv6_locator **locator, struct zserv *client, + const char *locator_name), + (locator, client, locator_name)); + /* define wrappers to be called in zapi_msg.c (as hooks must be called in * source file where they were defined) */ @@ -91,6 +96,13 @@ int srv6_manager_client_disconnect_cb(struct zserv *client) return 0; } +void srv6_manager_get_locator_call(struct srv6_locator **locator, + struct zserv *client, + const char *locator_name) +{ + hook_call(srv6_manager_get_locator, locator, client, locator_name); +} + static int zebra_srv6_cleanup(struct zserv *client) { return 0; @@ -921,6 +933,28 @@ void zebra_srv6_encap_src_addr_unset(void) memset(&srv6->encap_src_addr, 0, sizeof(struct in6_addr)); } +/** + * Handle a get SRv6 Locator request received from a client. + * + * It looks up the requested locator and send it to the client. + * + * @param locator SRv6 locator returned by this function + * @param client The client that sent the Get SRv6 Locator request + * @param locator_name Name of the locator to look up + * + * @return 0 on success + */ +static int srv6_manager_get_srv6_locator_internal(struct srv6_locator **locator, + struct zserv *client, + const char *locator_name) +{ + *locator = zebra_srv6_locator_lookup(locator_name); + if (!*locator) + return -1; + + return zsend_zebra_srv6_locator_add(client, *locator); +} + void zebra_srv6_terminate(void) { struct srv6_locator *locator; @@ -983,6 +1017,9 @@ void zebra_srv6_init(void) zebra_srv6_manager_get_locator_chunk); hook_register(srv6_manager_release_chunk, zebra_srv6_manager_release_locator_chunk); + + hook_register(srv6_manager_get_locator, + srv6_manager_get_srv6_locator_internal); } bool zebra_srv6_is_enable(void) diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index ad100925755f..681789e4aca9 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -231,6 +231,10 @@ DECLARE_HOOK(srv6_manager_release_chunk, vrf_id_t vrf_id), (client, locator_name, vrf_id)); +DECLARE_HOOK(srv6_manager_get_locator, + (struct srv6_locator **locator, struct zserv *client, + const char *locator_name), + (locator, client, locator_name)); extern void zebra_srv6_locator_add(struct srv6_locator *locator); extern void zebra_srv6_locator_delete(struct srv6_locator *locator); @@ -286,6 +290,10 @@ zebra_srv6_sid_alloc(struct zebra_srv6_sid_ctx *ctx, struct in6_addr *sid_value, extern void zebra_srv6_sid_free(struct zebra_srv6_sid *sid); extern void delete_zebra_srv6_sid(void *val); +extern void srv6_manager_get_locator_call(struct srv6_locator **locator, + struct zserv *client, + const char *locator_name); + extern struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void); extern void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx); extern void delete_zebra_srv6_sid_ctx(void *val); From c570d2bcaec477167d613d1b2bf57021200d1f89 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 16:30:58 +0100 Subject: [PATCH 270/472] zebra: Add functions to alloc/release SRv6 SIDs Add functions to allocate/release SRv6 SIDs. SIDs can be allocated either explicitly (allocate a specific SID) or dynamically (allocate any available SID). Signed-off-by: Carmine Scarpitta --- zebra/zapi_msg.c | 2 +- zebra/zebra_errors.c | 12 + zebra/zebra_errors.h | 2 + zebra/zebra_srv6.c | 1270 ++++++++++++++++++++++++++++++++++++++++++ zebra/zebra_srv6.h | 5 + 5 files changed, 1290 insertions(+), 1 deletion(-) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 21c18a144594..52ee0876896a 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1149,7 +1149,7 @@ int zsend_zebra_srv6_locator_add(struct zserv *client, struct srv6_locator *loc) locator.node_bits_length = format->node_len; locator.function_bits_length = format->function_len; locator.argument_bits_length = format->argument_len; - if (format->type == ZEBRA_SRV6_SID_FORMAT_TYPE_USID) + if (format->type == SRV6_SID_FORMAT_TYPE_USID) SET_FLAG(locator.flags, SRV6_LOCATOR_USID); } diff --git a/zebra/zebra_errors.c b/zebra/zebra_errors.c index 09b369e23eaf..dcfa37d268cb 100644 --- a/zebra/zebra_errors.c +++ b/zebra/zebra_errors.c @@ -787,6 +787,18 @@ static struct log_ref ferr_zebra_err[] = { .suggestion = "Wait for Zebra to reattempt update.", }, + { + .code = EC_ZEBRA_SM_CANNOT_ASSIGN_SID, + .title = "SRv6 manager unable to assign SID", + .description = "Zebra's SRv6 manager was unable to assign a SID to client.", + .suggestion = "Ensure that Zebra has a sufficient SID range available.", + }, + { + .code = EC_ZEBRA_SM_DAEMON_MISMATCH, + .title = "Daemon mismatch when releasing SRV6 SIDs", + .description = "Zebra noticed a mismatch between a SRv6 SID and a protocol daemon number or instance when releasing unused SRv6 SIDs.", + .suggestion = "Ignore this error.", + }, { .code = END_FERR, } diff --git a/zebra/zebra_errors.h b/zebra/zebra_errors.h index 3ac654bda5c3..84632e1ad5c1 100644 --- a/zebra/zebra_errors.h +++ b/zebra/zebra_errors.h @@ -124,6 +124,8 @@ enum zebra_log_refs { EC_ZEBRA_GRE_SET_UPDATE, EC_ZEBRA_SRV6M_UNRELEASED_LOCATOR_CHUNK, EC_ZEBRA_INTF_UPDATE_FAILURE, + EC_ZEBRA_SM_CANNOT_ASSIGN_SID, + EC_ZEBRA_SM_DAEMON_MISMATCH, }; void zebra_error_init(void); diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 0217be8c7f55..047422b9e33f 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -40,6 +40,10 @@ DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_USID_WLIB, DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID, "SRv6 SID"); DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_CTX, "SRv6 SID context"); +/* Prototypes */ +static int release_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, + uint32_t sid_func); + /* define hooks for the basic API, so that it can be specialized or served * externally */ @@ -933,6 +937,1272 @@ void zebra_srv6_encap_src_addr_unset(void) memset(&srv6->encap_src_addr, 0, sizeof(struct in6_addr)); } +/* --- SRv6 SID Allocation/Release functions -------------------------------- */ + +/** + * Return the SRv6 SID obtained composing the locator and function. + * + * @param sid_value SRv6 SID address returned + * @param locator Parent locator of the SRv6 SID + * @param sid_func Function part of the SID + * @return True if success, False otherwise + */ +static bool zebra_srv6_sid_compose(struct in6_addr *sid_value, + struct srv6_locator *locator, + uint32_t sid_func) +{ + uint8_t offset, func_len; + struct srv6_sid_format *format = locator->sid_format; + + if (!sid_value || !locator) + return false; + + if (format) { + offset = format->block_len + format->node_len; + func_len = format->function_len; + } else { + offset = locator->block_bits_length + locator->node_bits_length; + func_len = locator->function_bits_length; + } + + *sid_value = locator->prefix.prefix; + for (uint8_t idx = 0; idx < func_len; idx++) { + uint8_t tidx = offset + idx; + + sid_value->s6_addr[tidx / 8] &= ~(0x1 << (7 - tidx % 8)); + if (sid_func >> (func_len - 1 - idx) & 0x1) + sid_value->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8); + } + + return true; +} + +/** + * Return the parent locator and function of an SRv6 SID. + * + * @param sid_value SRv6 SID address to be decomposed + * @param sid_block Parent block of the SRv6 SID + * @param locator Parent locator of the SRv6 SID + * @param sid_func Function part of the SID + * @param sid_wide_func Wide function of the SID + * @return True if success, False otherwise + */ +static bool zebra_srv6_sid_decompose(struct in6_addr *sid_value, + struct zebra_srv6_sid_block **sid_block, + struct srv6_locator **locator, + uint32_t *sid_func, uint32_t *sid_wide_func) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct srv6_locator *l; + struct zebra_srv6_sid_block *b; + struct srv6_sid_format *format; + struct listnode *node; + struct prefix_ipv6 tmp_prefix; + uint8_t offset, func_len; + + if (!sid_value || !sid_func) + return false; + + *sid_func = 0; + *sid_wide_func = 0; + + /* + * Build a temporary prefix_ipv6 object representing the SRv6 SID. + * This temporary prefix object is used below by the prefix_match + * function to check if the SID belongs to a specific locator. + */ + tmp_prefix.family = AF_INET6; + tmp_prefix.prefixlen = IPV6_MAX_BITLEN; + tmp_prefix.prefix = *sid_value; + + /* + * Lookup the parent locator of the SID and return the locator and + * the function of the SID. + */ + for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, l)) { + /* + * Check if the locator prefix includes the temporary prefix + * representing the SID. + */ + if (prefix_match((struct prefix *)&l->prefix, + (struct prefix *)&tmp_prefix)) { + format = l->sid_format; + + if (format) { + offset = format->block_len + format->node_len; + func_len = format->function_len; + } else { + offset = l->block_bits_length + + l->node_bits_length; + func_len = l->function_bits_length; + } + + for (uint8_t idx = 0; idx < func_len; idx++) { + uint8_t tidx = offset + idx; + *sid_func |= (sid_value->s6_addr[tidx / 8] & + (0x1 << (7 - tidx % 8))) + << (((func_len - 1 - idx) / 8) * 8); + } + + /* + * If function comes from the Wide LIB range, we also + * need to get the Wide function. + */ + if (format && format->type == SRV6_SID_FORMAT_TYPE_USID) { + if (*sid_func >= format->config.usid.wlib_start && + *sid_func <= format->config.usid.wlib_end) { + format = l->sid_format; + + offset = format->block_len + + format->node_len + + format->function_len; + + for (uint8_t idx = 0; idx < 16; idx++) { + uint8_t tidx = offset + idx; + *sid_wide_func |= + (sid_value->s6_addr[tidx / + 8] & + (0x1 << (7 - tidx % 8))) + << (((16 - 1 - idx) / 8) * + 8); + } + } + } + + *locator = l; + *sid_block = l->sid_block; + + return true; + } + } + + /* + * If we arrive here, the SID does not belong to any locator. + * Then, let's try to find the parent block from which the SID + * has been allocated. + */ + + /* + * Lookup the parent block of the SID and return the block and + * the function of the SID. + */ + for (ALL_LIST_ELEMENTS_RO(srv6->sid_blocks, node, b)) { + /* + * Check if the block prefix includes the temporary prefix + * representing the SID + */ + if (prefix_match((struct prefix *)&b->prefix, + (struct prefix *)&tmp_prefix)) { + format = b->sid_format; + + if (!format) + continue; + + offset = format->block_len + format->node_len; + func_len = format->function_len; + + for (uint8_t idx = 0; idx < func_len; idx++) { + uint8_t tidx = offset + idx; + *sid_func |= (sid_value->s6_addr[tidx / 8] & + (0x1 << (7 - tidx % 8))) + << ((func_len - 1 - idx) / 8); + } + + /* + * If function comes from the Wide LIB range, we also + * need to get the Wide function. + */ + if (*sid_func >= format->config.usid.wlib_start && + *sid_func <= format->config.usid.wlib_end) { + format = b->sid_format; + + offset = format->block_len + format->node_len + + format->function_len; + + for (uint8_t idx = 0; idx < 16; idx++) { + uint8_t tidx = offset + idx; + *sid_wide_func |= + (sid_value->s6_addr[tidx / 8] & + (0x1 << (7 - tidx % 8))) + << (((16 - 1 - idx) / 8) * 8); + } + } + + *sid_block = b; + + return true; + } + } + + return false; +} + +/** + * Allocate an explicit SID function (i.e. specific SID function value) from a given SID block. + * + * @param block SRv6 SID block from which the SID function has to be allocated + * @param sid_func SID function to be allocated + * @param sid_wide_func SID wide function to be allocated + * + * @return true on success, false otherwise + */ +static bool alloc_srv6_sid_func_explicit(struct zebra_srv6_sid_block *block, + uint32_t sid_func, + uint32_t sid_wide_func) +{ + struct srv6_sid_format *format; + struct listnode *node; + uint32_t *sid_func_ptr = NULL; + + if (!block) + return false; + + format = block->sid_format; + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: trying to allocate explicit SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + + /* + * Allocate SID function from the corresponding range depending on the SID format type + */ + if (format) { + if (format->type == SRV6_SID_FORMAT_TYPE_USID) { + uint32_t elib_start = format->config.usid.elib_start; + uint32_t elib_end = format->config.usid.elib_end; + uint32_t wlib_end = format->config.usid.wlib_end; + uint32_t ewlib_start = format->config.usid.ewlib_start; + uint32_t ewlib_end = wlib_end; + uint32_t *sid_wide_func_ptr = NULL; + + /* Figure out the range from which the SID function has been allocated and release it */ + if ((sid_func >= elib_start) && (sid_func <= elib_end)) { + /* The SID function has to be allocated from the ELIB range */ + + /* Ensure that the requested SID function has not already been taken */ + for (ALL_LIST_ELEMENTS_RO(block->u.usid.lib + .func_allocated, + node, sid_func_ptr)) + if (*sid_func_ptr == sid_func) + break; + + if (sid_func_ptr) { + zlog_err("%s: invalid SM request arguments: SID function %u already taken", + __func__, sid_func); + return false; + } + + /* + * Mark the SID function as "taken" by adding it to the "func_allocated" list and + * increase the counter of function allocated + */ + sid_func_ptr = + zebra_srv6_sid_func_alloc(sid_func); + listnode_add(block->u.usid.lib.func_allocated, + sid_func_ptr); + block->u.usid.lib.num_func_allocated++; + } else if ((sid_func >= ewlib_start) && + (sid_func <= ewlib_end)) { + /* The SID function has to be allocated from the EWLIB range */ + + /* Ensure that the requested SID function has not already been taken */ + for (ALL_LIST_ELEMENTS_RO(block->u.usid + .wide_lib[sid_func] + .func_allocated, + node, + sid_wide_func_ptr)) + if (*sid_wide_func_ptr == sid_wide_func) + break; + + if (sid_wide_func_ptr) { + zlog_err("%s: invalid SM request arguments: SID function %u already taken", + __func__, sid_func); + return false; + } + + /* + * Mark the SID function as "taken" by adding it to the "func_allocated" list and + * increase the counter of function allocated + */ + sid_wide_func_ptr = zebra_srv6_sid_func_alloc( + sid_wide_func); + listnode_add(block->u.usid.wide_lib[sid_func] + .func_allocated, + sid_wide_func_ptr); + block->u.usid.wide_lib[sid_func] + .num_func_allocated++; + } else { + zlog_warn("%s: function %u is outside ELIB [%u/%u] and EWLIB alloc ranges [%u/%u]", + __func__, sid_func, elib_start, + elib_end, ewlib_start, ewlib_end); + return -1; + } + } else if (format->type == SRV6_SID_FORMAT_TYPE_UNCOMPRESSED) { + uint32_t explicit_start = + format->config.uncompressed.explicit_start; + uint32_t explicit_end = + (uint32_t)((1 << format->function_len) - 1); + + /* Ensure that the SID function comes from the Explicit range */ + if (!(sid_func >= explicit_start && + sid_func <= explicit_end)) { + zlog_err("%s: invalid SM request arguments: SID function %u out of explicit range (%u - %u)", + __func__, sid_func, explicit_start, + explicit_end); + return false; + } + + /* Ensure that the SID function has not already been taken */ + + for (ALL_LIST_ELEMENTS_RO(block->u.uncompressed + .func_allocated, + node, sid_func_ptr)) + if (*sid_func_ptr == sid_func) + break; + + /* SID function already taken */ + if (sid_func_ptr) { + zlog_err("%s: invalid SM request arguments: SID function %u already taken", + __func__, sid_func); + return false; + } + + /* + * Mark the SID function as "taken" by adding it to the "func_allocated" list and + * increase the counter of function allocated + */ + sid_func_ptr = zebra_srv6_sid_func_alloc(sid_func); + listnode_add(block->u.uncompressed.func_allocated, + sid_func_ptr); + block->u.uncompressed.num_func_allocated++; + } else { + /* We should never arrive here */ + zlog_err("%s: unknown SID format type: %u", __func__, + format->type); + assert(0); + } + } else { + /* Ensure that the SID function has not already been taken */ + + for (ALL_LIST_ELEMENTS_RO(block->u.uncompressed.func_allocated, + node, sid_func_ptr)) + if (*sid_func_ptr == sid_func) + break; + + /* SID function already taken */ + if (sid_func_ptr) { + zlog_err("%s: invalid SM request arguments: SID function %u already taken", + __func__, sid_func); + return false; + } + + /* + * Mark the SID function as "taken" by adding it to the "func_allocated" list and + * increase the counter of function allocated + */ + sid_func_ptr = zebra_srv6_sid_func_alloc(sid_func); + listnode_add(block->u.uncompressed.func_allocated, sid_func_ptr); + block->u.uncompressed.num_func_allocated++; + } + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: allocated explicit SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + + return true; +} + +/** + * Allocate a dynamic SID function (i.e. any available SID function value) from a given SID block. + * + * @param block SRv6 SID block from which the SID function has to be allocated + * @param sid_func SID function allocated + * + * @return true on success, false otherwise + */ +static bool alloc_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, + uint32_t *sid_func) +{ + struct srv6_sid_format *format; + uint32_t *sid_func_ptr = NULL; + + if (!block || !sid_func) + return false; + + format = block->sid_format; + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: trying to allocate dynamic SID function from block %pFX", + __func__, &block->prefix); + + /* + * Allocate SID function from the corresponding range depending on the SID format type + */ + if (format) { + if (format->type == SRV6_SID_FORMAT_TYPE_USID) { + /* Format is uSID and behavior => allocate SID function from LIB range */ + + /* The Dynamic LIB range ends where the Explicit LIB range begins */ + uint32_t dlib_end = format->config.usid.elib_start - 1; + + /* Check if we ran out of available SID functions */ + if (block->u.usid.lib.first_available_func > dlib_end) { + zlog_warn("%s: SRv6: Warning, SRv6 Dynamic LIB is depleted", + __func__); + return false; + } + + /* + * First, let's check if there are any SID functions that were previously + * allocated and then released. + */ + if (listcount(block->u.usid.lib.func_released) != 0) { + /* + * There are SID functions previously allocated and then released, + * let's pick the first one and reuse it now. + */ + sid_func_ptr = listnode_head( + block->u.usid.lib.func_released); + *sid_func = *sid_func_ptr; + listnode_delete(block->u.usid.lib.func_released, + sid_func_ptr); + zebra_srv6_sid_func_free(sid_func_ptr); + } else { + /* + * There are no SID functions previously allocated and then released, + * let's allocate a new function from the pool of available functions. + */ + *sid_func = + block->u.usid.lib.first_available_func; + block->u.usid.lib.first_available_func++; + } + + /* Increase the counter of SID functions allocated */ + block->u.usid.lib.num_func_allocated++; + + if (block->u.usid.lib.first_available_func > dlib_end) + zlog_warn("%s: SRv6: Warning, SRv6 Dynamic LIB is depleted and next SID request will fail", + __func__); + } else if (format->type == SRV6_SID_FORMAT_TYPE_UNCOMPRESSED) { + /* Format is uncompressed => allocate SID function from Dynamic range */ + + uint32_t dynamic_end = + format->config.uncompressed.explicit_start - 1; + + /* Check if we ran out of available SID functions */ + if (block->u.uncompressed.first_available_func > + dynamic_end) { + zlog_warn("%s: SRv6: Warning, SRv6 SID Dynamic alloc space is depleted", + __func__); + return NULL; + } + + /* + * First, let's check if there are any SID functions that were previously + * allocated and then released. + */ + if (listcount(block->u.uncompressed.func_released) != 0) { + /* + * There are SID functions previously allocated and then released, + * let's pick the first one and reuse it now. + */ + sid_func_ptr = listnode_head( + block->u.uncompressed.func_released); + *sid_func = *sid_func_ptr; + listnode_delete(block->u.uncompressed + .func_released, + sid_func_ptr); + zebra_srv6_sid_func_free(sid_func_ptr); + } else { + /* + * There are no SID functions previously allocated and then released, + * let's allocate a new function from the pool of available functions. + */ + *sid_func = block->u.uncompressed + .first_available_func; + block->u.uncompressed.first_available_func++; + } + + /* Increase the counter of SID functions allocated */ + block->u.uncompressed.num_func_allocated++; + + if (block->u.uncompressed.first_available_func > + dynamic_end) + zlog_warn("%s: SRv6: Warning, SRv6 SID Dynamic alloc space is depleted and next SID request will fail", + __func__); + } else { + /* We should never arrive here */ + zlog_err("%s: unknown SID format type: %u", __func__, + format->type); + assert(0); + } + } else { + /* + * First, let's check if there are any SID functions that were previously + * allocated and then released. + */ + if (listcount(block->u.uncompressed.func_released) != 0) { + /* + * There are SID functions previously allocated and then released, + * let's pick the first one and reuse it now. + */ + sid_func_ptr = listnode_head( + block->u.uncompressed.func_released); + *sid_func = *sid_func_ptr; + listnode_delete(block->u.uncompressed.func_released, + sid_func_ptr); + zebra_srv6_sid_func_free(sid_func_ptr); + } else { + /* + * There are no SID functions previously allocated and then released, + * let's allocate a new function from the pool of available functions. + */ + *sid_func = block->u.uncompressed.first_available_func; + block->u.uncompressed.first_available_func++; + } + + /* Increase the counter of SID functions allocated */ + block->u.uncompressed.num_func_allocated++; + } + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: allocated dynamic SID function %u from block %pFX", + __func__, *sid_func, &block->prefix); + + return true; +} + +/** + * Get an explicit SID (i.e., a specific SID value) for a given context. + * + * If a SID already exists associated with the context, it returns the existing SID. + * Otherwise, it allocates a new SID. + * + * @param sid SID returned + * @param ctx Context for which the SID has been requested + * @param sid_value specific SRv6 SID value (i.e. IPv6 address) to be + * allocated explicitly + * + * @return 0 if the function returned an existing SID and SID value has not changed, + * 1 if a new SID has been allocated or the existing SID value has changed, -1 if an error occurred + */ +static int get_srv6_sid_explicit(struct zebra_srv6_sid **sid, + struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_ctx *s = NULL; + struct zebra_srv6_sid_ctx *zctx = NULL; + struct listnode *node; + uint32_t sid_func = 0, sid_func_wide = 0; + struct srv6_locator *locator = NULL; + struct zebra_srv6_sid_block *block = NULL; + char buf[256]; + + if (!ctx || !sid_value) + return -1; + + /* Check if we already have a SID associated with the provided context */ + for (ALL_LIST_ELEMENTS_RO(srv6->sids, node, s)) { + if (memcmp(&s->ctx, ctx, sizeof(struct srv6_sid_ctx)) == 0) { + /* + * If the context is already associated with a SID that has the same SID value, then + * return the existing SID + */ + if (sid_same(&s->sid->value, sid_value)) { + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: returning existing SRv6 SID %pI6 ctx %s", + __func__, &s->sid->value, + srv6_sid_ctx2str(buf, + sizeof(buf), + ctx)); + *sid = s->sid; + return 0; + } + + /* + * It is not allowed to allocate an explicit SID for a given context if the context + * is already associated with an explicit SID + */ + if (s->sid->alloc_mode == SRV6_SID_ALLOC_MODE_EXPLICIT) { + zlog_err("%s: cannot alloc SID %pI6 for ctx %s: ctx already associated with SID %pI6", + __func__, sid_value, + srv6_sid_ctx2str(buf, sizeof(buf), + &s->ctx), + &s->sid->value); + return -1; + } + + zctx = s; + break; + } + } + + /* Get parent locator and function of the provided SID */ + if (!zebra_srv6_sid_decompose(sid_value, &block, &locator, &sid_func, + &sid_func_wide)) { + zlog_err("%s: invalid SM request arguments: parent block/locator not found for SID %pI6", + __func__, sid_value); + return -1; + } + + if (ctx->behavior == ZEBRA_SEG6_LOCAL_ACTION_END) { + zlog_err("%s: invalid SM request arguments: explicit SID allocation not allowed for End/uN behavior", + __func__); + return -1; + } + + /* Allocate an explicit SID function for the SID */ + if (!alloc_srv6_sid_func_explicit(block, sid_func, sid_func_wide)) { + zlog_err("%s: invalid SM request arguments: failed to allocate SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + return -1; + } + + if (!zctx) { + /* If we don't have a zebra SID context for this context, allocate a new one */ + zctx = zebra_srv6_sid_ctx_alloc(); + zctx->ctx = *ctx; + } else { + /* + * If we already have a SID associated with this context, we need to + * deallocate the current SID function before allocating the new one + */ + if (zctx->sid) { + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: ctx %s already associated with a dynamic SID %pI6, releasing dynamic SID", + __func__, + srv6_sid_ctx2str(buf, sizeof(buf), + ctx), + &zctx->sid->value); + + release_srv6_sid_func_dynamic(block, zctx->sid->func); + zebra_srv6_sid_free(zctx->sid); + zctx->sid = NULL; + } + } + + /* Allocate the SID to store SID information */ + *sid = zebra_srv6_sid_alloc(zctx, sid_value, locator, block, sid_func, + SRV6_SID_ALLOC_MODE_EXPLICIT); + if (!(*sid)) { + flog_err(EC_ZEBRA_SM_CANNOT_ASSIGN_SID, + "%s: failed to create SRv6 SID %s (%pI6)", __func__, + srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value); + return -1; + } + (*sid)->ctx = zctx; + zctx->sid = *sid; + listnode_add(srv6->sids, zctx); + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: allocated explicit SRv6 SID %pI6 for context %s", + __func__, &(*sid)->value, + srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + return 1; +} + +/** + * Get a dynamic SID (i.e., any available SID value) for a given context. + * + * If a SID already exists associated with the context, it returns the existing SID. + * Otherwise, it allocates a new SID. + * + * @param sid SID returned + * @param ctx Context for which the SID has been requested + * @param locator SRv6 locator from which the SID has to be allocated + * + * @return 0 if the function returned an existing SID and SID value has not changed, + * 1 if a new SID has been allocated or the existing SID value has changed, -1 if an error occurred + */ +static int get_srv6_sid_dynamic(struct zebra_srv6_sid **sid, + struct srv6_sid_ctx *ctx, + struct srv6_locator *locator) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_block *block; + struct srv6_sid_format *format; + struct zebra_srv6_sid_ctx *s = NULL; + struct zebra_srv6_sid_ctx *zctx; + struct listnode *node; + struct in6_addr sid_value; + uint32_t sid_func = 0; + char buf[256]; + + if (!ctx || !locator) + return -1; + + block = locator->sid_block; + format = locator->sid_format; + + /* + * If we already have a SID for the provided context, we return the existing + * SID instead of allocating a new one. + */ + for (ALL_LIST_ELEMENTS_RO(srv6->sids, node, s)) { + if (memcmp(&s->ctx, ctx, sizeof(struct srv6_sid_ctx)) == 0) { + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: returning existing SID %s %pI6", + __func__, + srv6_sid_ctx2str(buf, sizeof(buf), + ctx), + &s->sid->value); + *sid = s->sid; + return 0; + } + } + + if (format && format->type == SRV6_SID_FORMAT_TYPE_USID && + ctx->behavior == ZEBRA_SEG6_LOCAL_ACTION_END) { + /* uN SID is allocated from the GIB range */ + sid_value = locator->prefix.prefix; + } else if (!format && ctx->behavior == ZEBRA_SEG6_LOCAL_ACTION_END) { + /* uN SID is allocated from the GIB range */ + sid_value = locator->prefix.prefix; + } else { + /* Allocate a dynamic SID function for the SID */ + if (!alloc_srv6_sid_func_dynamic(block, &sid_func)) { + zlog_err("%s: invalid SM request arguments: failed to allocate SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + return -1; + } + + /* Compose the SID as the locator followed by the SID function */ + zebra_srv6_sid_compose(&sid_value, locator, sid_func); + } + + /* Allocate a zebra SID context to store SID context information */ + zctx = zebra_srv6_sid_ctx_alloc(); + zctx->ctx = *ctx; + + /* Allocate the SID to store SID information */ + *sid = zebra_srv6_sid_alloc(zctx, &sid_value, locator, block, sid_func, + SRV6_SID_ALLOC_MODE_DYNAMIC); + if (!(*sid)) { + flog_err(EC_ZEBRA_SM_CANNOT_ASSIGN_SID, + "%s: failed to create SRv6 SID ctx %s (%pI6)", __func__, + srv6_sid_ctx2str(buf, sizeof(buf), ctx), &sid_value); + return -1; + } + (*sid)->ctx = zctx; + zctx->sid = *sid; + listnode_add(srv6->sids, zctx); + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: allocated new dynamic SRv6 SID %pI6 for context %s", + __func__, &(*sid)->value, + srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + return 1; +} + +/** + * Get an SRv6 SID for a given context. + * + * If a SID already exists associated with the context, it returns the existing SID. + * Otherwise, it allocates a new SID. + * + * If the sid_value parameter is non-NULL, it allocates the requested SID value + * if it is available (explicit SID allocation). + * If the sid_value parameter is NULL, it allocates any available SID value + * (dynamic SID allocation). + * + * @param sid SID returned + * @param ctx Context for which the SID has been requested + * @param sid_value SRv6 SID value to be allocated (for explicit SID allocation) + * @param locator_name Parent SRv6 locator from which the SID has to be allocated (for dynamic SID allocation) + * + * @return 0 if the function returned an existing SID and SID value has not changed, + * 1 if a new SID has been allocated or the existing SID value has changed, -1 if an error occurred + */ +int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, const char *locator_name) +{ + int ret = -1; + struct srv6_locator *locator; + char buf[256]; + + enum srv6_sid_alloc_mode alloc_mode = + (sid_value) ? SRV6_SID_ALLOC_MODE_EXPLICIT + : SRV6_SID_ALLOC_MODE_DYNAMIC; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: received SRv6 SID alloc request: SID ctx %s (%pI6), mode=%s", + __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), + sid_value, srv6_sid_alloc_mode2str(alloc_mode)); + + switch (alloc_mode) { + case SRV6_SID_ALLOC_MODE_EXPLICIT: + /* + * Explicit SID allocation: allocate a specific SID value + */ + + if (!sid_value) { + zlog_err("%s: invalid SM request arguments: missing SRv6 SID value, necessary for explicit allocation", + __func__); + return -1; + } + + ret = get_srv6_sid_explicit(sid, ctx, sid_value); + + break; + case SRV6_SID_ALLOC_MODE_DYNAMIC: + /* + * Dynamic SID allocation: allocate any available SID value + */ + + if (!locator_name) { + zlog_err("%s: invalid SM request arguments: missing SRv6 locator, necessary for dynamic allocation", + __func__); + return -1; + } + + locator = zebra_srv6_locator_lookup(locator_name); + if (!locator) { + zlog_err("%s: invalid SM request arguments: SRv6 locator '%s' does not exist", + __func__, locator_name); + return -1; + } + + ret = get_srv6_sid_dynamic(sid, ctx, locator); + + break; + case SRV6_SID_ALLOC_MODE_MAX: + case SRV6_SID_ALLOC_MODE_UNSPEC: + default: + flog_err(EC_ZEBRA_SM_CANNOT_ASSIGN_SID, + "%s: SRv6 Manager: Unrecognized alloc mode %u", + __func__, alloc_mode); + /* We should never arrive here */ + assert(0); + } + + return ret; +} + +/** + * Release an explicit SRv6 SID function. + * + * @param block Parent SRv6 SID block of the SID function that has to be released + * @param sid_func SID function to be released + * @return 0 on success, -1 otherwise + */ +static bool release_srv6_sid_func_explicit(struct zebra_srv6_sid_block *block, + uint32_t sid_func, + uint32_t sid_wide_func) +{ + struct srv6_sid_format *format; + struct listnode *node; + uint32_t *sid_func_ptr = NULL; + + if (!block) + return -1; + + format = block->sid_format; + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: trying to release explicit SRv6 SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + + /* + * Release SID function from the corresponding range depending on the SID format type + */ + if (format) { + if (format->type == SRV6_SID_FORMAT_TYPE_USID) { + uint32_t elib_start = format->config.usid.elib_start; + uint32_t elib_end = format->config.usid.elib_end; + uint32_t ewlib_start = format->config.usid.ewlib_start; + uint32_t ewlib_end = format->config.usid.wlib_end; + uint32_t *sid_wide_func_ptr = NULL; + + /* Figure out the range from which the SID function has been allocated and release it */ + if ((sid_func >= elib_start) && (sid_func <= elib_end)) { + /* The SID function comes from the ELIB range */ + + /* Lookup SID function in the functions allocated list of ELIB range */ + for (ALL_LIST_ELEMENTS_RO(block->u.usid.lib + .func_allocated, + node, sid_func_ptr)) + if (*sid_func_ptr == sid_func) + break; + + /* Ensure that the SID function is allocated */ + if (!sid_func_ptr) { + zlog_warn("%s: failed to release SID function %u, function is not allocated", + __func__, sid_func); + return -1; + } + + /* Release the SID function from the ELIB range */ + listnode_delete(block->u.usid.lib.func_allocated, + sid_func_ptr); + zebra_srv6_sid_func_free(sid_func_ptr); + } else if ((sid_func >= ewlib_start) && + (sid_func <= ewlib_end)) { + /* The SID function comes from the EWLIB range */ + + /* Lookup SID function in the functions allocated list of EWLIB range */ + for (ALL_LIST_ELEMENTS_RO(block->u.usid + .wide_lib[sid_func] + .func_allocated, + node, sid_func_ptr)) + if (*sid_wide_func_ptr == sid_wide_func) + break; + + /* Ensure that the SID function is allocated */ + if (!sid_wide_func_ptr) { + zlog_warn("%s: failed to release wide SID function %u, function is not allocated", + __func__, sid_wide_func); + return -1; + } + + /* Release the SID function from the EWLIB range */ + listnode_delete(block->u.usid.wide_lib[sid_func] + .func_allocated, + sid_wide_func_ptr); + zebra_srv6_sid_func_free(sid_wide_func_ptr); + } else { + zlog_warn("%s: function %u is outside ELIB [%u/%u] and EWLIB alloc ranges [%u/%u]", + __func__, sid_func, elib_start, + elib_end, ewlib_start, ewlib_end); + return -1; + } + } else if (format->type == SRV6_SID_FORMAT_TYPE_UNCOMPRESSED) { + uint32_t explicit_start = + format->config.uncompressed.explicit_start; + uint32_t explicit_end = + (uint32_t)((1 << format->function_len) - 1); + + /* Ensure that the SID function comes from the Explicit range */ + if (!(sid_func >= explicit_start && + sid_func <= explicit_end)) { + zlog_warn("%s: function %u is outside explicit alloc range [%u/%u]", + __func__, sid_func, explicit_start, + explicit_end); + return -1; + } + + /* Lookup SID function in the functions allocated list of Explicit range */ + for (ALL_LIST_ELEMENTS_RO(block->u.uncompressed + .func_allocated, + node, sid_func_ptr)) + if (*sid_func_ptr == sid_func) + break; + + /* Ensure that the SID function is allocated */ + if (!sid_func_ptr) { + zlog_warn("%s: failed to release SID function %u, function is not allocated", + __func__, sid_func); + return -1; + } + + /* Release the SID function from the Explicit range */ + listnode_delete(block->u.uncompressed.func_allocated, + sid_func_ptr); + zebra_srv6_sid_func_free(sid_func_ptr); + } else { + /* We should never arrive here */ + assert(0); + } + } else { + /* Lookup SID function in the functions allocated list of Explicit range */ + for (ALL_LIST_ELEMENTS_RO(block->u.uncompressed.func_allocated, + node, sid_func_ptr)) + if (*sid_func_ptr == sid_func) + break; + + /* Ensure that the SID function is allocated */ + if (!sid_func_ptr) { + zlog_warn("%s: failed to release SID function %u, function is not allocated", + __func__, sid_func); + return -1; + } + + /* Release the SID function from the Explicit range */ + listnode_delete(block->u.uncompressed.func_allocated, + sid_func_ptr); + zebra_srv6_sid_func_free(sid_func_ptr); + } + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: released explicit SRv6 SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + + return 0; +} + +/** + * Release a dynamic SRv6 SID function. + * + * @param block Parent SRv6 SID block of the SID function that has to be released + * @param sid_func SID function to be released + * @return 0 on success, -1 otherwise + */ +static int release_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block, + uint32_t sid_func) +{ + struct srv6_sid_format *format; + struct listnode *node, *nnode; + uint32_t *sid_func_ptr = NULL; + + if (!block) + return -1; + + format = block->sid_format; + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: trying to release dynamic SRv6 SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + + /* + * Release SID function from the corresponding range depending on the SID format type + */ + if (format && format->type == SRV6_SID_FORMAT_TYPE_USID) { + uint32_t dlib_start = format->config.usid.lib_start; + /* The Dynamic LIB range ends where the Explicit LIB range begins */ + uint32_t dlib_end = format->config.usid.elib_start - 1; + + /* Ensure that the SID function to be released comes from the Dynamic LIB (DLIB) range */ + if (!(sid_func >= dlib_start && sid_func <= dlib_end)) { + zlog_warn("%s: function %u is outside Dynamic LIB range [%u/%u]", + __func__, sid_func, dlib_start, dlib_end); + return -1; + } + + if (sid_func == block->u.usid.lib.first_available_func - 1) { + /* + * The SID function to be released precedes the `first_available_func`. + * Reset first_available_func to the first available position. + */ + + block->u.usid.lib.first_available_func -= 1; + + bool found; + + do { + found = false; + for (ALL_LIST_ELEMENTS(block->u.usid.lib + .func_released, + node, nnode, + sid_func_ptr)) + if (*sid_func_ptr == + block->u.usid.lib.first_available_func - + 1) { + listnode_delete(block->u.usid + .lib + .func_released, + sid_func_ptr); + zebra_srv6_sid_func_free( + sid_func_ptr); + block->u.usid.lib + .first_available_func -= + 1; + found = true; + break; + } + } while (found); + } else { + /* + * The SID function to be released does not precede the `first_available_func`. + * Add the released function to the func_released array to indicate + * that it is available again for allocation. + */ + sid_func_ptr = zebra_srv6_sid_func_alloc(sid_func); + listnode_add_head(block->u.usid.lib.func_released, + sid_func_ptr); + } + } else if (format && format->type == SRV6_SID_FORMAT_TYPE_UNCOMPRESSED) { + uint32_t dynamic_start = + SRV6_SID_FORMAT_UNCOMPRESSED_F4024_FUNC_UNRESERVED_MIN; + /* The Dynamic range ends where the Explicit range begins */ + uint32_t dynamic_end = + format->config.uncompressed.explicit_start - 1; + + /* Ensure that the SID function to be released comes from the Dynamic range */ + if (!(sid_func >= dynamic_start && sid_func <= dynamic_end)) { + zlog_warn("%s: function %u is outside dynamic range [%u/%u]", + __func__, sid_func, dynamic_start, + dynamic_end); + return -1; + } + + if (sid_func == block->u.uncompressed.first_available_func - 1) { + /* + * The released SID function precedes the `first_available_func`. + * Reset first_available_func to the first available position. + */ + + block->u.uncompressed.first_available_func -= 1; + + bool found; + + do { + found = false; + for (ALL_LIST_ELEMENTS(block->u.uncompressed + .func_released, + node, nnode, + sid_func_ptr)) + if (*sid_func_ptr == + block->u.uncompressed + .first_available_func - + 1) { + listnode_delete(block->u.uncompressed + .func_released, + sid_func_ptr); + zebra_srv6_sid_func_free( + sid_func_ptr); + block->u.uncompressed + .first_available_func -= + 1; + found = true; + break; + } + } while (found); + } else { + /* + * The released SID function does not precede the `first_available_func`. + * Add the released function to the func_released array to indicate + * that it is available again for allocation. + */ + sid_func_ptr = zebra_srv6_sid_func_alloc(sid_func); + listnode_add_head(block->u.uncompressed.func_released, + sid_func_ptr); + } + } else if (!format) { + if (sid_func == block->u.uncompressed.first_available_func - 1) { + /* + * The released SID function precedes the `first_available_func`. + * Reset first_available_func to the first available position. + */ + + block->u.uncompressed.first_available_func -= 1; + + bool found; + + do { + found = false; + for (ALL_LIST_ELEMENTS(block->u.uncompressed + .func_released, + node, nnode, + sid_func_ptr)) + if (*sid_func_ptr == + block->u.uncompressed + .first_available_func - + 1) { + listnode_delete(block->u.uncompressed + .func_released, + sid_func_ptr); + zebra_srv6_sid_func_free( + sid_func_ptr); + block->u.uncompressed + .first_available_func -= + 1; + found = true; + break; + } + } while (found); + } else { + /* + * The released SID function does not precede the `first_available_func`. + * Add the released function to the func_released array to indicate + * that it is available again for allocation. + */ + sid_func_ptr = zebra_srv6_sid_func_alloc(sid_func); + listnode_add_head(block->u.uncompressed.func_released, + sid_func_ptr); + } + } + + if (ZEBRA_DEBUG_PACKET) + zlog_debug("%s: released dynamic SRv6 SID function %u from block %pFX", + __func__, sid_func, &block->prefix); + + return 0; +} + +/** + * Core function, release the SRv6 SID associated with a given context. + * + * @param client The client for which the SID has to be released + * @param ctx Context associated with the SRv6 SID to be released + * @return 0 on success, -1 otherwise + */ +int release_srv6_sid(struct zserv *client, struct zebra_srv6_sid_ctx *zctx) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + char buf[256]; + + if (!zctx || !zctx->sid) + return -1; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: releasing SRv6 SID %pI6 associated with ctx %s (proto=%u, instance=%u)", + __func__, &zctx->sid->value, + srv6_sid_ctx2str(buf, sizeof(buf), &zctx->ctx), + client->proto, client->instance); + + /* Ensures the SID is in use by the client */ + if (!listnode_lookup(zctx->sid->client_list, client)) { + flog_err(EC_ZEBRA_SM_DAEMON_MISMATCH, "%s: Daemon mismatch!!", + __func__); + return -1; + } + + /* Remove the client from the list of clients using the SID */ + listnode_delete(zctx->sid->client_list, client); + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: released SRv6 SID %pI6 associated with ctx %s (proto=%u, instance=%u)", + __func__, &zctx->sid->value, + srv6_sid_ctx2str(buf, sizeof(buf), &zctx->ctx), + client->proto, client->instance); + + /* + * If the SID is not used by any other client, then deallocate it + * and remove it from the SRv6 database. + */ + if (listcount(zctx->sid->client_list) == 0) { + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: SRv6 SID %pI6 associated with ctx %s is no longer in use, removing it from SRv6 database", + __func__, &zctx->sid->value, + srv6_sid_ctx2str(buf, sizeof(buf), + &zctx->ctx)); + + if (!(zctx->sid->block->sid_format && + zctx->sid->block->sid_format->type == + SRV6_SID_FORMAT_TYPE_USID && + zctx->ctx.behavior == ZEBRA_SEG6_LOCAL_ACTION_END) && + !(!zctx->sid->block->sid_format && + zctx->ctx.behavior == ZEBRA_SEG6_LOCAL_ACTION_END)) { + if (zctx->sid->alloc_mode == + SRV6_SID_ALLOC_MODE_EXPLICIT) + /* Release SRv6 SID function */ + release_srv6_sid_func_explicit(zctx->sid->block, + zctx->sid->func, + zctx->sid->wide_func); + else if (zctx->sid->alloc_mode == + SRV6_SID_ALLOC_MODE_DYNAMIC) + /* Release SRv6 SID function */ + release_srv6_sid_func_dynamic(zctx->sid->block, + zctx->sid->func); + else + /* We should never arrive here */ + assert(0); + } + + /* Free the SID */ + zebra_srv6_sid_free(zctx->sid); + zctx->sid = NULL; + + /* Remove the SID context from the list and free memory */ + listnode_delete(srv6->sids, zctx); + zebra_srv6_sid_ctx_free(zctx); + } + + return 0; +} + /** * Handle a get SRv6 Locator request received from a client. * diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 681789e4aca9..7d989f180f54 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -294,6 +294,11 @@ extern void srv6_manager_get_locator_call(struct srv6_locator **locator, struct zserv *client, const char *locator_name); +extern int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, const char *locator_name); +extern int release_srv6_sid(struct zserv *client, + struct zebra_srv6_sid_ctx *zctx); + extern struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void); extern void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx); extern void delete_zebra_srv6_sid_ctx(void *val); From 84dd482cb929d522cf12c91c2e7ec1faead848ea Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 17:25:39 +0100 Subject: [PATCH 271/472] zebra: Alloc/Release SIDs to daemons upon request Previous commits introduced two new ZAPI operations, `ZEBRA_SRV6_MANAGER_GET_SRV6_SID` and `ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID`. These operations allow a daemon to interact with the SRv6 SID Manager to get and release an SRv6 SID, respectively. This commit extends the SID Manager by adding logic to process the requests `ZEBRA_SRV6_MANAGER_GET_SRV6_SID` and `ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID`, and allocate/release SIDs to requesting daemons. Signed-off-by: Carmine Scarpitta --- zebra/zapi_msg.c | 73 ++++++++++++++++++++ zebra/zebra_srv6.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ zebra/zebra_srv6.h | 18 +++++ 3 files changed, 254 insertions(+) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 52ee0876896a..bab4c4fa3d74 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -3006,6 +3006,71 @@ static void zread_srv6_manager_release_locator_chunk(struct zserv *client, return; } +/** + * Handle SRv6 SID request received from a client daemon protocol. + * + * @param client The client zapi session + * @param msg The request message + */ +static void zread_srv6_manager_get_srv6_sid(struct zserv *client, + struct stream *msg) +{ + struct stream *s; + struct srv6_sid_ctx ctx = {}; + struct in6_addr sid_value = {}; + struct in6_addr *sid_value_ptr = NULL; + char locator[SRV6_LOCNAME_SIZE] = { 0 }; + uint16_t len; + struct zebra_srv6_sid *sid = NULL; + uint8_t flags; + + /* Get input stream */ + s = msg; + + /* Get data */ + STREAM_GET(&ctx, s, sizeof(struct srv6_sid_ctx)); + STREAM_GETC(s, flags); + if (CHECK_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_SID_VALUE)) { + STREAM_GET(&sid_value, s, sizeof(struct in6_addr)); + sid_value_ptr = &sid_value; + } + if (CHECK_FLAG(flags, ZAPI_SRV6_MANAGER_SID_FLAG_HAS_LOCATOR)) { + STREAM_GETW(s, len); + STREAM_GET(locator, s, len); + } + + /* Call hook to get a SID using wrapper */ + srv6_manager_get_sid_call(&sid, client, &ctx, sid_value_ptr, locator); + +stream_failure: + return; +} + +/** + * Handle SRv6 SID release request received from a client daemon protocol. + * + * @param client The client zapi session + * @param msg The request message + */ +static void zread_srv6_manager_release_srv6_sid(struct zserv *client, + struct stream *msg) +{ + struct stream *s; + struct srv6_sid_ctx ctx = {}; + + /* Get input stream */ + s = msg; + + /* Get data */ + STREAM_GET(&ctx, s, sizeof(struct srv6_sid_ctx)); + + /* Call hook to release a SID using wrapper */ + srv6_manager_release_sid_call(client, &ctx); + +stream_failure: + return; +} + /** * Handle SRv6 locator get request received from a client daemon protocol. * @@ -3042,6 +3107,12 @@ static void zread_srv6_manager_request(ZAPI_HANDLER_ARGS) zread_srv6_manager_release_locator_chunk(client, msg, zvrf_id(zvrf)); break; + case ZEBRA_SRV6_MANAGER_GET_SRV6_SID: + zread_srv6_manager_get_srv6_sid(client, msg); + break; + case ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID: + zread_srv6_manager_release_srv6_sid(client, msg); + break; case ZEBRA_SRV6_MANAGER_GET_LOCATOR: zread_srv6_manager_get_locator(client, msg); break; @@ -3993,6 +4064,8 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = { [ZEBRA_MLAG_FORWARD_MSG] = zebra_mlag_forward_client_msg, [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] = zread_srv6_manager_request, [ZEBRA_SRV6_MANAGER_RELEASE_LOCATOR_CHUNK] = zread_srv6_manager_request, + [ZEBRA_SRV6_MANAGER_GET_SRV6_SID] = zread_srv6_manager_request, + [ZEBRA_SRV6_MANAGER_RELEASE_SRV6_SID] = zread_srv6_manager_request, [ZEBRA_SRV6_MANAGER_GET_LOCATOR] = zread_srv6_manager_request, [ZEBRA_CLIENT_CAPABILITIES] = zread_client_capabilities, [ZEBRA_NEIGH_DISCOVER] = zread_neigh_discover, diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 047422b9e33f..d93f09f1b4fd 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -65,6 +65,13 @@ DEFINE_HOOK(srv6_manager_release_chunk, vrf_id_t vrf_id), (client, locator_name, vrf_id)); +DEFINE_HOOK(srv6_manager_get_sid, + (struct zebra_srv6_sid **sid, struct zserv *client, + struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, + const char *locator_name), + (sid, client, ctx, sid_value, locator_name)); +DEFINE_HOOK(srv6_manager_release_sid, + (struct zserv *client, struct srv6_sid_ctx *ctx), (client, ctx)); DEFINE_HOOK(srv6_manager_get_locator, (struct srv6_locator **locator, struct zserv *client, const char *locator_name), @@ -100,6 +107,22 @@ int srv6_manager_client_disconnect_cb(struct zserv *client) return 0; } + +void srv6_manager_get_sid_call(struct zebra_srv6_sid **sid, + struct zserv *client, struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, + const char *locator_name) +{ + hook_call(srv6_manager_get_sid, sid, client, ctx, sid_value, + locator_name); +} + +void srv6_manager_release_sid_call(struct zserv *client, + struct srv6_sid_ctx *ctx) +{ + hook_call(srv6_manager_release_sid, client, ctx); +} + void srv6_manager_get_locator_call(struct srv6_locator **locator, struct zserv *client, const char *locator_name) @@ -109,6 +132,8 @@ void srv6_manager_get_locator_call(struct srv6_locator **locator, static int zebra_srv6_cleanup(struct zserv *client) { + /* Client has disconnected, let's release all the SIDs allocated by it. */ + release_daemon_srv6_sids(client); return 0; } @@ -2225,6 +2250,141 @@ static int srv6_manager_get_srv6_locator_internal(struct srv6_locator **locator, return zsend_zebra_srv6_locator_add(client, *locator); } +/** + * Handle a get SID request received from a client. + * + * It gets a SID for a given context. If there is no SID associated with the context yet, + * we allocate one and return it to the client. Otherwise, we return the existing SID. + * + * - When the `sid_value` parameter is non-NULL, SRv6 Manager assigns the requested SID value + * if it is available (explicit SID allocation). + * - When the `sid_value` parameter is NULL, SRv6 Manager assigns any available SID value + * (dynamic SID allocation). + * + * Finally, notify the client whether the SID allocation was successful or failed. + * + * @param sid SID returned by this function + * @param client The client that requested the SID + * @param ctx Context for which the SID was requested + * @param sid_value SID value (i.e., IPv6 address) that has to be assigned to the SID + * (for explicit SID allocation) + * @param locator_name Locator from which the SID has to be allocated (for dynamic SID allocation) + * + * @return 0 on success, -1 otherwise + */ +static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, + struct zserv *client, + struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, + const char *locator_name) +{ + int ret = -1; + char buf[256]; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: getting SRv6 SID for ctx %s, sid_value=%pI6, locator_name=%s", + __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), + sid_value, locator_name); + + ret = get_srv6_sid(sid, ctx, sid_value, locator_name); + if (ret < 0) { + zlog_warn("%s: not got SRv6 SID for ctx %s, sid_value=%pI6, locator_name=%s", + __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), + sid_value, locator_name); + } else if (ret == 0) { + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: got existing SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notify client", + __func__, + srv6_sid_ctx2str(buf, sizeof(buf), ctx), + &(*sid)->value, (*sid)->func, client->proto, + client->instance, client->session_id); + if (!listnode_lookup((*sid)->client_list, client)) + listnode_add((*sid)->client_list, client); + } else { + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: got new SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notifying all clients", + __func__, + srv6_sid_ctx2str(buf, sizeof(buf), ctx), + &(*sid)->value, (*sid)->func, client->proto, + client->instance, client->session_id); + if (!listnode_lookup((*sid)->client_list, client)) + listnode_add((*sid)->client_list, client); + } + + return ret; +} + +/** + * Release SRv6 SIDs from a client. + * + * Called on client disconnection or reconnection. + * + * @param client The client to release SIDs from + * @return Number of SIDs released + */ +int release_daemon_srv6_sids(struct zserv *client) +{ + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct listnode *node, *nnode; + struct zebra_srv6_sid_ctx *ctx; + int count = 0; + int ret; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: releasing SRv6 SIDs for client proto %s, instance %d, session %u", + __func__, zebra_route_string(client->proto), + client->instance, client->session_id); + + /* Iterate over the SIDs and release SIDs used by the client daemon */ + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, ctx)) { + if (!listnode_lookup(ctx->sid->client_list, client)) + continue; + + ret = release_srv6_sid(client, ctx); + if (ret == 0) + count++; + } + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: released %d SRv6 SIDs", __func__, count); + + return count; +} + +/** + * Release SRv6 SIDs from a client. + * + * @param client The client zapi session + * @param ctx Context associated with the SRv6 SID + * @return 0 on success, -1 on failure + */ +static int srv6_manager_release_sid_internal(struct zserv *client, + struct srv6_sid_ctx *ctx) +{ + int ret = -1; + struct zebra_srv6 *srv6 = zebra_srv6_get_default(); + struct zebra_srv6_sid_ctx *zctx; + struct listnode *node, *nnode; + char buf[256]; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: releasing SRv6 SID associated with ctx %s", + __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + /* Lookup Zebra SID context and release it */ + for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, zctx)) + if (memcmp(&zctx->ctx, ctx, sizeof(struct srv6_sid_ctx)) == 0) { + ret = release_srv6_sid(client, zctx); + break; + } + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: no SID associated with ctx %s", __func__, + srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + + return ret; +} + void zebra_srv6_terminate(void) { struct srv6_locator *locator; @@ -2288,6 +2448,9 @@ void zebra_srv6_init(void) hook_register(srv6_manager_release_chunk, zebra_srv6_manager_release_locator_chunk); + hook_register(srv6_manager_get_sid, srv6_manager_get_sid_internal); + hook_register(srv6_manager_release_sid, + srv6_manager_release_sid_internal); hook_register(srv6_manager_get_locator, srv6_manager_get_srv6_locator_internal); } diff --git a/zebra/zebra_srv6.h b/zebra/zebra_srv6.h index 7d989f180f54..1599fd7adfbd 100644 --- a/zebra/zebra_srv6.h +++ b/zebra/zebra_srv6.h @@ -231,6 +231,13 @@ DECLARE_HOOK(srv6_manager_release_chunk, vrf_id_t vrf_id), (client, locator_name, vrf_id)); +DECLARE_HOOK(srv6_manager_get_sid, + (struct zebra_srv6_sid **sid, struct zserv *client, + struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, + const char *locator_name), + (sid, client, ctx, sid_value, locator_name)); +DECLARE_HOOK(srv6_manager_release_sid, + (struct zserv *client, struct srv6_sid_ctx *ctx), (client, ctx)); DECLARE_HOOK(srv6_manager_get_locator, (struct srv6_locator **locator, struct zserv *client, const char *locator_name), @@ -290,6 +297,14 @@ zebra_srv6_sid_alloc(struct zebra_srv6_sid_ctx *ctx, struct in6_addr *sid_value, extern void zebra_srv6_sid_free(struct zebra_srv6_sid *sid); extern void delete_zebra_srv6_sid(void *val); +extern void srv6_manager_get_sid_call(struct zebra_srv6_sid **sid, + struct zserv *client, + struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, + const char *locator_name); +extern void srv6_manager_release_sid_call(struct zserv *client, + struct srv6_sid_ctx *ctx); + extern void srv6_manager_get_locator_call(struct srv6_locator **locator, struct zserv *client, const char *locator_name); @@ -298,6 +313,9 @@ extern int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, const char *locator_name); extern int release_srv6_sid(struct zserv *client, struct zebra_srv6_sid_ctx *zctx); +extern int release_daemon_srv6_sids(struct zserv *client); +extern int srv6_manager_get_sid_response(struct zebra_srv6_sid *sid, + struct zserv *client); extern struct zebra_srv6_sid_ctx *zebra_srv6_sid_ctx_alloc(void); extern void zebra_srv6_sid_ctx_free(struct zebra_srv6_sid_ctx *ctx); From b90cb00974ef84beff603fb0e91a7a38b3a1b6a4 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Mon, 6 May 2024 17:53:18 +0200 Subject: [PATCH 272/472] lib: Add ZAPI command `ZEBRA_SRV6_SID_NOTIFY` Add a new ZAPI command `ZEBRA_SRV6_SID_NOTIFY` used by zebra to send asynchronous SRv6 SIDs notifications to zclients. Signed-off-by: Carmine Scarpitta --- lib/log.c | 3 ++- lib/zclient.c | 24 ++++++++++++++++++++++++ lib/zclient.h | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/lib/log.c b/lib/log.c index fa8a8734a4e7..880180ae5a94 100644 --- a/lib/log.c +++ b/lib/log.c @@ -464,7 +464,8 @@ static const struct zebra_desc_table command_types[] = { DESC_ENTRY(ZEBRA_TC_CLASS_DELETE), DESC_ENTRY(ZEBRA_TC_FILTER_ADD), DESC_ENTRY(ZEBRA_TC_FILTER_DELETE), - DESC_ENTRY(ZEBRA_OPAQUE_NOTIFY) + DESC_ENTRY(ZEBRA_OPAQUE_NOTIFY), + DESC_ENTRY(ZEBRA_SRV6_SID_NOTIFY) }; #undef DESC_ENTRY diff --git a/lib/zclient.c b/lib/zclient.c index b0e97b0f126c..e4d02d743a93 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2133,6 +2133,30 @@ bool zapi_iptable_notify_decode(struct stream *s, return false; } +bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, uint32_t *func, + uint32_t *wide_func, + enum zapi_srv6_sid_notify *note) +{ + uint32_t f, wf; + + STREAM_GET(note, s, sizeof(*note)); + STREAM_GET(ctx, s, sizeof(struct srv6_sid_ctx)); + STREAM_GET(sid_value, s, sizeof(struct in6_addr)); + STREAM_GETL(s, f); + STREAM_GETL(s, wf); + + if (func) + *func = f; + if (wide_func) + *wide_func = wf; + + return true; + +stream_failure: + return false; +} + struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh) { struct nexthop *n = nexthop_new(); diff --git a/lib/zclient.h b/lib/zclient.h index bb527f0b41b6..bfe955b7acc7 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -238,6 +238,7 @@ typedef enum { ZEBRA_TC_FILTER_ADD, ZEBRA_TC_FILTER_DELETE, ZEBRA_OPAQUE_NOTIFY, + ZEBRA_SRV6_SID_NOTIFY, } zebra_message_types_t; /* Zebra message types. Please update the corresponding * command_types array with any changes! @@ -764,6 +765,13 @@ enum zapi_iptable_notify_owner { ZAPI_IPTABLE_FAIL_REMOVE, }; +enum zapi_srv6_sid_notify { + ZAPI_SRV6_SID_FAIL_ALLOC = 0, + ZAPI_SRV6_SID_ALLOCATED, + ZAPI_SRV6_SID_RELEASED, + ZAPI_SRV6_SID_FAIL_RELEASE, +}; + enum zclient_send_status { ZCLIENT_SEND_FAILURE = -1, ZCLIENT_SEND_SUCCESS = 0, @@ -816,6 +824,28 @@ zapi_rule_notify_owner2str(enum zapi_rule_notify_owner note) return ret; } +static inline const char *zapi_srv6_sid_notify2str(enum zapi_srv6_sid_notify note) +{ + const char *ret = "UNKNOWN"; + + switch (note) { + case ZAPI_SRV6_SID_FAIL_ALLOC: + ret = "ZAPI_SRV6_SID_FAIL_ALLOC"; + break; + case ZAPI_SRV6_SID_ALLOCATED: + ret = "ZAPI_SRV6_SID_ALLOCATED"; + break; + case ZAPI_SRV6_SID_FAIL_RELEASE: + ret = "ZAPI_SRV6_SID_FAIL_RELEASE"; + break; + case ZAPI_SRV6_SID_RELEASED: + ret = "ZAPI_SRV6_SID_RELEASED"; + break; + } + + return ret; +} + /* Zebra MAC types */ #define ZEBRA_MACIP_TYPE_STICKY 0x01 /* Sticky MAC*/ #define ZEBRA_MACIP_TYPE_GW 0x02 /* gateway (SVI) mac*/ @@ -1144,6 +1174,10 @@ bool zapi_rule_notify_decode(struct stream *s, uint32_t *seqno, bool zapi_ipset_notify_decode(struct stream *s, uint32_t *unique, enum zapi_ipset_notify_owner *note); +bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, uint32_t *func, + uint32_t *wide_func, + enum zapi_srv6_sid_notify *note); /* Nexthop-group message apis */ extern enum zclient_send_status From efa830e89ca39c93eeddef40ed7c959ba36b1fc1 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 2 May 2024 13:39:49 +0200 Subject: [PATCH 273/472] zebra: Notify daemons about SIDs Send asynchronous notifications to zclients when an SRv6 SID is allocated/released and when a SID alloc/release operation fails. Signed-off-by: Carmine Scarpitta --- zebra/zapi_msg.c | 33 +++++++++++++++++++++++++++++++++ zebra/zapi_msg.h | 5 +++++ zebra/zebra_srv6.c | 22 ++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index bab4c4fa3d74..164c0dd68723 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -999,6 +999,39 @@ void zsend_neighbor_notify(int cmd, struct interface *ifp, } } +void zsend_srv6_sid_notify(struct zserv *client, const struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, uint32_t func, + uint32_t wide_func, enum zapi_srv6_sid_notify note) +{ + struct stream *s; + uint16_t cmd = ZEBRA_SRV6_SID_NOTIFY; + char buf[256]; + + if (IS_ZEBRA_DEBUG_PACKET) + zlog_debug("%s: notifying %s ctx %s sid %pI6 note %s (proto=%u, instance=%u, sessionId=%u)", + __func__, zserv_command_string(cmd), + srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value, + zapi_srv6_sid_notify2str(note), client->proto, + client->instance, client->session_id); + + s = stream_new(ZEBRA_MAX_PACKET_SIZ); + + zclient_create_header(s, cmd, VRF_DEFAULT); + /* Notification type (e.g. ZAPI_SRV6_SID_ALLOCATED, ZAPI_SRV6_SID_FAIL_ALLOC, ...) */ + stream_put(s, ¬e, sizeof(note)); + /* Context associated with the SRv6 SID */ + stream_put(s, ctx, sizeof(struct srv6_sid_ctx)); + /* SRv6 SID value (i.e. IPv6 address) */ + stream_put(s, sid_value, sizeof(struct in6_addr)); + /* SRv6 SID function */ + stream_putl(s, func); + /* SRv6 wide SID function */ + stream_putl(s, wide_func); + stream_putw_at(s, 0, stream_get_endp(s)); + + zserv_send_message(client, s); +} + /* Router-id is updated. Send ZEBRA_ROUTER_ID_UPDATE to client. */ int zsend_router_id_update(struct zserv *client, afi_t afi, struct prefix *p, diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index c7123e2593f2..3505bc0dc4e3 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -94,6 +94,11 @@ extern int zsend_sr_policy_notify_status(uint32_t color, extern void zsend_neighbor_notify(int cmd, struct interface *ifp, struct ipaddr *ipaddr, int ndm_state, union sockunion *link_layer_ipv4, int ip_len); +extern void zsend_srv6_sid_notify(struct zserv *client, + const struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, uint32_t func, + uint32_t wide_func, + enum zapi_srv6_sid_notify note); extern int zsend_client_close_notify(struct zserv *client, struct zserv *closed_client); diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index d93f09f1b4fd..663afa2f855d 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -2279,6 +2279,8 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, const char *locator_name) { int ret = -1; + struct listnode *node; + struct zserv *c; char buf[256]; if (IS_ZEBRA_DEBUG_PACKET) @@ -2291,6 +2293,10 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, zlog_warn("%s: not got SRv6 SID for ctx %s, sid_value=%pI6, locator_name=%s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value, locator_name); + + /* Notify client about SID alloc failure */ + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + ZAPI_SRV6_SID_FAIL_ALLOC); } else if (ret == 0) { if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: got existing SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notify client", @@ -2300,6 +2306,10 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, client->instance, client->session_id); if (!listnode_lookup((*sid)->client_list, client)) listnode_add((*sid)->client_list, client); + + zsend_srv6_sid_notify(client, ctx, &(*sid)->value, (*sid)->func, + (*sid)->wide_func, + ZAPI_SRV6_SID_ALLOCATED); } else { if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: got new SRv6 SID for ctx %s: sid_value=%pI6 (func=%u) (proto=%u, instance=%u, sessionId=%u), notifying all clients", @@ -2309,6 +2319,11 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, client->instance, client->session_id); if (!listnode_lookup((*sid)->client_list, client)) listnode_add((*sid)->client_list, client); + + for (ALL_LIST_ELEMENTS_RO((*sid)->client_list, node, c)) + zsend_srv6_sid_notify(c, ctx, &(*sid)->value, + (*sid)->func, (*sid)->wide_func, + ZAPI_SRV6_SID_ALLOCATED); } return ret; @@ -2382,6 +2397,13 @@ static int srv6_manager_release_sid_internal(struct zserv *client, zlog_debug("%s: no SID associated with ctx %s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); + if (ret == 0) + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + ZAPI_SRV6_SID_RELEASED); + else + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + ZAPI_SRV6_SID_FAIL_RELEASE); + return ret; } From 5365c56614191c7184126fd1a32db20953f008eb Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 2 May 2024 23:50:38 +0200 Subject: [PATCH 274/472] zebra: Notify all daemons about locator delete Currently, when a locator is deleted in zebra, zebra notifies only the zclient that owns the locator. With the introduction of SID Manager, the locator is no longer owned by any client. Instead, the locator is owned by Zebra, and clients can allocate and release SIDs from the locator using the ZAPI ZEBRA_SRV6_MANAGER_GET_SID and ZEBRA_SRV6_MANAGER_RELEASE_SID. Therefore, when a locator is removed in Zebra, we need to notify all daemons so that they can release/uninstall the SIDs allocated by that locator. Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 663afa2f855d..aac4ba86a9b4 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -634,7 +634,6 @@ void zebra_srv6_locator_add(struct srv6_locator *locator) void zebra_srv6_locator_delete(struct srv6_locator *locator) { struct listnode *n; - struct srv6_locator_chunk *c; struct zebra_srv6 *srv6 = zebra_srv6_get_default(); struct zserv *client; @@ -649,18 +648,8 @@ void zebra_srv6_locator_delete(struct srv6_locator *locator) * by ZEBRA_SRV6_LOCATOR_DELETE, and this notification is sent to the * owner of each chunk. */ - for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, n, c)) { - if (c->proto == ZEBRA_ROUTE_SYSTEM) - continue; - client = zserv_find_client(c->proto, c->instance); - if (!client) { - zlog_warn( - "%s: Not found zclient(proto=%u, instance=%u).", - __func__, c->proto, c->instance); - continue; - } + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, n, client)) zsend_zebra_srv6_locator_delete(client, locator); - } listnode_delete(srv6->locators, locator); srv6_locator_free(locator); @@ -703,7 +692,6 @@ void zebra_notify_srv6_locator_add(struct srv6_locator *locator) void zebra_notify_srv6_locator_delete(struct srv6_locator *locator) { struct listnode *n; - struct srv6_locator_chunk *c; struct zserv *client; /* @@ -717,17 +705,8 @@ void zebra_notify_srv6_locator_delete(struct srv6_locator *locator) * by ZEBRA_SRV6_LOCATOR_DELETE, and this notification is sent to the * owner of each chunk. */ - for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, n, c)) { - if (c->proto == ZEBRA_ROUTE_SYSTEM) - continue; - client = zserv_find_client(c->proto, c->instance); - if (!client) { - zlog_warn("Not found zclient(proto=%u, instance=%u).", - c->proto, c->instance); - continue; - } + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, n, client)) zsend_zebra_srv6_locator_delete(client, locator); - } } struct zebra_srv6 srv6; From 33bd67a006ca3958e094232f80a32c879783227a Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 2 May 2024 17:08:15 +0200 Subject: [PATCH 275/472] doc: Add documentation for SRv6 SID formats CLI Signed-off-by: Carmine Scarpitta --- doc/user/zebra.rst | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 37644dc88a78..900d2fd34305 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -1021,6 +1021,35 @@ and this section also helps that case. ! ... +.. clicmd:: format NAME + + Specify the SID allocation schema for the SIDs allocated from this locator. Currently, + FRR supports supports the following allocation schemas: + + - `usid-f3216` + - `uncompressed` + +:: + + router# configure terminal + router(config)# segment-routinig + router(config-sr)# srv6 + router(config-srv6)# locators + router(config-srv6-locators)# locator loc1 + router(config-srv6-locator)# prefix fc00:0:1::/48 + router(config-srv6-locator)# format usid-f3216 + + router(config-srv6-locator)# show run + ... + segment-routing + srv6 + locators + locator loc1 + prefix fc00:0:1::/48 + format usid-f3216 + ! + ... + .. clicmd:: encapsulation Configure parameters for SRv6 encapsulation. @@ -1029,6 +1058,61 @@ and this section also helps that case. Configure the source address of the outer encapsulating IPv6 header. +.. clicmd:: formats + + Configure SRv6 SID formats. + +.. clicmd:: format NAME + + Configure SRv6 SID format. + +.. clicmd:: compressed usid + + Enable SRv6 uSID compression and configure SRv6 uSID compression parameters. + +.. clicmd:: local-id-block start START + + Configure the start value for the Local ID Block (LIB). + +.. clicmd:: local-id-block explicit start START end END + + Configure the start/end values for the Explicit LIB (ELIB). + +.. clicmd:: wide-local-id-block start START end END + + Configure the start/end values for the Wide LIB (W-LIB). + +.. clicmd:: wide-local-id-block explicit start START + + Configure the start value for the Explicit Wide LIB (EW-LIB). + +:: + + router# configure terminal + router(config)# segment-routinig + router(config-sr)# srv6 + router(config-srv6)# formats + router(config-srv6-formats)# format usid-f3216 + router(config-srv6-format)# compressed usid + router(config-srv6-format-usid)# local-id-block start 0xD000 + router(config-srv6-format-usid)# local-id-block explicit start 0xF000 end 0xFDFF + router(config-srv6-format-usid)# wide-local-id-block start 0xFFF4 end 0xFFF5 + router(config-srv6-format-usid)# wide-local-id-block explicit start 0xFFF4 + + router(config-srv6-locator)# show run + ... + segment-routing + srv6 + formats + format usid-f3216 + compressed usid + local-id-block start 0xD000 + local-id-block explicit start 0xF000 end 0xFDFF + wide-local-id-block start 0xFFF4 end 0xFFF5 + wide-local-id-block explicit start 0xFFF4 + ! + ... + .. _multicast-rib-commands: Multicast RIB Commands From 4dcb69e0f91c8698be537a3e46b075b703afe8b3 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 3 May 2024 19:31:56 +0200 Subject: [PATCH 276/472] zebra: Fix checkpatch warning Signed-off-by: Carmine Scarpitta --- lib/zclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zclient.c b/lib/zclient.c index e4d02d743a93..a1386e501a72 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -3447,7 +3447,7 @@ int srv6_manager_release_sid(struct zclient *zclient, /* * Asynchronous label chunk request * - * @param zclient Zclient used to connect to label manager (zebra) + * @param zclient The zclient used to connect to label manager (zebra) * @param keep Avoid garbage collection * @param chunk_size Amount of labels requested * @param base Base for the label chunk. if MPLS_LABEL_BASE_ANY we do not care From 708f20e58aa928d795eaa9ceb6c6de67341fb4ac Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 7 Jun 2024 15:46:20 +0200 Subject: [PATCH 277/472] zebra: fix display srv6 address only for explicit-sid Signed-off-by: Philippe Guibert --- zebra/zebra_srv6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index aac4ba86a9b4..cbf471ae3db8 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -2265,13 +2265,13 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: getting SRv6 SID for ctx %s, sid_value=%pI6, locator_name=%s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), - sid_value, locator_name); + sid_value ? sid_value : &in6addr_any, locator_name); ret = get_srv6_sid(sid, ctx, sid_value, locator_name); if (ret < 0) { zlog_warn("%s: not got SRv6 SID for ctx %s, sid_value=%pI6, locator_name=%s", __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), - sid_value, locator_name); + sid_value ? sid_value : &in6addr_any, locator_name); /* Notify client about SID alloc failure */ zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, From 35a87b6acda9b6a7be594e743798fb5b66fa7e79 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 7 Jun 2024 15:46:53 +0200 Subject: [PATCH 278/472] zebra: fix display explicit sid refused > 2024/06/07 15:09:43 ZEBRA: [MZYPC-GBDGR] srv6_manager_get_sid_internal: getting SRv6 SID for ctx End.DT4 vrf vrf1, sid_value=1003::4, locator_name= > [..] > 2024/06/07 15:09:43 ZEBRA: [QGJBT-YJ11W] zsend_srv6_sid_notify: notifying ZEBRA_SRV6_SID_NOTIFY ctx End.DT4 vrf vrf2, sid (null) note ZAPI_SRV6_SID_FAIL_ALLOC (proto=30, instance=0, sessionId=0) Signed-off-by: Philippe Guibert --- zebra/zebra_srv6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index cbf471ae3db8..4273e52a0172 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -2274,7 +2274,7 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, sid_value ? sid_value : &in6addr_any, locator_name); /* Notify client about SID alloc failure */ - zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + zsend_srv6_sid_notify(client, ctx, sid_value, 0, 0, ZAPI_SRV6_SID_FAIL_ALLOC); } else if (ret == 0) { if (IS_ZEBRA_DEBUG_PACKET) From 209223dae298ed33388563f2947923c0471b2ce7 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 11 Jun 2024 18:14:58 +0200 Subject: [PATCH 279/472] zebra: fix sid allocation should be different with 2 isis instances With 2 ISIS SRv6 instances, the second ISIS instance always gets the same End SID as the first one. > router isis 1 > segment-routing srv6 > locator loc1 > exit > exit > router isis 2 > segment-routing srv6 > locator loc2 > end > segment-routing > srv6 > locators > locator loc1 > prefix 2001::1/64 > exit > locator loc2 > prefix 3001::1/64 > output: > 2024/06/11 17:30:15 ISIS: [N6PCR-FQ5ZA] SRv6 locator (locator loc1, prefix 2001::1/64) set for IS-IS area 1 > 2024/06/11 17:30:15 ISIS: [V4RBG-TYW5S] Requesting SRv6 SIDs for IS-IS area 1 > 2024/06/11 17:30:15 ISIS: [ZRHYM-6RMYK] isis_zebra_srv6_sid_notify: received SRv6 SID notify: ctx End USP sid_value 2001::1 sid_func 0 note ZAPI_SRV6_SID_ALLOCATED > [..] > 2024/06/11 17:36:49 ISIS: [N6PCR-FQ5ZA] SRv6 locator (locator loc2, prefix 3001::1/64) set for IS-IS area 2 > 2024/06/11 17:36:49 ISIS: [V4RBG-TYW5S] Requesting SRv6 SIDs for IS-IS area 2 > 2024/06/11 17:36:49 ISIS: [ZRHYM-6RMYK] isis_zebra_srv6_sid_notify: received SRv6 SID notify: ctx End USP sid_value 2001::1 sid_func 0 note ZAPI_SRV6_SID_ALLOCATED Actually, at the second request, ZEBRA always gives an existing dynamic SID of the first available locator, because the locator name is never checked. > 2024/06/11 17:36:49 ZEBRA: [XMBTQ-GE6EY] get_srv6_sid: received SRv6 SID alloc request: SID ctx End USP ((null)), mode=dynamic > 2024/06/11 17:36:49 ZEBRA: [R61Q3-QWR23] get_srv6_sid_dynamic: returning existing SID End USP 2001::1 > 2024/06/11 17:36:49 ZEBRA: [J1GMY-B6CAK] srv6_manager_get_sid_internal: got existing SRv6 SID for ctx End USP: sid_value=2001::1 (func=0) (proto=9, instance=0, sessionId=0), notify client Fix this by checking the locator of the existing SID. Fixes: b771bf8ce687 ("zebra: Add functions to alloc/release SRv6 SIDs") Signed-off-by: Philippe Guibert --- zebra/zebra_srv6.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 4273e52a0172..a6db66bbccea 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -1645,6 +1645,12 @@ static int get_srv6_sid_dynamic(struct zebra_srv6_sid **sid, * SID instead of allocating a new one. */ for (ALL_LIST_ELEMENTS_RO(srv6->sids, node, s)) { + if (locator && s->sid && s->sid->locator) { + if (strncmp(s->sid->locator->name, locator->name, + SRV6_LOCNAME_SIZE)) { + continue; + } + } if (memcmp(&s->ctx, ctx, sizeof(struct srv6_sid_ctx)) == 0) { if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: returning existing SID %s %pI6", From a23a9385a74dcf31be1224cd7536fa585e6f0283 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 13 Jun 2024 15:30:00 -0400 Subject: [PATCH 280/472] zebra: Use built in data structure counter Instead of keeping a counter that is independent of the queue's data structure. Just use the queue's built-in counter. Ensure that it's pthread safe by keeping it wrapped inside the mutex for adding/deleting to the queue. Signed-off-by: Donald Sharp --- zebra/dplane_fpm_nl.c | 40 ++++++++++++++++++---------------------- zebra/zebra_dplane.c | 5 +++++ zebra/zebra_dplane.h | 2 ++ 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 9ad92d6269dd..28c481d1d873 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -136,8 +136,6 @@ struct fpm_nl_ctx { /* Amount of data plane context processed. */ _Atomic uint32_t dplane_contexts; - /* Amount of data plane contexts enqueued. */ - _Atomic uint32_t ctxqueue_len; /* Peak amount of data plane contexts enqueued. */ _Atomic uint32_t ctxqueue_len_peak; @@ -399,6 +397,12 @@ DEFUN(fpm_show_counters, fpm_show_counters_cmd, FPM_STR "FPM statistic counters\n") { + uint32_t curr_queue_len; + + frr_with_mutex (&gfnc->ctxqueue_mutex) { + curr_queue_len = dplane_ctx_queue_count(&gfnc->ctxqueue); + } + vty_out(vty, "%30s\n%30s\n", "FPM counters", "============"); #define SHOW_COUNTER(label, counter) \ @@ -412,8 +416,7 @@ DEFUN(fpm_show_counters, fpm_show_counters_cmd, SHOW_COUNTER("Connection errors", gfnc->counters.connection_errors); SHOW_COUNTER("Data plane items processed", gfnc->counters.dplane_contexts); - SHOW_COUNTER("Data plane items enqueued", - gfnc->counters.ctxqueue_len); + SHOW_COUNTER("Data plane items enqueued", curr_queue_len); SHOW_COUNTER("Data plane items queue peak", gfnc->counters.ctxqueue_len_peak); SHOW_COUNTER("Buffer full hits", gfnc->counters.buffer_full); @@ -432,6 +435,12 @@ DEFUN(fpm_show_counters_json, fpm_show_counters_json_cmd, "FPM statistic counters\n" JSON_STR) { + uint32_t curr_queue_len; + + frr_with_mutex (&gfnc->ctxqueue_mutex) { + curr_queue_len = dplane_ctx_queue_count(&gfnc->ctxqueue); + } + struct json_object *jo; jo = json_object_new_object(); @@ -445,8 +454,7 @@ DEFUN(fpm_show_counters_json, fpm_show_counters_json_cmd, gfnc->counters.connection_errors); json_object_int_add(jo, "data-plane-contexts", gfnc->counters.dplane_contexts); - json_object_int_add(jo, "data-plane-contexts-queue", - gfnc->counters.ctxqueue_len); + json_object_int_add(jo, "data-plane-contexts-queue", curr_queue_len); json_object_int_add(jo, "data-plane-contexts-queue-peak", gfnc->counters.ctxqueue_len_peak); json_object_int_add(jo, "buffer-full-hits", gfnc->counters.buffer_full); @@ -1495,8 +1503,6 @@ static void fpm_process_queue(struct event *t) /* Account the processed entries. */ processed_contexts++; - atomic_fetch_sub_explicit(&fnc->counters.ctxqueue_len, 1, - memory_order_relaxed); dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_SUCCESS); dplane_provider_enqueue_out_ctx(fnc->prov, ctx); @@ -1670,7 +1676,7 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) struct zebra_dplane_ctx *ctx; struct fpm_nl_ctx *fnc; int counter, limit; - uint64_t cur_queue, peak_queue = 0, stored_peak_queue; + uint64_t cur_queue = 0, peak_queue = 0, stored_peak_queue; fnc = dplane_provider_get_data(prov); limit = dplane_provider_get_work_limit(prov); @@ -1684,20 +1690,12 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) * anyway. */ if (fnc->socket != -1 && fnc->connecting == false) { - /* - * Update the number of queued contexts *before* - * enqueueing, to ensure counter consistency. - */ - atomic_fetch_add_explicit(&fnc->counters.ctxqueue_len, - 1, memory_order_relaxed); - frr_with_mutex (&fnc->ctxqueue_mutex) { dplane_ctx_enqueue_tail(&fnc->ctxqueue, ctx); + cur_queue = + dplane_ctx_queue_count(&fnc->ctxqueue); } - cur_queue = atomic_load_explicit( - &fnc->counters.ctxqueue_len, - memory_order_relaxed); if (peak_queue < cur_queue) peak_queue = cur_queue; continue; @@ -1714,9 +1712,7 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) atomic_store_explicit(&fnc->counters.ctxqueue_len_peak, peak_queue, memory_order_relaxed); - if (atomic_load_explicit(&fnc->counters.ctxqueue_len, - memory_order_relaxed) - > 0) + if (cur_queue > 0) event_add_event(fnc->fthread->master, fpm_process_queue, fnc, 0, &fnc->t_dequeue); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 06b34da20932..ee48a571b832 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -969,6 +969,11 @@ struct zebra_dplane_ctx *dplane_ctx_dequeue(struct dplane_ctx_list_head *q) return ctx; } +uint32_t dplane_ctx_queue_count(struct dplane_ctx_list_head *q) +{ + return dplane_ctx_list_count(q); +} + /* * Accessors for information from the context object */ diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 060b1c8b9e03..0e9a8bfb99f5 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -323,6 +323,8 @@ struct zebra_dplane_ctx *dplane_ctx_get_head(struct dplane_ctx_list_head *q); /* Init a list of contexts */ void dplane_ctx_q_init(struct dplane_ctx_list_head *q); +uint32_t dplane_ctx_queue_count(struct dplane_ctx_list_head *q); + /* * Accessors for information from the context object */ From 7a905c0d019d1f85092f7fea8f35320d956c5859 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 6 Jun 2024 15:18:48 +0200 Subject: [PATCH 281/472] isisd: fix 'show isis route prefix-sid backup' command It is not possible to dump both backup and prefix-sid information. Fix this by authorising it. > rt1# show isis route prefix-sid backup > Area 1: > IS-IS paths to level-1 routers that speak IP > Vertex Type Metric Next-Hop Interface Parent > rt1 > 10.12.0.0/24 IP internal 0 rt1(4) > 10.13.0.0/24 IP internal 0 rt1(4) > 1.1.1.1/32 IP internal 0 rt1(4) > rt2 TE-IS 10 rt2 eth-rt2 rt1(4) > rt3 TE-IS 10 rt3 eth-rt3 rt1(4) > 10.12.0.0/24 IP TE 20 rt2 eth-rt2 rt2(4) > 10.23.0.0/24 IP TE 20 rt2 eth-rt2 rt2(4) > rt3 eth-rt3 rt3(4) > 2.2.2.2/32 IP TE 20 rt2 eth-rt2 rt2(4) > 10.13.0.0/24 IP TE 20 rt3 eth-rt3 rt3(4) > 3.3.3.3/32 IP TE 20 rt3 eth-rt3 rt3(4) > > IS-IS L1 IPv4 routing table: > > IS-IS paths to level-1 routers that speak IPv6 > Vertex Type Metric Next-Hop Interface Parent > rt1 > 2001:db8:1000::1/128 IP6 internal 0 rt1(4) > rt2 TE-IS 10 rt2 eth-rt2 rt1(4) > rt3 TE-IS 10 rt3 eth-rt3 rt1(4) > 2001:db8:1000::2/128 IP6 internal 20 rt2 eth-rt2 rt2(4) > 2001:db8:1000::3/128 IP6 internal 20 rt3 eth-rt3 rt3(4) > > IS-IS L1 IPv6 routing table: > Fixes: d47d6089e06c ("isisd: refactor handling of SR Prefix-SIDs") Signed-off-by: Philippe Guibert --- doc/user/isisd.rst | 2 +- isisd/isis_spf.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 741261186929..3a0f277bf0cf 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -325,7 +325,7 @@ Showing ISIS information Show topology IS-IS paths to Intermediate Systems, globally, in area (level-1) or domain (level-2). -.. clicmd:: show isis [vrf ] route [level-1|level-2] [prefix-sid|backup] [algorithm [(128-255)]] +.. clicmd:: show isis [vrf ] route [level-1|level-2] [prefix-sid] [backup] [algorithm [(128-255)]] Show the ISIS routing table, as determined by the most recent SPF calculation. diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index e349373372d6..81201023d657 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -3074,7 +3074,7 @@ DEFUN(show_isis_route, show_isis_route_cmd, #ifndef FABRICD " []" #endif /* ifndef FABRICD */ - " []" + " [prefix-sid] [backup]" #ifndef FABRICD " [algorithm [(128-255)]]" #endif /* ifndef FABRICD */ From 686d477242890c575024962188dd50c06160f2a3 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 14 Jun 2024 10:30:31 +0300 Subject: [PATCH 282/472] docker: Use Alpine Linux 3.20 Signed-off-by: Donatas Abraitis --- docker/alpine/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile index 1cff06feee21..3f811455b394 100644 --- a/docker/alpine/Dockerfile +++ b/docker/alpine/Dockerfile @@ -1,7 +1,7 @@ # syntax=docker/dockerfile:1 # Create a basic stage set up to build APKs -FROM alpine:3.19 as alpine-builder +FROM alpine:3.20 as alpine-builder RUN apk add \ --update-cache \ abuild \ @@ -24,7 +24,7 @@ RUN cd /src/libyang \ && abuild -r -P /pkgs/apk # This stage builds a dist tarball from the source -FROM alpine:3.19 as source-builder +FROM alpine:3.20 as source-builder RUN mkdir -p /src/alpine /pkgs/apk COPY alpine/APKBUILD.in /src/alpine COPY --from=alpine-apk-builder-libyang /pkgs/apk/src /pkgs/apk @@ -57,7 +57,7 @@ RUN cd /dist \ && abuild -r -P /pkgs/apk # This stage installs frr from the apk -FROM alpine:3.19 +FROM alpine:3.20 RUN mkdir -p /pkgs/apk COPY --from=alpine-apk-builder /pkgs/apk/ /pkgs/apk/ RUN apk add \ From 2876847d500b7b734fa290e6dc9aa151de9f9a48 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 14 Jun 2024 10:35:27 +0300 Subject: [PATCH 283/472] docker: Do not require checks for libyang Alpine Linux package build Since Alpine Linux 3.20, we get this: >>> WARNING: libyang: APKBUILD does not run any tests! Alpine policy will soon require that packages have any relevant testsuites run during the build process. To fix, either define a check() function, or declare !check in $options to indicate the package does not have a testsuite. Signed-off-by: Donatas Abraitis --- docker/alpine/libyang/APKBUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/alpine/libyang/APKBUILD b/docker/alpine/libyang/APKBUILD index 6973fd62d865..7979ee1b1ed2 100755 --- a/docker/alpine/libyang/APKBUILD +++ b/docker/alpine/libyang/APKBUILD @@ -11,6 +11,7 @@ makedepends="bison cmake cmocka-dev flex pcre2-dev" checkdepends="expect grep shunit2" subpackages="$pkgname-dev $pkgname-doc" source="$pkgname-$pkgver.tar.gz::https://github.com/CESNET/libyang/archive/v$pkgver.tar.gz" +options="!check" # secfixes: # 1.0.215-r1: From 0314adac4b906ac6c9abcb702f9fd799b89d93f2 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 14 Jun 2024 11:37:23 +0300 Subject: [PATCH 284/472] docker: Set ABUILD_APK_INDEX_OPTS for libyang In build() stage of abuild, it does `apk index ...` where libyang* packages are unsigned. We don't sign them here, and thus we need to specify `--allow-untrusted`. Signed-off-by: Donatas Abraitis --- docker/alpine/libyang/APKBUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/alpine/libyang/APKBUILD b/docker/alpine/libyang/APKBUILD index 7979ee1b1ed2..d8cd4d918a53 100755 --- a/docker/alpine/libyang/APKBUILD +++ b/docker/alpine/libyang/APKBUILD @@ -22,6 +22,7 @@ options="!check" # - CVE-2021-28906 build() { + export ABUILD_APK_INDEX_OPTS="--allow-untrusted" if [ "$CBUILD" != "$CHOST" ]; then CMAKE_CROSSOPTS="-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_HOST_SYSTEM_NAME=Linux" fi From 09db258157576999975a9d95add4ae327f7f3a5c Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 14 Jun 2024 16:33:32 +0300 Subject: [PATCH 285/472] docker: Set ABUILD_APK_INDEX_OPTS for frr build In build() stage of abuild, it does `apk index ...` where frr* packages are unsigned. We don't sign them here, and thus we need to specify `--allow-untrusted`. Signed-off-by: Donatas Abraitis --- alpine/APKBUILD.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/alpine/APKBUILD.in b/alpine/APKBUILD.in index 2cb3feec157f..855b5859039c 100644 --- a/alpine/APKBUILD.in +++ b/alpine/APKBUILD.in @@ -33,6 +33,8 @@ _libdir=/usr/lib _user=frr build() { + export ABUILD_APK_INDEX_OPTS="--allow-untrusted" + cd "$builddir" ./configure \ From 6faad863f30d29157e4c675ad956e3ccd38991a7 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 14 Jun 2024 13:36:51 -0400 Subject: [PATCH 286/472] zebra: Prevent starvation in dplane_thread_loop When removing a large number of routes, the linux kernel can take the cpu for an extended amount of time, leaving a situation where FRR detects a starvation event. r1# sharp install routes 10.0.0.0 nexthop 192.168.44.33 1000000 repeat 10 2024-06-14 12:55:49.365 [NTFY] sharpd: [M7Q4P-46WDR] vty[5]@# sharp install routes 10.0.0.0 nexthop 192.168.44.33 1000000 repeat 10 2024-06-14 12:55:49.365 [DEBG] sharpd: [YP4TQ-01TYK] Inserting 1000000 routes 2024-06-14 12:55:57.256 [DEBG] sharpd: [TPHKD-3NYSB] Installed All Items 7.890085 2024-06-14 12:55:57.256 [DEBG] sharpd: [YJ486-NX5R1] Removing 1000000 routes 2024-06-14 12:56:07.802 [WARN] zebra: [QH9AB-Y4XMZ][EC 100663314] STARVATION: task dplane_thread_loop (634377bc8f9e) ran for 7078ms (cpu time 220ms) 2024-06-14 12:56:25.039 [DEBG] sharpd: [WTN53-GK9Y5] Removed all Items 27.783668 2024-06-14 12:56:25.039 [DEBG] sharpd: [YP4TQ-01TYK] Inserting 1000000 routes 2024-06-14 12:56:32.783 [DEBG] sharpd: [TPHKD-3NYSB] Installed All Items 7.743524 2024-06-14 12:56:32.783 [DEBG] sharpd: [YJ486-NX5R1] Removing 1000000 routes 2024-06-14 12:56:41.447 [WARN] zebra: [QH9AB-Y4XMZ][EC 100663314] STARVATION: task dplane_thread_loop (634377bc8f9e) ran for 5175ms (cpu time 179ms) Let's modify the loop in dplane_thread_loop such that after a provider has been run, check to see if the event should yield, if so, stop and reschedule this for the future. Signed-off-by: Donald Sharp --- zebra/zebra_dplane.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 06b34da20932..394487643934 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -7441,6 +7441,11 @@ static void dplane_thread_loop(struct event *event) zlog_debug("dplane dequeues %d completed work from provider %s", counter, dplane_provider_get_name(prov)); + if (event_should_yield(event)) { + reschedule = true; + break; + } + /* Locate next provider */ prov = dplane_prov_list_next(&zdplane_info.dg_providers, prov); } From accdf83c5774cf814775e7273057e6191dc1f0f2 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sat, 15 Jun 2024 13:56:25 +0800 Subject: [PATCH 287/472] doc: fix one ldp neighbor command Signed-off-by: anlan_cs --- doc/user/ldpd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user/ldpd.rst b/doc/user/ldpd.rst index cbed734e4292..7a000a49c450 100644 --- a/doc/user/ldpd.rst +++ b/doc/user/ldpd.rst @@ -148,7 +148,7 @@ LDP Configuration configured password. PASSWORD is a clear text password wit its digest sent through the network. -.. clicmd:: neighbor A.B.C.D holdtime HOLDTIME +.. clicmd:: neighbor A.B.C.D session holdtime HOLDTIME The following command located under MPLS router node configures the holdtime value in seconds of the LDP neighbor ID. Configuring it triggers a keepalive From 1919df3a64d3fe6d4084c1d0b050b3e368860170 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sat, 15 Jun 2024 20:34:20 +0800 Subject: [PATCH 288/472] ldpd: fix wrong gtsm count In linux networking stack, the received mpls packets will be processed by the host *twice*, one as mpls packet, the other as ip packet, so its ttl decreased 1. So, we need release the `IP_MINTTL` value if gtsm is enabled, it is for the mpls packets of neighbor session caused by the command: `label local advertise explicit-null`. This change makes the gtsm mechanism a bit deviation. Fix PR #8313 Signed-off-by: anlan_cs --- ldpd/neighbor.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index d40728b0436b..2596c7948116 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -681,6 +681,18 @@ nbr_gtsm_setup(int fd, int af, struct nbr_params *nbrp) if (nbrp && CHECK_FLAG(nbrp->flags, F_NBRP_GTSM_HOPS)) ttl = 256 - nbrp->gtsm_hops; + /* + * In linux networking stack, the received mpls packets + * will be processed by the host twice, one as mpls packet, + * the other as ip packet, so its ttl will be decreased 1. + * This behavior is based on the new kernel (5.10 and 6.1), + * and older versions may behave differently. + * + * Here, decrease 1 for IP_MINTTL if GTSM is enabled. + * And this workaround makes the GTSM mechanism a bit deviation. + */ + ttl -= 1; + switch (af) { case AF_INET: if (sock_set_ipv4_minttl(fd, ttl) == -1) From 5d1298de68b95ab19a3338abb0b794ddb046187c Mon Sep 17 00:00:00 2001 From: zhou-run <166502045+zhou-run@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:45:09 +0800 Subject: [PATCH 289/472] isisd: After the router switches IS-IS type several times, the neighbor adjacency cannot be established. 1. Router A is configured with "is-type level-1-2", while Router B is configured with "is-type level-1". Only level 1 neighbor entries are present on Router A. 2. After configuring Router B with "is-type level-2-only", both level 1 and level 2 neighbor entries exist on Router A. The state of these entries is UP, and the level 1 neighbor entry is currently aging. 3. Before the level 1 neighbor entry on Router A ages out, configuring Router B with "is-type level-1", both level 1 and level 2 neighbor entries exist on Router A. The level 2 neighbor entry is UP and will age out normally. However, the level 1 neighbor entry remains in the Initializing state, preventing the establishment of level 1 neighbor adjacency between Router A and Router B. When the adjacency type of the link is switched in function isis_circuit_is_type_set, the function circuit_resign_level() is called to delete the old level's circuit->u.bc.lan_neighs linked list. If the old level is not level-1-2, the function circuit_commence_level() is called to create a new level's circuit->u.bc.lan_neighs linked list, but neither of these functions handle the circuit->u.bc.adjdb linked list. This leads to a situation where upon receiving hello packets again before the circuit->u.bc.adjdb linked list entries age out, the circuit->u.bc.lan_neighs linked list is not constructed based on the circuit->u.bc.adjdb linked list. As a result, the hello packets sent will consistently lack an SNPA, causing the neighbor to remain unable to establish an adjacency upon receiving the hello packets. Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com> --- isisd/isis_events.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 32231a079f1a..5574bbc50fca 100644 --- a/isisd/isis_events.c +++ b/isisd/isis_events.c @@ -83,6 +83,7 @@ static void circuit_commence_level(struct isis_circuit *circuit, int level) send_hello_sched(circuit, level, TRIGGERED_IIH_DELAY); circuit->u.bc.lan_neighs[level - 1] = list_new(); + circuit->u.bc.adjdb[level - 1] = list_new(); } } @@ -108,6 +109,10 @@ static void circuit_resign_level(struct isis_circuit *circuit, int level) circuit->u.bc.is_dr[idx] = 0; if (circuit->u.bc.lan_neighs[idx] != NULL) list_delete(&circuit->u.bc.lan_neighs[idx]); + if (circuit->u.bc.adjdb[idx]) { + circuit->u.bc.adjdb[idx]->del = isis_delete_adj; + list_delete(&circuit->u.bc.adjdb[idx]); + } } return; From 8381dbd9e258825daff4802c4c44b3d435a7b7e3 Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Sat, 15 Jun 2024 22:36:32 +0530 Subject: [PATCH 290/472] tests: Avoid importing unused modules Signed-off-by: y-bharath14 --- .../topotests/eigrp_topo1/test_eigrp_topo1.py | 1 - .../test_evpn_type5_topo1.py | 3 +-- .../fpm_testing_topo1/test_fpm_topo1.py | 2 -- tests/topotests/grpc_basic/test_basic_grpc.py | 3 +-- .../test_isis_advertise_high_metrics.py | 3 --- .../isis_lfa_topo1/test_isis_lfa_topo1.py | 7 +++--- .../test_isis_lsp_bits_topo1.py | 2 +- .../isis_rlfa_topo1/test_isis_rlfa_topo1.py | 2 +- tests/topotests/isis_snmp/test_isis_snmp.py | 2 +- .../test_isis_sr_flex_algo_topo1.py | 3 +-- .../test_isis_sr_flex_algo_topo2.py | 6 ++--- .../isis_sr_te_topo1/test_isis_sr_te_topo1.py | 4 ++-- .../isis_sr_topo1/test_isis_sr_topo1.py | 2 +- .../isis_srv6_topo1/test_isis_srv6_topo1.py | 5 ++-- .../isis_tilfa_topo1/test_isis_tilfa_topo1.py | 3 +-- tests/topotests/isis_topo1/test_isis_topo1.py | 16 ++++++------- .../isis_topo1_vrf/test_isis_topo1_vrf.py | 4 ++-- .../topotests/key_sendaccept/test_keychain.py | 2 +- .../ldp_oc_acl_topo1/test_ldp_oc_acl_topo1.py | 2 +- .../ldp_oc_topo1/test_ldp_oc_topo1.py | 2 +- .../topotests/ldp_snmp/test_ldp_snmp_topo1.py | 2 +- .../test_ldp_sync_isis_topo1.py | 2 +- .../test_ldp_sync_ospf_topo1.py | 2 +- .../ldp_vpls_topo1/test_ldp_vpls_topo1.py | 2 +- tests/topotests/lib/bgp.py | 20 ++++++++-------- tests/topotests/lib/checkping.py | 2 +- tests/topotests/lib/common_config.py | 13 +++++----- tests/topotests/lib/fe_client.py | 11 ++++----- tests/topotests/lib/ospf.py | 4 ++-- tests/topotests/lib/pim.py | 24 +++++++++---------- .../topotests/mgmt_debug_flags/test_debug.py | 2 +- tests/topotests/mgmt_notif/test_notif.py | 3 +-- tests/topotests/mgmt_oper/oper.py | 4 ++-- tests/topotests/mgmt_oper/test_oper.py | 6 ----- tests/topotests/mgmt_rpc/test_rpc.py | 2 +- tests/topotests/mgmt_tests/test_yang_mgmt.py | 1 - tests/topotests/msdp_topo1/test_msdp_topo1.py | 2 +- .../test_multicast_pim6_sm1.py | 2 +- .../test_multicast_pim6_sm2.py | 2 +- .../test_pim_dr_nondr_with_ospf_topo2.py | 11 --------- .../test_multicast_pim_sm_topo1.py | 3 +-- .../test_multicast_pim_sm_topo2.py | 3 +-- .../test_multicast_pim_sm_topo3.py | 5 ++-- .../test_multicast_pim_sm_topo4.py | 5 ++-- .../test_multicast_pim_static_rp.py | 7 ------ .../test_multicast_pim_static_rp1.py | 5 ---- .../test_multicast_pim_static_rp2.py | 5 ---- .../test_multicast_pim_uplink_topo1.py | 5 ++-- .../test_multicast_pim_uplink_topo2.py | 2 +- tests/topotests/nb_config/test_nb_config.py | 2 +- .../nhrp_redundancy/test_nhrp_redundancy.py | 3 +-- .../ospf6_gr_topo1/test_ospf6_gr_topo1.py | 2 +- .../test_ospf6_loopback_cost.py | 4 ++-- .../test_ospf6_point_to_multipoint.py | 4 ++-- .../topotests/ospf6_topo1/test_ospf6_topo1.py | 6 ++--- .../ospf6_topo1_vrf/test_ospf6_topo1_vrf.py | 6 ++--- .../test_ospf_asbr_summary_topo1.py | 4 ++-- .../test_ospf_asbr_summary_type7_lsa.py | 2 +- .../test_ospf_authentication.py | 2 +- .../test_ospf_chaos.py | 2 +- .../test_ospf_ecmp.py | 4 ++-- .../test_ospf_flood_reduction.py | 5 +--- .../test_ospf_nssa.py | 2 +- .../test_ospf_p2mp.py | 2 +- .../test_ospf_routemaps.py | 2 +- .../test_ospf_rte_calc.py | 6 ++--- .../test_ospf_single_area.py | 2 +- .../ospf_dual_stack/test_ospf_dual_stack.py | 2 +- .../ospf_gr_helper/test_ospf_gr_helper1.py | 2 -- .../ospf_gr_helper/test_ospf_gr_helper3.py | 2 -- .../ospf_gr_topo1/test_ospf_gr_topo1.py | 2 +- .../test_ospf_instance_redistribute.py | 1 - .../test_ospf_metric_propagation.py | 5 ++-- .../test_ospf_multi_vrf_bgp_route_leak.py | 4 ++-- .../ospf_netns_vrf/test_ospf_netns_vrf.py | 4 ++-- .../ospf_nssa_topo1/test_ospf_nssa_topo1.py | 2 +- .../ospf_p2mp/test_ospf_p2mp_broadcast.py | 9 ++----- .../ospf_p2mp/test_ospf_p2mp_non_broadcast.py | 8 ++----- .../test_ospf_prefix_suppression.py | 9 ++----- .../test_ospf_single_switch.py | 5 ++-- .../ospf_sr_te_topo1/test_ospf_sr_te_topo1.py | 2 +- .../ospf_sr_topo1/test_ospf_sr_topo1.py | 2 +- .../ospf_suppress_fa/test_ospf_suppress_fa.py | 1 - .../ospf_tilfa_topo1/test_ospf_tilfa_topo1.py | 2 +- tests/topotests/ospf_topo1/test_ospf_topo1.py | 2 +- tests/topotests/ospf_topo2/test_ospf_topo2.py | 2 +- .../ospf_unnumbered/test_ospf_unnumbered.py | 2 +- ...est_ospf_unnumbered_point_to_multipoint.py | 2 +- .../topotests/ospfapi/test_ospf_clientapi.py | 4 +--- .../test_ospfv3_asbr_summary_topo1.py | 6 ++--- .../test_ospfv3_authentication.py | 11 +++------ .../test_ospfv3_ecmp.py | 4 ++-- .../test_ospfv3_ecmp_lan.py | 15 +----------- .../test_ospfv3_nssa.py | 2 +- .../test_ospfv3_nssa2.py | 14 ----------- .../test_ospfv3_routemaps.py | 2 +- .../test_ospfv3_rte_calc.py | 3 +-- .../test_ospfv3_single_area.py | 3 +-- tests/topotests/pim_acl/test_pim_acl.py | 2 +- tests/topotests/pim_basic/test_pim.py | 2 +- tests/topotests/pim_igmp_vrf/test_pim_vrf.py | 4 ++-- .../rip_allow_ecmp/test_rip_allow_ecmp.py | 4 ++-- .../rip_bfd_topo1/test_rip_bfd_topo1.py | 1 - .../test_rip_passive_interface.py | 4 ++-- .../ripng_allow_ecmp/test_ripng_allow_ecmp.py | 4 ++-- .../ripng_route_map/test_ripng_route_map.py | 5 ++-- .../route_scale/scale_test_common.py | 1 - .../route_scale/test_route_scale1.py | 6 ----- .../route_scale/test_route_scale2.py | 6 ----- .../simple_snmp_test/test_simple_snmp.py | 2 +- .../test_srv6_encap_src_addr.py | 3 +-- .../srv6_locator/test_srv6_locator.py | 6 ++--- .../test_srv6_locator_custom_bits_length.py | 6 ++--- .../test_srv6_locator_usid.py | 6 ++--- .../srv6_static_route/test_srv6_route.py | 4 ++-- .../test_static_routing_mpls.py | 5 +--- .../test_static_routes_topo2_ebgp.py | 2 +- .../test_static_routes_topo3_ebgp.py | 2 +- .../test_static_routes_topo4_ebgp.py | 2 +- .../test_static_routes_topo1_ibgp.py | 2 +- .../test_static_routes_topo2_ibgp.py | 2 +- .../test_static_routes_topo3_ibgp.py | 2 +- .../test_static_routes_topo4_ibgp.py | 2 +- .../static_simple/test_static_simple.py | 8 +++---- .../test_zebra_multiple_connected.py | 4 +--- .../zebra_netlink/test_zebra_netlink.py | 4 +--- .../test_verify_nh_resolution.py | 2 -- .../zebra_opaque/test_zebra_opaque.py | 10 ++++---- tests/topotests/zebra_rib/test_zebra_rib.py | 4 ++-- .../zebra_seg6_route/test_zebra_seg6_route.py | 4 ++-- .../test_zebra_seg6local_route.py | 2 +- 131 files changed, 200 insertions(+), 348 deletions(-) diff --git a/tests/topotests/eigrp_topo1/test_eigrp_topo1.py b/tests/topotests/eigrp_topo1/test_eigrp_topo1.py index b3152f43bcb9..7ab1572daedd 100644 --- a/tests/topotests/eigrp_topo1/test_eigrp_topo1.py +++ b/tests/topotests/eigrp_topo1/test_eigrp_topo1.py @@ -143,7 +143,6 @@ def test_zebra_ipv4_routingTable(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - failures = 0 router_list = tgen.routers().values() for router in router_list: output = router.vtysh_cmd("show ip route json", isjson=True) diff --git a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py index 10d216ab1ed4..beb4de432e22 100644 --- a/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py +++ b/tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py @@ -22,7 +22,6 @@ import os import sys -import json import time import pytest import platform @@ -69,7 +68,7 @@ verify_attributes_for_evpn_routes, verify_evpn_routes, ) -from lib.topojson import build_topo_from_json, build_config_from_json +from lib.topojson import build_config_from_json pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] diff --git a/tests/topotests/fpm_testing_topo1/test_fpm_topo1.py b/tests/topotests/fpm_testing_topo1/test_fpm_topo1.py index 22fc50b91427..66cefcc2a06f 100644 --- a/tests/topotests/fpm_testing_topo1/test_fpm_topo1.py +++ b/tests/topotests/fpm_testing_topo1/test_fpm_topo1.py @@ -14,7 +14,6 @@ """ import os -import re import sys import pytest import json @@ -28,7 +27,6 @@ # Import topogen and topotest helpers from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger pytestmark = [pytest.mark.fpm, pytest.mark.sharpd] diff --git a/tests/topotests/grpc_basic/test_basic_grpc.py b/tests/topotests/grpc_basic/test_basic_grpc.py index cf1c6d0ec75b..5ff2894fd1ab 100644 --- a/tests/topotests/grpc_basic/test_basic_grpc.py +++ b/tests/topotests/grpc_basic/test_basic_grpc.py @@ -19,7 +19,6 @@ from lib.common_config import step from lib.micronet import commander from lib.topogen import Topogen, TopoRouter -from lib.topolog import logger from lib.topotest import json_cmp CWD = os.path.dirname(os.path.realpath(__file__)) @@ -60,7 +59,7 @@ def tgen(request): tgen.start_topology() router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf", f"-M grpc:{GRPCP_ZEBRA}") router.load_config(TopoRouter.RD_STATIC, "", f"-M grpc:{GRPCP_STATICD}") # router.load_config(TopoRouter.RD_BFDD, "", f"-M grpc:{GRPCP_BFDD}") diff --git a/tests/topotests/isis_advertise_high_metrics/test_isis_advertise_high_metrics.py b/tests/topotests/isis_advertise_high_metrics/test_isis_advertise_high_metrics.py index ada8c0f5fbda..ad896b7422af 100644 --- a/tests/topotests/isis_advertise_high_metrics/test_isis_advertise_high_metrics.py +++ b/tests/topotests/isis_advertise_high_metrics/test_isis_advertise_high_metrics.py @@ -30,8 +30,6 @@ import sys import pytest import json -from time import sleep -from functools import partial # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -39,7 +37,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers -from lib import topotest from lib.common_config import ( retry, stop_router, diff --git a/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py b/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py index 44b3dd0b7927..af28dbdf3ce3 100755 --- a/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py +++ b/tests/topotests/isis_lfa_topo1/test_isis_lfa_topo1.py @@ -42,7 +42,6 @@ import sys import pytest import json -import time import tempfile from functools import partial @@ -169,7 +168,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() @@ -832,7 +831,7 @@ def _rt2_neigh_down(router): rname = "rt1" router = tgen.gears[rname] test_func = partial(_rt2_neigh_down, router) - success, result = topotest.run_and_expect(test_func, None, count=200, wait=0.05) + _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.05) assert result is None, 'rt2 neighbor is still present on "{}"'.format(router) router_compare_json_output( @@ -1034,7 +1033,7 @@ def _bfd_down(router): rname = "rt1" router = tgen.gears[rname] test_func = partial(_bfd_down, router) - success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.3) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.3) assert result is None, 'BFD session is still up on "{}"'.format(router) router_compare_json_output( diff --git a/tests/topotests/isis_lsp_bits_topo1/test_isis_lsp_bits_topo1.py b/tests/topotests/isis_lsp_bits_topo1/test_isis_lsp_bits_topo1.py index c4ce6a30cd43..6f4653d2c295 100755 --- a/tests/topotests/isis_lsp_bits_topo1/test_isis_lsp_bits_topo1.py +++ b/tests/topotests/isis_lsp_bits_topo1/test_isis_lsp_bits_topo1.py @@ -131,7 +131,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/isis_rlfa_topo1/test_isis_rlfa_topo1.py b/tests/topotests/isis_rlfa_topo1/test_isis_rlfa_topo1.py index 15327fe03adf..f97c7d2c9c9c 100755 --- a/tests/topotests/isis_rlfa_topo1/test_isis_rlfa_topo1.py +++ b/tests/topotests/isis_rlfa_topo1/test_isis_rlfa_topo1.py @@ -170,7 +170,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/isis_snmp/test_isis_snmp.py b/tests/topotests/isis_snmp/test_isis_snmp.py index ddef08008b43..81c96b3daf17 100755 --- a/tests/topotests/isis_snmp/test_isis_snmp.py +++ b/tests/topotests/isis_snmp/test_isis_snmp.py @@ -147,7 +147,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/isis_sr_flex_algo_topo1/test_isis_sr_flex_algo_topo1.py b/tests/topotests/isis_sr_flex_algo_topo1/test_isis_sr_flex_algo_topo1.py index c81f63942bde..d1fc68291ea7 100755 --- a/tests/topotests/isis_sr_flex_algo_topo1/test_isis_sr_flex_algo_topo1.py +++ b/tests/topotests/isis_sr_flex_algo_topo1/test_isis_sr_flex_algo_topo1.py @@ -37,7 +37,6 @@ import sys import pytest import json -import tempfile from copy import deepcopy from functools import partial @@ -121,7 +120,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/isis_sr_flex_algo_topo2/test_isis_sr_flex_algo_topo2.py b/tests/topotests/isis_sr_flex_algo_topo2/test_isis_sr_flex_algo_topo2.py index 6689cf4c5eba..7d063910d0f3 100755 --- a/tests/topotests/isis_sr_flex_algo_topo2/test_isis_sr_flex_algo_topo2.py +++ b/tests/topotests/isis_sr_flex_algo_topo2/test_isis_sr_flex_algo_topo2.py @@ -47,7 +47,6 @@ import sys import pytest import json -import time from functools import partial # Save the Current Working Directory to find configuration files. @@ -67,7 +66,6 @@ def build_topo(tgen): "Build function" - routers = [] for i in range(0, 10): rt = tgen.add_router("rt{}".format(i)) rt.run("sysctl -w net.ipv4.fib_multipath_hash_policy=1") @@ -140,7 +138,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() @@ -174,7 +172,7 @@ def _check(name, cmd, expected_file): logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) tgen = get_topogen() func = partial(_check, name, cmd, expected_file) - success, result = topotest.run_and_expect(func, None, count=120, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=120, wait=0.5) assert result is None, "Failed" diff --git a/tests/topotests/isis_sr_te_topo1/test_isis_sr_te_topo1.py b/tests/topotests/isis_sr_te_topo1/test_isis_sr_te_topo1.py index fc2ce7cb4b66..cb4f4ffa56ef 100755 --- a/tests/topotests/isis_sr_te_topo1/test_isis_sr_te_topo1.py +++ b/tests/topotests/isis_sr_te_topo1/test_isis_sr_te_topo1.py @@ -164,7 +164,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() @@ -641,7 +641,7 @@ def test_srte_route_map_with_sr_policy_check_nextop_step5(): ) # (re-)build the SR Policy two times to ensure that reinstalling still works - for i in [1, 2]: + for _ in [1, 2]: cmp_json_output( "rt1", "show ip route bgp json", "step5/show_ip_route_bgp_inactive_srte.ref" ) diff --git a/tests/topotests/isis_sr_topo1/test_isis_sr_topo1.py b/tests/topotests/isis_sr_topo1/test_isis_sr_topo1.py index 9a4085ab5593..baf7e98ba10a 100644 --- a/tests/topotests/isis_sr_topo1/test_isis_sr_topo1.py +++ b/tests/topotests/isis_sr_topo1/test_isis_sr_topo1.py @@ -137,7 +137,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/isis_srv6_topo1/test_isis_srv6_topo1.py b/tests/topotests/isis_srv6_topo1/test_isis_srv6_topo1.py index 1a7505dd123a..9c1a23f54f42 100644 --- a/tests/topotests/isis_srv6_topo1/test_isis_srv6_topo1.py +++ b/tests/topotests/isis_srv6_topo1/test_isis_srv6_topo1.py @@ -60,7 +60,6 @@ """ import os -import re import sys import json import functools @@ -212,7 +211,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" # Teardown the topology @@ -250,7 +249,7 @@ def _check(name, dest_addr, match): logger.info("[+] check {} {} {}".format(name, dest_addr, match)) tgen = get_topogen() func = functools.partial(_check, name, dest_addr, match) - success, result = topotest.run_and_expect(func, None, count=10, wait=1) + _, result = topotest.run_and_expect(func, None, count=10, wait=1) assert result is None, "Failed" diff --git a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py index aaf6af0be4cb..c8e66befa5c0 100755 --- a/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py +++ b/tests/topotests/isis_tilfa_topo1/test_isis_tilfa_topo1.py @@ -54,7 +54,6 @@ import sys import pytest import json -import tempfile from functools import partial from time import sleep @@ -144,7 +143,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py index b388f52bd9bd..cea284963d1e 100644 --- a/tests/topotests/isis_topo1/test_isis_topo1.py +++ b/tests/topotests/isis_topo1/test_isis_topo1.py @@ -104,7 +104,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() @@ -160,7 +160,7 @@ def compare_isis_installed_routes(router, expected): return topotest.json_cmp(actual, expected) test_func = functools.partial(compare_isis_installed_routes, router, expected) - (result, diff) = topotest.run_and_expect(test_func, None, wait=1, count=10) + (result, _) = topotest.run_and_expect(test_func, None, wait=1, count=10) assertmsg = "Router '{}' routes mismatch".format(rname) assert result, assertmsg @@ -205,7 +205,7 @@ def compare_isis_v6_installed_routes(router, expected): test_func = functools.partial( compare_isis_v6_installed_routes, router, expected ) - (result, diff) = topotest.run_and_expect(test_func, None, wait=1, count=10) + (result, _) = topotest.run_and_expect(test_func, None, wait=1, count=10) assertmsg = "Router '{}' routes mismatch".format(rname) assert result, assertmsg @@ -237,7 +237,7 @@ def test_isis_summary_json(): pytest.skip(tgen.errors) logger.info("Checking 'show isis summary json'") - for rname, router in tgen.routers().items(): + for rname, _ in tgen.routers().items(): logger.info("Checking router %s", rname) json_output = tgen.gears[rname].vtysh_cmd("show isis summary json", isjson=True) assertmsg = "Test isis summary json failed in '{}' data '{}'".format( @@ -257,7 +257,7 @@ def test_isis_interface_json(): pytest.skip(tgen.errors) logger.info("Checking 'show isis interface json'") - for rname, router in tgen.routers().items(): + for rname, _ in tgen.routers().items(): logger.info("Checking router %s", rname) json_output = tgen.gears[rname].vtysh_cmd( "show isis interface json", isjson=True @@ -294,7 +294,7 @@ def test_isis_neighbor_json(): # tgen.mininet_cli() logger.info("Checking 'show isis neighbor json'") - for rname, router in tgen.routers().items(): + for rname, _ in tgen.routers().items(): logger.info("Checking router %s", rname) json_output = tgen.gears[rname].vtysh_cmd( "show isis neighbor json", isjson=True @@ -330,7 +330,7 @@ def test_isis_database_json(): # tgen.mininet_cli() logger.info("Checking 'show isis database json'") - for rname, router in tgen.routers().items(): + for rname, _ in tgen.routers().items(): logger.info("Checking router %s", rname) json_output = tgen.gears[rname].vtysh_cmd( "show isis database json", isjson=True @@ -755,7 +755,7 @@ def dict_merge(dct, merge_dct): Source: https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 """ - for k, v in merge_dct.items(): + for k, _ in merge_dct.items(): if k in dct and isinstance(dct[k], dict) and topotest.is_mapping(merge_dct[k]): dict_merge(dct[k], merge_dct[k]) else: diff --git a/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py b/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py index 032319c446a1..7aac7c704da9 100644 --- a/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py +++ b/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py @@ -118,7 +118,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() # move back rx-eth0 to default VRF @@ -287,7 +287,7 @@ def dict_merge(dct, merge_dct): Source: https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 """ - for k, v in merge_dct.items(): + for k, _ in merge_dct.items(): if k in dct and isinstance(dct[k], dict) and topotest.is_mapping(merge_dct[k]): dict_merge(dct[k], merge_dct[k]) else: diff --git a/tests/topotests/key_sendaccept/test_keychain.py b/tests/topotests/key_sendaccept/test_keychain.py index b11d31b981a6..1d24c170042f 100644 --- a/tests/topotests/key_sendaccept/test_keychain.py +++ b/tests/topotests/key_sendaccept/test_keychain.py @@ -27,7 +27,7 @@ def tgen(request): tgen.start_topology() router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_frr_config("frr.conf") tgen.start_router() diff --git a/tests/topotests/ldp_oc_acl_topo1/test_ldp_oc_acl_topo1.py b/tests/topotests/ldp_oc_acl_topo1/test_ldp_oc_acl_topo1.py index c2bcaa84ceb2..8123e0498260 100644 --- a/tests/topotests/ldp_oc_acl_topo1/test_ldp_oc_acl_topo1.py +++ b/tests/topotests/ldp_oc_acl_topo1/test_ldp_oc_acl_topo1.py @@ -117,7 +117,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ldp_oc_topo1/test_ldp_oc_topo1.py b/tests/topotests/ldp_oc_topo1/test_ldp_oc_topo1.py index 387fd89c20d3..bfb93d55889a 100644 --- a/tests/topotests/ldp_oc_topo1/test_ldp_oc_topo1.py +++ b/tests/topotests/ldp_oc_topo1/test_ldp_oc_topo1.py @@ -116,7 +116,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ldp_snmp/test_ldp_snmp_topo1.py b/tests/topotests/ldp_snmp/test_ldp_snmp_topo1.py index 52a67d8bb8da..ea404beae4fa 100644 --- a/tests/topotests/ldp_snmp/test_ldp_snmp_topo1.py +++ b/tests/topotests/ldp_snmp/test_ldp_snmp_topo1.py @@ -136,7 +136,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ldp_sync_isis_topo1/test_ldp_sync_isis_topo1.py b/tests/topotests/ldp_sync_isis_topo1/test_ldp_sync_isis_topo1.py index cb6b784d6d36..f2c41ebe301f 100644 --- a/tests/topotests/ldp_sync_isis_topo1/test_ldp_sync_isis_topo1.py +++ b/tests/topotests/ldp_sync_isis_topo1/test_ldp_sync_isis_topo1.py @@ -129,7 +129,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ldp_sync_ospf_topo1/test_ldp_sync_ospf_topo1.py b/tests/topotests/ldp_sync_ospf_topo1/test_ldp_sync_ospf_topo1.py index 760b4e3df566..9e41e06c6a85 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/test_ldp_sync_ospf_topo1.py +++ b/tests/topotests/ldp_sync_ospf_topo1/test_ldp_sync_ospf_topo1.py @@ -128,7 +128,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ldp_vpls_topo1/test_ldp_vpls_topo1.py b/tests/topotests/ldp_vpls_topo1/test_ldp_vpls_topo1.py index 1f4a4b5fd595..c14c79e6d4f2 100644 --- a/tests/topotests/ldp_vpls_topo1/test_ldp_vpls_topo1.py +++ b/tests/topotests/ldp_vpls_topo1/test_ldp_vpls_topo1.py @@ -129,7 +129,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 3a16ed5a090d..4250c405f3dc 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -333,7 +333,7 @@ def __create_bgp_global(tgen, input_dict, router, build=False): else: del_action = False - for rs_timer, value in timer.items(): + for rs_timer, _ in timer.items(): rs_timer_value = timer.setdefault(rs_timer, None) if rs_timer_value and rs_timer != "delete": @@ -1229,7 +1229,7 @@ def modify_bgp_config_when_bgpd_down(tgen, topo, input_dict): # Copy bgp config file to /etc/frr for dut in input_dict.keys(): router_list = tgen.routers() - for router, rnode in router_list.items(): + for router, _ in router_list.items(): if router != dut: continue @@ -1750,7 +1750,7 @@ def verify_as_numbers(tgen, topo, input_dict, expected=True): for bgp_neighbor, peer_data in bgp_neighbors.items(): remote_as = input_dict[bgp_neighbor]["bgp"]["local_as"] - for dest_link, peer_dict in peer_data["dest_link"].items(): + for dest_link, _ in peer_data["dest_link"].items(): neighbor_ip = None data = topo["routers"][bgp_neighbor]["links"] @@ -1833,7 +1833,7 @@ def verify_bgp_convergence_from_running_config(tgen, dut=None, expected=True): return errormsg for vrf, addr_family_data in show_bgp_json.items(): - for address_family, neighborship_data in addr_family_data.items(): + for _, neighborship_data in addr_family_data.items(): total_peer = 0 no_of_peer = 0 @@ -1980,7 +1980,7 @@ def clear_bgp_and_verify(tgen, topo, router, rid=None): bgp_neighbors = bgp_addr_type[addr_type]["unicast"]["neighbor"] for bgp_neighbor, peer_data in bgp_neighbors.items(): - for dest_link, peer_dict in peer_data["dest_link"].items(): + for dest_link, _ in peer_data["dest_link"].items(): data = topo["routers"][bgp_neighbor]["links"] if dest_link in data: @@ -3231,7 +3231,7 @@ def verify_graceful_restart( if bgp_neighbor != peer: continue - for dest_link, peer_dict in peer_data["dest_link"].items(): + for dest_link, _ in peer_data["dest_link"].items(): data = topo["routers"][bgp_neighbor]["links"] if dest_link in data: @@ -3479,7 +3479,7 @@ def verify_r_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True): if bgp_neighbor != peer: continue - for dest_link, peer_dict in peer_data["dest_link"].items(): + for dest_link, _ in peer_data["dest_link"].items(): data = topo["routers"][bgp_neighbor]["links"] if dest_link in data: @@ -3597,7 +3597,7 @@ def verify_eor(tgen, topo, addr_type, input_dict, dut, peer, expected=True): if bgp_neighbor != peer: continue - for dest_link, peer_dict in peer_data["dest_link"].items(): + for dest_link, _ in peer_data["dest_link"].items(): data = topo["routers"][bgp_neighbor]["links"] if dest_link in data: @@ -3762,7 +3762,7 @@ def verify_f_bit(tgen, topo, addr_type, input_dict, dut, peer, expected=True): if bgp_neighbor != peer: continue - for dest_link, peer_dict in peer_data["dest_link"].items(): + for dest_link, _ in peer_data["dest_link"].items(): data = topo["routers"][bgp_neighbor]["links"] if dest_link in data: @@ -3890,7 +3890,7 @@ def verify_graceful_restart_timers(tgen, topo, addr_type, input_dict, dut, peer) if bgp_neighbor != peer: continue - for dest_link, peer_dict in peer_data["dest_link"].items(): + for dest_link, _ in peer_data["dest_link"].items(): data = topo["routers"][bgp_neighbor]["links"] if dest_link in data: diff --git a/tests/topotests/lib/checkping.py b/tests/topotests/lib/checkping.py index 5500807fabe3..aa95f45b2967 100644 --- a/tests/topotests/lib/checkping.py +++ b/tests/topotests/lib/checkping.py @@ -33,5 +33,5 @@ def _check(name, dest_addr, source_addr, match): logger.info("[+] check {} {} {}".format(name, dest_addr, match)) tgen = get_topogen() func = functools.partial(_check, name, dest_addr, source_addr, match) - success, result = topotest.run_and_expect(func, None, count=count, wait=wait) + _, result = topotest.run_and_expect(func, None, count=count, wait=wait) assert result is None, "Failed" diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py index 7787b6f74b1d..e856c23d3632 100644 --- a/tests/topotests/lib/common_config.py +++ b/tests/topotests/lib/common_config.py @@ -7,7 +7,6 @@ import functools import ipaddress -import json import os import platform import socket @@ -442,7 +441,7 @@ def check_router_status(tgen): try: router_list = tgen.routers() - for router, rnode in router_list.items(): + for _, rnode in router_list.items(): result = rnode.check_router_running() if result != "": daemons = [] @@ -686,7 +685,7 @@ def prep_load_config_to_routers(tgen, *config_name_list): """ routers = tgen.routers() - for rname, router in routers.items(): + for rname, _ in routers.items(): destname = "{}/{}/{}".format(tgen.logdir, rname, FRRCFG_FILE) wmode = "w" for cfbase in config_name_list: @@ -871,7 +870,7 @@ def get_frr_ipv6_linklocal(tgen, router, intf=None, vrf=None): """ router_list = tgen.routers() - for rname, rnode in router_list.items(): + for rname, _ in router_list.items(): if rname != router: continue @@ -887,7 +886,7 @@ def get_frr_ipv6_linklocal(tgen, router, intf=None, vrf=None): cmd = "show interface vrf {}".format(vrf) else: cmd = "show interface" - for chk_ll in range(0, 60): + for _ in range(0, 60): sleep(1 / 4) ifaces = router_list[router].run('vtysh -c "{}"'.format(cmd)) # Fix newlines (make them all the same) @@ -3095,7 +3094,7 @@ def configure_brctl(tgen, topo, input_dict): "{} dev {} master {}".format(ip_cmd, brctl_name, vrf) ) - for intf_name, data in topo["routers"][dut]["links"].items(): + for _, data in topo["routers"][dut]["links"].items(): if "vrf" not in data: continue @@ -4942,7 +4941,7 @@ def scapy_send_raw_packet(tgen, topo, senderRouter, intf, packet=None): sender_interface = intf rnode = tgen.routers()[senderRouter] - for destLink, data in topo["routers"][senderRouter]["links"].items(): + for _, data in topo["routers"][senderRouter]["links"].items(): if "type" in data and data["type"] == "loopback": continue diff --git a/tests/topotests/lib/fe_client.py b/tests/topotests/lib/fe_client.py index d61bc850b4d2..784f7d17eb29 100755 --- a/tests/topotests/lib/fe_client.py +++ b/tests/topotests/lib/fe_client.py @@ -9,7 +9,6 @@ # noqa: E501 # import argparse -import json import logging import os import socket @@ -216,7 +215,7 @@ def __init__(self, sock, use_protobuf): self.sess_id = reply.session_reply.session_id else: self.sess_id = 0 - mdata, req_id = self.get_native_msg_header(MSG_CODE_SESSION_REQ) + mdata, _ = self.get_native_msg_header(MSG_CODE_SESSION_REQ) mdata += struct.pack(MSG_SESSION_REQ_FMT) mdata += "test-client".encode("utf-8") + b"\x00" @@ -324,7 +323,7 @@ def lock(self, lock=True, ds_id=mgmt_pb2.CANDIDATE_DS): def get_data(self, query, data=True, config=False): # Create the message - mdata, req_id = self.get_native_msg_header(MSG_CODE_GET_DATA) + mdata, _ = self.get_native_msg_header(MSG_CODE_GET_DATA) flags = GET_DATA_FLAG_STATE if data else 0 flags |= GET_DATA_FLAG_CONFIG if config else 0 mdata += struct.pack(MSG_GET_DATA_FMT, MSG_FORMAT_JSON, flags) @@ -333,7 +332,7 @@ def get_data(self, query, data=True, config=False): self.send_native_msg(mdata) logging.debug("Sent GET-TREE") - mhdr, mfixed, mdata = self.recv_native_msg() + _, mfixed, mdata = self.recv_native_msg() assert mdata[-1] == 0 result = mdata[:-1].decode("utf-8") @@ -342,7 +341,7 @@ def get_data(self, query, data=True, config=False): def add_notify_select(self, replace, notif_xpaths): # Create the message - mdata, req_id = self.get_native_msg_header(MSG_CODE_NOTIFY_SELECT) + mdata, _ = self.get_native_msg_header(MSG_CODE_NOTIFY_SELECT) mdata += struct.pack(MSG_NOTIFY_SELECT_FMT, replace) for xpath in notif_xpaths: @@ -355,7 +354,7 @@ def recv_notify(self, xpaths=None): if xpaths: self.add_notify_select(True, xpaths) - for remaining in Timeout(60): + for _ in Timeout(60): logging.debug("Waiting for Notify Message") mhdr, mfixed, mdata = self.recv_native_msg() if mhdr[HDR_FIELD_CODE] == MSG_CODE_NOTIFY: diff --git a/tests/topotests/lib/ospf.py b/tests/topotests/lib/ospf.py index 5b18f8b679ce..2c876e198926 100644 --- a/tests/topotests/lib/ospf.py +++ b/tests/topotests/lib/ospf.py @@ -1545,7 +1545,7 @@ def verify_ospf_database( ) return errormsg if ospf_external_lsa: - for ospf_ext_lsa, ext_lsa_data in ospf_external_lsa.items(): + for ospf_ext_lsa, _ in ospf_external_lsa.items(): if ospf_ext_lsa in show_ospf_json["AS External Link States"]: logger.info( "[DUT: %s] OSPF LSDB:External LSA %s", router, ospf_ext_lsa @@ -2509,7 +2509,7 @@ def verify_ospf_gr_helper(tgen, topo, dut, input_dict=None): raise ValueError(errormsg) return errormsg - for ospf_gr, gr_data in input_dict.items(): + for ospf_gr, _ in input_dict.items(): try: if input_dict[ospf_gr] == show_ospf_json[ospf_gr]: logger.info( diff --git a/tests/topotests/lib/pim.py b/tests/topotests/lib/pim.py index f7440efd6d57..cc56ffdd8c9f 100644 --- a/tests/topotests/lib/pim.py +++ b/tests/topotests/lib/pim.py @@ -149,7 +149,7 @@ def _add_pim_rp_config(tgen, topo, input_dict, router, build, config_data_dict): # At least one interface must be enabled for PIM on the router pim_if_enabled = False pim6_if_enabled = False - for destLink, data in topo[dut]["links"].items(): + for _, data in topo[dut]["links"].items(): if "pim" in data: pim_if_enabled = True if "pim6" in data: @@ -603,7 +603,7 @@ def find_rp_details(tgen, topo): # ip address of RP rp_addr = rp_dict["rp_addr"] - for link, data in topo["routers"][router]["links"].items(): + for _, data in topo["routers"][router]["links"].items(): if data["ipv4"].split("/")[0] == rp_addr: rp_details[router] = rp_addr @@ -2089,7 +2089,7 @@ def verify_pim_interface( ) return True else: - for destLink, data in topo["routers"][dut]["links"].items(): + for _, data in topo["routers"][dut]["links"].items(): if "type" in data and data["type"] == "loopback": continue @@ -2292,7 +2292,7 @@ def clear_pim_interfaces(tgen, dut): # Waiting for maximum 60 sec fail_intf = [] - for retry in range(1, 13): + for _ in range(1, 13): sleep(5) logger.info("[DUT: %s]: Waiting for 5 sec for PIM neighbors" " to come up", dut) run_json_after = run_frr_cmd(rnode, "show ip pim neighbor json", isjson=True) @@ -2368,7 +2368,7 @@ def clear_igmp_interfaces(tgen, dut): total_groups_before_clear = igmp_json["totalGroups"] - for key, value in igmp_json.items(): + for _, value in igmp_json.items(): if type(value) is not dict: continue @@ -2381,7 +2381,7 @@ def clear_igmp_interfaces(tgen, dut): result = run_frr_cmd(rnode, "clear ip igmp interfaces") # Waiting for maximum 60 sec - for retry in range(1, 13): + for _ in range(1, 13): logger.info( "[DUT: %s]: Waiting for 5 sec for igmp interfaces" " to come up", dut ) @@ -2460,7 +2460,7 @@ def clear_mroute_verify(tgen, dut, expected=True): # RFC 3376: 8.2. Query Interval - Default: 125 seconds # So waiting for maximum 130 sec to get the igmp report - for retry in range(1, 26): + for _ in range(1, 26): logger.info("[DUT: %s]: Waiting for 2 sec for mroutes" " to come up", dut) sleep(5) keys_json1 = mroute_json_1.keys() @@ -2671,7 +2671,7 @@ def add_rp_interfaces_and_pim_config(tgen, topo, interface, rp, rp_mapping): try: config_data = [] - for group, rp_list in rp_mapping.items(): + for _, rp_list in rp_mapping.items(): for _rp in rp_list: config_data.append("interface {}".format(interface)) config_data.append("ip address {}".format(_rp)) @@ -2720,7 +2720,7 @@ def scapy_send_bsr_raw_packet(tgen, topo, senderRouter, receiverRouter, packet=N script_path = os.path.join(CWD, "send_bsr_packet.py") node = tgen.net[senderRouter] - for destLink, data in topo["routers"][senderRouter]["links"].items(): + for _, data in topo["routers"][senderRouter]["links"].items(): if "type" in data and data["type"] == "loopback": continue @@ -2795,12 +2795,12 @@ def find_rp_from_bsrp_info(tgen, dut, bsr, grp=None): # RP with lowest priority if len(priority_dict) != 1: - rp_p, lowest_priority = sorted(rp_priority.items(), key=lambda x: x[1])[0] + rp_p, _ = sorted(rp_priority.items(), key=lambda x: x[1])[0] rp_details[group] = rp_p # RP with highest hash value if len(priority_dict) == 1: - rp_h, highest_hash = sorted(rp_hash.items(), key=lambda x: x[1])[-1] + rp_h, _ = sorted(rp_hash.items(), key=lambda x: x[1])[-1] rp_details[group] = rp_h # RP with highest IP address @@ -3239,7 +3239,7 @@ def verify_pim_join( interface_json = show_pim_join_json[interface] grp_addr = grp_addr.split("/")[0] - for source, data in interface_json[grp_addr].items(): + for _, data in interface_json[grp_addr].items(): # Verify pim join if pim_join: if data["group"] == grp_addr and data["channelJoinName"] == "JOIN": diff --git a/tests/topotests/mgmt_debug_flags/test_debug.py b/tests/topotests/mgmt_debug_flags/test_debug.py index e49d9b7beb41..fe659e54cabb 100644 --- a/tests/topotests/mgmt_debug_flags/test_debug.py +++ b/tests/topotests/mgmt_debug_flags/test_debug.py @@ -27,7 +27,7 @@ def tgen(request): tgen = Topogen(topodef, request.module.__name__) tgen.start_topology() - for rname, router in tgen.routers().items(): + for _, router in tgen.routers().items(): router.load_frr_config("frr.conf") tgen.start_router() diff --git a/tests/topotests/mgmt_notif/test_notif.py b/tests/topotests/mgmt_notif/test_notif.py index 01466892a880..e5286faae208 100644 --- a/tests/topotests/mgmt_notif/test_notif.py +++ b/tests/topotests/mgmt_notif/test_notif.py @@ -10,7 +10,6 @@ Test YANG Notifications """ import json -import logging import os import pytest @@ -35,7 +34,7 @@ def tgen(request): tgen.start_topology() router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_frr_config("frr.conf") tgen.start_router() diff --git a/tests/topotests/mgmt_oper/oper.py b/tests/topotests/mgmt_oper/oper.py index 162c1eb5ccb5..934093aeee0e 100644 --- a/tests/topotests/mgmt_oper/oper.py +++ b/tests/topotests/mgmt_oper/oper.py @@ -146,7 +146,7 @@ def check_kernel(r1, super_prefix, count, add, is_blackhole, vrf, matchvia): # logger.debug("checking kernel routing table%s:\n%s", vrfstr, kernel) - for i, net in enumerate(get_ip_networks(super_prefix, count)): + for _, net in enumerate(get_ip_networks(super_prefix, count)): if not add: assert str(net) not in kernel continue @@ -233,7 +233,7 @@ def do_config( if vrf: f.write("vrf {}\n".format(vrf)) - for i, net in enumerate(get_ip_networks(super_prefix, count)): + for _, net in enumerate(get_ip_networks(super_prefix, count)): if add: f.write("ip route {} {}\n".format(net, via)) else: diff --git a/tests/topotests/mgmt_oper/test_oper.py b/tests/topotests/mgmt_oper/test_oper.py index 8b8a51c29e0b..e4ceabf35275 100644 --- a/tests/topotests/mgmt_oper/test_oper.py +++ b/tests/topotests/mgmt_oper/test_oper.py @@ -12,17 +12,11 @@ import ipaddress import math -import time import pytest from lib.topogen import Topogen from oper import check_kernel_32, do_oper_test -try: - from deepdiff import DeepDiff as dd_json_cmp -except ImportError: - dd_json_cmp = None - pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd] diff --git a/tests/topotests/mgmt_rpc/test_rpc.py b/tests/topotests/mgmt_rpc/test_rpc.py index 618d9022cea0..839db97379a0 100644 --- a/tests/topotests/mgmt_rpc/test_rpc.py +++ b/tests/topotests/mgmt_rpc/test_rpc.py @@ -32,7 +32,7 @@ def tgen(request): tgen.start_topology() router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_frr_config("frr.conf") tgen.start_router() diff --git a/tests/topotests/mgmt_tests/test_yang_mgmt.py b/tests/topotests/mgmt_tests/test_yang_mgmt.py index 605c14285fa9..52f6ba4db745 100644 --- a/tests/topotests/mgmt_tests/test_yang_mgmt.py +++ b/tests/topotests/mgmt_tests/test_yang_mgmt.py @@ -66,7 +66,6 @@ start_router_daemons, ) from lib.topolog import logger -from lib.bgp import verify_bgp_convergence, create_router_bgp, verify_bgp_rib from lib.topojson import build_config_from_json pytestmark = [pytest.mark.bgpd, pytest.mark.staticd, pytest.mark.mgmtd] diff --git a/tests/topotests/msdp_topo1/test_msdp_topo1.py b/tests/topotests/msdp_topo1/test_msdp_topo1.py index 1af58b0a010f..08c37617cf76 100755 --- a/tests/topotests/msdp_topo1/test_msdp_topo1.py +++ b/tests/topotests/msdp_topo1/test_msdp_topo1.py @@ -101,7 +101,7 @@ def setup_module(mod): app_helper.init(tgen) -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() app_helper.cleanup() diff --git a/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm1.py b/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm1.py index 7eb583803715..b8eb67a32eca 100644 --- a/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm1.py +++ b/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm1.py @@ -221,7 +221,7 @@ def verify_state_incremented(state_before, state_after): """ for router, state_data in state_before.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): if state_before[router][state] >= state_after[router][state]: errormsg = ( "[DUT: %s]: state %s value has not" diff --git a/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm2.py b/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm2.py index 8b174bf9b833..bab7fddf9e73 100644 --- a/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm2.py +++ b/tests/topotests/multicast_pim6_sm_topo1/test_multicast_pim6_sm2.py @@ -175,7 +175,7 @@ def verify_state_incremented(state_before, state_after): """ for router, state_data in state_before.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): if state_before[router][state] >= state_after[router][state]: errormsg = ( "[DUT: %s]: state %s value has not" diff --git a/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_ospf_topo2.py b/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_ospf_topo2.py index 00d38fe647dc..5aa2ea65f7b5 100755 --- a/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_ospf_topo2.py +++ b/tests/topotests/multicast_pim_dr_nondr_test/test_pim_dr_nondr_with_ospf_topo2.py @@ -20,10 +20,7 @@ import os import sys -import json import time -import datetime -from time import sleep import pytest # Save the Current Working Directory to find configuration files. @@ -43,14 +40,9 @@ write_test_footer, step, reset_config_on_routers, - shutdown_bringup_interface, apply_raw_config, add_interfaces_to_vlan, - kill_router_daemons, - start_router_daemons, - create_static_routes, check_router_status, - topo_daemons, required_linux_kernel_version, ) from lib.pim import ( @@ -59,9 +51,6 @@ verify_mroutes, clear_mroute, clear_pim_interface_traffic, - verify_pim_config, - verify_upstream_iif, - verify_multicast_traffic, verify_multicast_flag_state, verify_igmp_groups, McastTesterHelper, diff --git a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py index f87a90d19822..eefa96a38962 100755 --- a/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py +++ b/tests/topotests/multicast_pim_sm_topo1/test_multicast_pim_sm_topo1.py @@ -64,7 +64,6 @@ reset_config_on_routers, shutdown_bringup_interface, required_linux_kernel_version, - topo_daemons, ) from lib.pim import ( create_pim_config, @@ -214,7 +213,7 @@ def verify_state_incremented(state_before, state_after): """ for router, state_data in state_before.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): if state_before[router][state] >= state_after[router][state]: errormsg = ( "[DUT: %s]: state %s value has not" diff --git a/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py b/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py index b62f7bbfc987..0af2efcc7e36 100755 --- a/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py +++ b/tests/topotests/multicast_pim_sm_topo2/test_multicast_pim_sm_topo2.py @@ -62,7 +62,6 @@ start_router_daemons, stop_router, required_linux_kernel_version, - topo_daemons, ) from lib.pim import ( create_pim_config, @@ -211,7 +210,7 @@ def verify_state_incremented(state_before, state_after): """ for router, state_data in state_before.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): if state_before[router][state] >= state_after[router][state]: errormsg = ( "[DUT: %s]: state %s value has not" diff --git a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py index ae275467035d..9488ae02bf27 100755 --- a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py +++ b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo3.py @@ -57,7 +57,7 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import ( start_topology, write_test_header, @@ -68,7 +68,6 @@ apply_raw_config, check_router_status, required_linux_kernel_version, - topo_daemons, ) from lib.pim import ( create_pim_config, @@ -354,7 +353,7 @@ def verify_pim_stats_increament(stats_before, stats_after): """ for router, stats_data in stats_before.items(): - for stats, value in stats_data.items(): + for stats, _ in stats_data.items(): if stats_before[router][stats] >= stats_after[router][stats]: errormsg = ( "[DUT: %s]: state %s value has not" diff --git a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py index 825281afbb01..11f3cc4254aa 100755 --- a/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py +++ b/tests/topotests/multicast_pim_sm_topo3/test_multicast_pim_sm_topo4.py @@ -55,7 +55,6 @@ apply_raw_config, create_static_routes, required_linux_kernel_version, - topo_daemons, ) from lib.pim import ( create_pim_config, @@ -191,7 +190,7 @@ def reset_stats(stats): """ for router, state_data in stats.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): stats[router][state] = 0 logger.info( "[DUT: %s]: stats %s value has reset" " reset, Current value: %s", @@ -214,7 +213,7 @@ def verify_state_incremented(state_before, state_after): """ for router, state_data in state_before.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): if state_before[router][state] >= state_after[router][state]: errormsg = ( "[DUT: %s]: state %s value has not" diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py index c492d95d40af..38b9b2ecb13a 100755 --- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp.py @@ -87,7 +87,6 @@ import os import sys import time -from time import sleep import datetime import pytest @@ -112,10 +111,7 @@ reset_config_on_routers, step, shutdown_bringup_interface, - kill_router_daemons, - start_router_daemons, create_static_routes, - topo_daemons, ) from lib.pim import ( create_pim_config, @@ -128,10 +124,7 @@ verify_pim_rp_info, verify_pim_state, clear_pim_interface_traffic, - clear_igmp_interfaces, - clear_pim_interfaces, clear_mroute, - clear_mroute_verify, McastTesterHelper, ) diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py index 690c92f58087..6f078a68d8d2 100755 --- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp1.py @@ -112,9 +112,6 @@ reset_config_on_routers, step, shutdown_bringup_interface, - kill_router_daemons, - start_router_daemons, - create_static_routes, ) from lib.pim import ( create_pim_config, @@ -123,9 +120,7 @@ verify_join_state_and_timer, verify_mroutes, verify_pim_neighbors, - get_pim_interface_traffic, verify_pim_rp_info, - verify_pim_state, clear_pim_interface_traffic, clear_igmp_interfaces, clear_pim_interfaces, diff --git a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py index 8aa2e4efa1eb..48c0a78f9805 100755 --- a/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py +++ b/tests/topotests/multicast_pim_static_rp_topo1/test_multicast_pim_static_rp2.py @@ -123,14 +123,9 @@ verify_join_state_and_timer, verify_mroutes, verify_pim_neighbors, - get_pim_interface_traffic, verify_pim_rp_info, - verify_pim_state, clear_pim_interface_traffic, - clear_igmp_interfaces, - clear_pim_interfaces, clear_mroute, - clear_mroute_verify, McastTesterHelper, ) diff --git a/tests/topotests/multicast_pim_uplink_topo1/test_multicast_pim_uplink_topo1.py b/tests/topotests/multicast_pim_uplink_topo1/test_multicast_pim_uplink_topo1.py index 5728a4d08eee..bbd5501dbb64 100644 --- a/tests/topotests/multicast_pim_uplink_topo1/test_multicast_pim_uplink_topo1.py +++ b/tests/topotests/multicast_pim_uplink_topo1/test_multicast_pim_uplink_topo1.py @@ -25,7 +25,6 @@ import os import sys -import json import time import pytest @@ -356,7 +355,7 @@ def verify_state_incremented(state_before, state_after): """ for router, state_data in state_before.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): if state_before[router][state] > state_after[router][state]: errormsg = ( "[DUT: %s]: state %s value has not" @@ -1682,7 +1681,7 @@ def test_mroutes_updated_correctly_after_source_interface_shut_noshut_p1(request step("Shut and No shut source interface multiple time") - for i in range(0, 2): + for _ in range(0, 2): step("Shut and no shut the source interface from DUT") intf_r1_i2 = topo["routers"]["r1"]["links"]["i2"]["interface"] shutdown_bringup_interface(tgen, "r1", intf_r1_i2, False) diff --git a/tests/topotests/multicast_pim_uplink_topo2/test_multicast_pim_uplink_topo2.py b/tests/topotests/multicast_pim_uplink_topo2/test_multicast_pim_uplink_topo2.py index 1fb81c0d7091..893b80083ea7 100644 --- a/tests/topotests/multicast_pim_uplink_topo2/test_multicast_pim_uplink_topo2.py +++ b/tests/topotests/multicast_pim_uplink_topo2/test_multicast_pim_uplink_topo2.py @@ -213,7 +213,7 @@ def verify_state_incremented(state_before, state_after): """ for router, state_data in state_before.items(): - for state, value in state_data.items(): + for state, _ in state_data.items(): if state_before[router][state] > state_after[router][state]: errormsg = ( "[DUT: %s]: state %s value has not" diff --git a/tests/topotests/nb_config/test_nb_config.py b/tests/topotests/nb_config/test_nb_config.py index 9099ef10b8c4..09d6407d5b07 100644 --- a/tests/topotests/nb_config/test_nb_config.py +++ b/tests/topotests/nb_config/test_nb_config.py @@ -30,7 +30,7 @@ def tgen(request): tgen.start_topology() router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_frr_config("frr.conf") tgen.start_router() diff --git a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py index 81a22ebfaf5d..ffd9abc9d471 100644 --- a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py +++ b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py @@ -10,7 +10,6 @@ import os import sys import json -from time import sleep from functools import partial import pytest @@ -207,7 +206,7 @@ def test_protocols_convergence(): router_list = tgen.routers() # Check NHRP cache on servers and clients - for rname, router in router_list.items(): + for _, router in router_list.items(): json_file = "{}/{}/nhrp_cache.json".format(CWD, router.name) if not os.path.isfile(json_file): diff --git a/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py index 45e1bc8db387..ba705e3dfc79 100755 --- a/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py +++ b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py @@ -135,7 +135,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ospf6_loopback_cost/test_ospf6_loopback_cost.py b/tests/topotests/ospf6_loopback_cost/test_ospf6_loopback_cost.py index 8e7a7ea40ac3..077a9e4205e1 100644 --- a/tests/topotests/ospf6_loopback_cost/test_ospf6_loopback_cost.py +++ b/tests/topotests/ospf6_loopback_cost/test_ospf6_loopback_cost.py @@ -30,7 +30,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen def setup_module(mod): @@ -46,7 +46,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf6_point_to_multipoint/test_ospf6_point_to_multipoint.py b/tests/topotests/ospf6_point_to_multipoint/test_ospf6_point_to_multipoint.py index 142acf1eb47d..73a902244251 100644 --- a/tests/topotests/ospf6_point_to_multipoint/test_ospf6_point_to_multipoint.py +++ b/tests/topotests/ospf6_point_to_multipoint/test_ospf6_point_to_multipoint.py @@ -153,7 +153,7 @@ def setup_module(mod): # tgen.mininet_cli() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() @@ -229,7 +229,7 @@ def test_ospfv3_routingTable(): # tgen.mininet_cli() # Verify OSPFv3 Routing Table - for router, rnode in tgen.routers().items(): + for router, _ in tgen.routers().items(): logger.info('Waiting for router "%s" convergence', router) # Load expected results from the command diff --git a/tests/topotests/ospf6_topo1/test_ospf6_topo1.py b/tests/topotests/ospf6_topo1/test_ospf6_topo1.py index 5649757010c3..85075a79aaf8 100644 --- a/tests/topotests/ospf6_topo1/test_ospf6_topo1.py +++ b/tests/topotests/ospf6_topo1/test_ospf6_topo1.py @@ -153,7 +153,7 @@ def setup_module(mod): # tgen.mininet_cli() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() @@ -229,7 +229,7 @@ def test_ospfv3_routingTable(): # tgen.mininet_cli() # Verify OSPFv3 Routing Table - for router, rnode in tgen.routers().items(): + for router, _ in tgen.routers().items(): logger.info('Waiting for router "%s" convergence', router) # Load expected results from the command @@ -351,7 +351,7 @@ def test_ospfv3_routingTable_write_multiplier(): r1.vtysh_cmd("clear ipv6 ospf interface r1-sw5") # Verify OSPFv3 Routing Table - for router, rnode in tgen.routers().items(): + for router, _ in tgen.routers().items(): logger.info('Waiting for router "%s" convergence', router) # Load expected results from the command diff --git a/tests/topotests/ospf6_topo1_vrf/test_ospf6_topo1_vrf.py b/tests/topotests/ospf6_topo1_vrf/test_ospf6_topo1_vrf.py index f982990987b5..ccf25a0fc84b 100755 --- a/tests/topotests/ospf6_topo1_vrf/test_ospf6_topo1_vrf.py +++ b/tests/topotests/ospf6_topo1_vrf/test_ospf6_topo1_vrf.py @@ -186,7 +186,7 @@ def setup_module(mod): # tgen.mininet_cli() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() @@ -260,7 +260,7 @@ def test_ospfv3_routingTable(): # For debugging, uncomment the next line # tgen.mininet_cli() # Verify OSPFv3 Routing Table - for router, rnode in tgen.routers().items(): + for router, _ in tgen.routers().items(): logger.info('Waiting for router "%s" convergence', router) # Load expected results from the command @@ -391,7 +391,7 @@ def test_ospfv3_routingTable_write_multiplier(): r1.vtysh_cmd("clear ipv6 ospf interface r1-sw5") # Verify OSPFv3 Routing Table - for router, rnode in tgen.routers().items(): + for router, _ in tgen.routers().items(): logger.info('Waiting for router "%s" convergence', router) # Load expected results from the command diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py index 0531e81d4431..18b72772fe49 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_topo1.py @@ -147,7 +147,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. @@ -2893,7 +2893,7 @@ def test_ospf_type5_summary_tc51_p2(request): step("Configure and re configure all the commands 10 times in a loop.") - for itrate in range(0, 10): + for _ in range(0, 10): ospf_summ_r1 = { "r0": { "ospf": { diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py index 603aeadb855b..cdc5d126b47f 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_asbr_summary_type7_lsa.py @@ -139,7 +139,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py index 8dd103013b4e..922c5a0e0b3c 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_authentication.py @@ -109,7 +109,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py index e58f081f9636..dc237e9512cd 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_chaos.py @@ -118,7 +118,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py index aba313db9f73..21e767522adb 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py @@ -121,7 +121,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. @@ -193,7 +193,7 @@ def test_ospf_ecmp_tc16_p0(request): step("Verify that route in R2 in stalled with 8 next hops.") nh = [] - for item in range(1, 7): + for _ in range(1, 7): nh.append(topo["routers"]["r0"]["links"]["r1-link1"]["ipv4"].split("/")[0]) nh2 = topo["routers"]["r0"]["links"]["r1"]["ipv4"].split("/")[0] diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_flood_reduction.py b/tests/topotests/ospf_basic_functionality/test_ospf_flood_reduction.py index 62b821220334..7c37af02ace8 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_flood_reduction.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_flood_reduction.py @@ -51,7 +51,6 @@ create_static_routes, step, topo_daemons, - shutdown_bringup_interface, check_router_status, start_topology, write_test_header, @@ -65,8 +64,6 @@ write_test_header, write_test_footer, reset_config_on_routers, - stop_router, - start_router, step, create_static_routes, kill_router_daemons, @@ -163,7 +160,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py index 4a40b3e9ecae..9c531c03abae 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_nssa.py @@ -119,7 +119,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py index a90d7dbdc05f..6aec98c71bb2 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py @@ -105,7 +105,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py index c9f43cdfe497..eee51796c929 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py @@ -134,7 +134,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py index d169245f4e43..193f5c8c5f08 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py @@ -130,7 +130,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. @@ -208,7 +208,7 @@ def test_ospf_redistribution_tc5_p0(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) dut = "r1" - for num in range(0, nretry): + for _ in range(0, nretry): result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False) if result is not True: break @@ -332,7 +332,7 @@ def test_ospf_redistribution_tc6_p0(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) dut = "r1" - for num in range(0, nretry): + for _ in range(0, nretry): result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False) if result is not True: break diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py index 59afc7a8afcd..33841b9ab20a 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_single_area.py @@ -115,7 +115,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.py b/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.py index ade55321f9b6..2d1637995269 100644 --- a/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.py +++ b/tests/topotests/ospf_dual_stack/test_ospf_dual_stack.py @@ -72,7 +72,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper1.py b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper1.py index 79374281cb7a..3bed390b1882 100644 --- a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper1.py +++ b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper1.py @@ -29,7 +29,6 @@ write_test_footer, reset_config_on_routers, step, - create_interfaces_cfg, scapy_send_raw_packet, ) @@ -38,7 +37,6 @@ from lib.ospf import ( verify_ospf_neighbor, - clear_ospf, verify_ospf_gr_helper, create_router_ospf, ) diff --git a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper3.py b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper3.py index 3be28196d884..a9028673d205 100644 --- a/tests/topotests/ospf_gr_helper/test_ospf_gr_helper3.py +++ b/tests/topotests/ospf_gr_helper/test_ospf_gr_helper3.py @@ -29,7 +29,6 @@ write_test_footer, reset_config_on_routers, step, - create_interfaces_cfg, scapy_send_raw_packet, ) @@ -38,7 +37,6 @@ from lib.ospf import ( verify_ospf_neighbor, - clear_ospf, verify_ospf_gr_helper, create_router_ospf, ) diff --git a/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py b/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py index 73185d501def..73b660e59031 100755 --- a/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py +++ b/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py @@ -144,7 +144,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py b/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py index 590b0d5e68d4..ea4507736e74 100644 --- a/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py +++ b/tests/topotests/ospf_instance_redistribute/test_ospf_instance_redistribute.py @@ -15,7 +15,6 @@ """ import os -import re import sys import pytest import json diff --git a/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py b/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py index 085eb1f9c123..b9c63622f019 100644 --- a/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py +++ b/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py @@ -11,14 +11,13 @@ import os import sys import json -from time import sleep from functools import partial import pytest # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.topolog import logger @@ -166,7 +165,7 @@ def setup_module(mod): tgen.set_error("unsupported version") -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/test_ospf_multi_vrf_bgp_route_leak.py b/tests/topotests/ospf_multi_vrf_bgp_route_leak/test_ospf_multi_vrf_bgp_route_leak.py index ee0a0f6c3be0..10a0051a472b 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/test_ospf_multi_vrf_bgp_route_leak.py +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/test_ospf_multi_vrf_bgp_route_leak.py @@ -16,7 +16,7 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.topolog import logger @@ -139,7 +139,7 @@ def setup_module(mod): tgen.set_error("unsupported version") -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py index 23eef8f5a633..eae8806a5943 100644 --- a/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py +++ b/tests/topotests/ospf_netns_vrf/test_ospf_netns_vrf.py @@ -104,13 +104,13 @@ def setup_module(mod): tgen.set_error("unsupported version") -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() # Move interfaces out of vrf namespace and delete the namespace router_list = tgen.routers() - for rname, router in router_list.items(): + for rname, _ in router_list.items(): tgen.net[rname].reset_intf_netns(rname + "-eth0") tgen.net[rname].reset_intf_netns(rname + "-eth1") tgen.net[rname].delete_netns(rname + "-ospf-cust1") diff --git a/tests/topotests/ospf_nssa_topo1/test_ospf_nssa_topo1.py b/tests/topotests/ospf_nssa_topo1/test_ospf_nssa_topo1.py index d8cd1322bd5c..4a67fa33a6fe 100644 --- a/tests/topotests/ospf_nssa_topo1/test_ospf_nssa_topo1.py +++ b/tests/topotests/ospf_nssa_topo1/test_ospf_nssa_topo1.py @@ -106,7 +106,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py b/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py index 1f0f87959af1..cce116e9748b 100644 --- a/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py +++ b/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py @@ -9,21 +9,16 @@ import os import sys -import json -from time import sleep from functools import partial import pytest # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.topolog import logger from lib.common_config import ( - run_frr_cmd, - shutdown_bringup_interface, - start_router_daemons, step, ) @@ -112,7 +107,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py b/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py index 175dca74e7a9..3c9e1b1a6f4f 100644 --- a/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py +++ b/tests/topotests/ospf_p2mp/test_ospf_p2mp_non_broadcast.py @@ -10,7 +10,6 @@ import os import sys -import json from time import sleep from functools import partial import pytest @@ -18,13 +17,10 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.topolog import logger from lib.common_config import ( - run_frr_cmd, - shutdown_bringup_interface, - start_router_daemons, step, ) @@ -116,7 +112,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_prefix_suppression/test_ospf_prefix_suppression.py b/tests/topotests/ospf_prefix_suppression/test_ospf_prefix_suppression.py index d5ea7ebc4048..f91cba8d3c57 100644 --- a/tests/topotests/ospf_prefix_suppression/test_ospf_prefix_suppression.py +++ b/tests/topotests/ospf_prefix_suppression/test_ospf_prefix_suppression.py @@ -10,21 +10,16 @@ import os import sys -import json -from time import sleep from functools import partial import pytest # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.topolog import logger from lib.common_config import ( - run_frr_cmd, - shutdown_bringup_interface, - start_router_daemons, step, ) @@ -125,7 +120,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_single_switch/test_ospf_single_switch.py b/tests/topotests/ospf_single_switch/test_ospf_single_switch.py index e53b5f5b1e52..0a8d8456daab 100644 --- a/tests/topotests/ospf_single_switch/test_ospf_single_switch.py +++ b/tests/topotests/ospf_single_switch/test_ospf_single_switch.py @@ -14,12 +14,11 @@ import pytest from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.topolog import logger from lib.common_config import verify_rib from lib.ospf import verify_ospf_rib -from _ast import Try pytestmark = pytest.mark.ospfd @@ -86,7 +85,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Tear-down the test environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_sr_te_topo1/test_ospf_sr_te_topo1.py b/tests/topotests/ospf_sr_te_topo1/test_ospf_sr_te_topo1.py index 21ae14323137..ec076bb3ccfd 100755 --- a/tests/topotests/ospf_sr_te_topo1/test_ospf_sr_te_topo1.py +++ b/tests/topotests/ospf_sr_te_topo1/test_ospf_sr_te_topo1.py @@ -164,7 +164,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ospf_sr_topo1/test_ospf_sr_topo1.py b/tests/topotests/ospf_sr_topo1/test_ospf_sr_topo1.py index 936b438e9d7c..bac585dd8f96 100644 --- a/tests/topotests/ospf_sr_topo1/test_ospf_sr_topo1.py +++ b/tests/topotests/ospf_sr_topo1/test_ospf_sr_topo1.py @@ -136,7 +136,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py index 8b3fc5808aad..7f9ad27eab99 100644 --- a/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py +++ b/tests/topotests/ospf_suppress_fa/test_ospf_suppress_fa.py @@ -24,7 +24,6 @@ import sys import json from functools import partial -import re import pytest # Save the Current Working Directory to find configuration files. diff --git a/tests/topotests/ospf_tilfa_topo1/test_ospf_tilfa_topo1.py b/tests/topotests/ospf_tilfa_topo1/test_ospf_tilfa_topo1.py index f939f3f578f0..246672488844 100644 --- a/tests/topotests/ospf_tilfa_topo1/test_ospf_tilfa_topo1.py +++ b/tests/topotests/ospf_tilfa_topo1/test_ospf_tilfa_topo1.py @@ -110,7 +110,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/ospf_topo1/test_ospf_topo1.py b/tests/topotests/ospf_topo1/test_ospf_topo1.py index a079f5698ff1..b9bdee3db467 100644 --- a/tests/topotests/ospf_topo1/test_ospf_topo1.py +++ b/tests/topotests/ospf_topo1/test_ospf_topo1.py @@ -93,7 +93,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_topo2/test_ospf_topo2.py b/tests/topotests/ospf_topo2/test_ospf_topo2.py index 8be06e41aff2..45ae338a245d 100644 --- a/tests/topotests/ospf_topo2/test_ospf_topo2.py +++ b/tests/topotests/ospf_topo2/test_ospf_topo2.py @@ -66,7 +66,7 @@ def tgen(request): router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_frr_config("frr.conf") tgen.start_router() diff --git a/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py b/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py index d07f5dc5c9a0..712c4e1d7c0e 100644 --- a/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py +++ b/tests/topotests/ospf_unnumbered/test_ospf_unnumbered.py @@ -89,7 +89,7 @@ def setup_module(mod): # tgen.mininet_cli() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospf_unnumbered_point_to_multipoint/test_ospf_unnumbered_point_to_multipoint.py b/tests/topotests/ospf_unnumbered_point_to_multipoint/test_ospf_unnumbered_point_to_multipoint.py index c0dd85cba077..a97b1145476e 100644 --- a/tests/topotests/ospf_unnumbered_point_to_multipoint/test_ospf_unnumbered_point_to_multipoint.py +++ b/tests/topotests/ospf_unnumbered_point_to_multipoint/test_ospf_unnumbered_point_to_multipoint.py @@ -92,7 +92,7 @@ def setup_module(mod): # tgen.mininet_cli() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ospfapi/test_ospf_clientapi.py b/tests/topotests/ospfapi/test_ospf_clientapi.py index 626a9d31854b..89a34ff9b58d 100644 --- a/tests/topotests/ospfapi/test_ospf_clientapi.py +++ b/tests/topotests/ospfapi/test_ospf_clientapi.py @@ -16,7 +16,6 @@ import subprocess import sys import time -from datetime import datetime, timedelta from functools import partial import pytest @@ -35,8 +34,7 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger +from lib.topogen import Topogen, TopoRouter pytestmark = [pytest.mark.ospfd] diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py index 49c25ab8f6da..c431147e5591 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_asbr_summary_topo1.py @@ -29,7 +29,6 @@ from lib.common_config import ( start_topology, write_test_header, - kill_router_daemons, write_test_footer, reset_config_on_routers, stop_router, @@ -37,7 +36,6 @@ verify_rib, create_static_routes, step, - start_router_daemons, create_route_maps, shutdown_bringup_interface, create_prefix_lists, @@ -163,7 +161,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. @@ -2456,7 +2454,7 @@ def test_ospfv3_type5_summary_tc51_p2(request): step("Configure and re configure all the commands 10 times in a loop.") - for itrate in range(0, 10): + for _ in range(0, 10): ospf_summ_r1 = { "r0": { "ospf6": { diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py index 00c98ac97c26..5f88f6d8357c 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_authentication.py @@ -14,9 +14,7 @@ import time import pytest from time import sleep -from copy import deepcopy import json -from lib.topotest import frr_unicode pytestmark = pytest.mark.ospf6d @@ -39,11 +37,8 @@ shutdown_bringup_interface, ) from lib.topolog import logger -from lib.topojson import build_topo_from_json, build_config_from_json -from lib.ospf import verify_ospf6_neighbor, config_ospf6_interface, clear_ospf -from ipaddress import IPv4Address - -# Global variables +from lib.topojson import build_config_from_json +from lib.ospf import verify_ospf6_neighbor, config_ospf6_interface topo = None # Reading the data from JSON File for topology creation jsonFile = "{}/ospfv3_authentication.json".format(CWD) @@ -118,7 +113,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. * `mod`: module name diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py index 0c1e3fa43e87..45652a3ee8e6 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp.py @@ -122,7 +122,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. @@ -285,7 +285,7 @@ def test_ospfv3_ecmp_tc16_p0(request): step("Verify that route in R2 in stalled with 8 next hops.") nh = [] - for item in range(1, 7): + for _ in range(1, 7): nh.append(llip) llip = get_llip("r0", "r1") diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py index 7c6773260edf..95f2493c2a8b 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_ecmp_lan.py @@ -13,11 +13,6 @@ import sys import time import pytest -import json -from copy import deepcopy -from ipaddress import IPv4Address -from lib.topotest import frr_unicode -import ipaddress # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -37,9 +32,6 @@ verify_rib, create_static_routes, step, - create_route_maps, - shutdown_bringup_interface, - create_interfaces_cfg, get_frr_ipv6_linklocal, ) from lib.topolog import logger @@ -47,16 +39,11 @@ from lib.ospf import ( verify_ospf6_neighbor, - config_ospf_interface, clear_ospf, verify_ospf6_rib, create_router_ospf, - verify_ospf6_interface, - verify_ospf6_database, - config_ospf6_interface, ) -from ipaddress import IPv6Address pytestmark = [pytest.mark.ospfd, pytest.mark.staticd] @@ -137,7 +124,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py index dc4ce888306e..cc96cd1731b7 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa.py @@ -78,7 +78,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py index 5a6c377aefe0..4ad725e3e69a 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_nssa2.py @@ -13,15 +13,10 @@ import sys import time import pytest -from copy import deepcopy import ipaddress from lib.ospf import ( verify_ospf6_neighbor, - config_ospf6_interface, - clear_ospf, verify_ospf6_rib, - verify_ospf6_interface, - verify_ospf6_database, create_router_ospf, ) @@ -29,12 +24,6 @@ # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.bgp import ( - verify_bgp_convergence, - create_router_bgp, - clear_bgp_and_verify, - verify_bgp_rib, -) from lib.topolog import logger from lib.common_config import ( start_topology, @@ -44,12 +33,9 @@ verify_rib, create_static_routes, step, - create_route_maps, - shutdown_bringup_interface, create_interfaces_cfg, check_router_status, ) -from ipaddress import IPv4Address from lib.topolog import logger from lib.topojson import build_config_from_json diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py index 069806a3ef46..ff88badeebcc 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_routemaps.py @@ -136,7 +136,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py index 916f655550b5..06989db894de 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_rte_calc.py @@ -45,7 +45,6 @@ verify_ospf6_neighbor, clear_ospf, verify_ospf6_rib, - verify_ospf_database, create_router_ospf, config_ospf6_interface, verify_ospf6_interface, @@ -127,7 +126,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py index 3bafd27f24e4..15e0f5316ea0 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py @@ -36,7 +36,6 @@ step, create_interfaces_cfg, create_debug_log_config, - apply_raw_config, ) from lib.topolog import logger from lib.topojson import build_config_from_json @@ -121,7 +120,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/pim_acl/test_pim_acl.py b/tests/topotests/pim_acl/test_pim_acl.py index 6e5092dabb50..d8eececf8151 100755 --- a/tests/topotests/pim_acl/test_pim_acl.py +++ b/tests/topotests/pim_acl/test_pim_acl.py @@ -169,7 +169,7 @@ def setup_module(module): tgen.start_router() -def teardown_module(module): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/pim_basic/test_pim.py b/tests/topotests/pim_basic/test_pim.py index 85b49aacc665..ce1abe42bb09 100644 --- a/tests/topotests/pim_basic/test_pim.py +++ b/tests/topotests/pim_basic/test_pim.py @@ -88,7 +88,7 @@ def setup_module(mod): # tgen.mininet_cli() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/pim_igmp_vrf/test_pim_vrf.py b/tests/topotests/pim_igmp_vrf/test_pim_vrf.py index 01c496d70388..d6d879d45fe7 100755 --- a/tests/topotests/pim_igmp_vrf/test_pim_vrf.py +++ b/tests/topotests/pim_igmp_vrf/test_pim_vrf.py @@ -92,7 +92,7 @@ from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger from lib.topotest import iproute2_is_vrf_capable -from lib.common_config import required_linux_kernel_version, retry +from lib.common_config import required_linux_kernel_version from lib.pim import McastTesterHelper @@ -205,7 +205,7 @@ def setup_module(module): ) -def teardown_module(module): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py b/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py index 7d958fd496d6..c07b1ffc1521 100644 --- a/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py +++ b/tests/topotests/rip_allow_ecmp/test_rip_allow_ecmp.py @@ -20,7 +20,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step pytestmark = [pytest.mark.ripd] @@ -39,7 +39,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/rip_bfd_topo1/test_rip_bfd_topo1.py b/tests/topotests/rip_bfd_topo1/test_rip_bfd_topo1.py index d03d5479fd81..26680f54600e 100644 --- a/tests/topotests/rip_bfd_topo1/test_rip_bfd_topo1.py +++ b/tests/topotests/rip_bfd_topo1/test_rip_bfd_topo1.py @@ -20,7 +20,6 @@ from functools import partial from lib import topotest from lib.topogen import Topogen, TopoRouter -from lib.topolog import logger pytestmark = [ pytest.mark.bfdd, diff --git a/tests/topotests/rip_passive_interface/test_rip_passive_interface.py b/tests/topotests/rip_passive_interface/test_rip_passive_interface.py index c2b28c4a3efe..ebc36d1fdc1c 100644 --- a/tests/topotests/rip_passive_interface/test_rip_passive_interface.py +++ b/tests/topotests/rip_passive_interface/test_rip_passive_interface.py @@ -21,7 +21,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step pytestmark = [pytest.mark.ripd] @@ -40,7 +40,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ripng_allow_ecmp/test_ripng_allow_ecmp.py b/tests/topotests/ripng_allow_ecmp/test_ripng_allow_ecmp.py index 08bb9999288e..060b558f0df3 100644 --- a/tests/topotests/ripng_allow_ecmp/test_ripng_allow_ecmp.py +++ b/tests/topotests/ripng_allow_ecmp/test_ripng_allow_ecmp.py @@ -20,7 +20,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step pytestmark = [pytest.mark.ripngd] @@ -39,7 +39,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/ripng_route_map/test_ripng_route_map.py b/tests/topotests/ripng_route_map/test_ripng_route_map.py index e1cc88e9b68d..4fadb5fbcf7f 100644 --- a/tests/topotests/ripng_route_map/test_ripng_route_map.py +++ b/tests/topotests/ripng_route_map/test_ripng_route_map.py @@ -20,8 +20,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.ripngd] @@ -39,7 +38,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/route_scale/scale_test_common.py b/tests/topotests/route_scale/scale_test_common.py index b3cba1cb4e3f..3e20296018dd 100644 --- a/tests/topotests/route_scale/scale_test_common.py +++ b/tests/topotests/route_scale/scale_test_common.py @@ -182,7 +182,6 @@ def route_install_helper(iter): # Build up a list of dicts with params for each step of the test; # use defaults where the step doesn't supply a value - scale_setups = [] s = scale_steps[iter] d = dict(zip(scale_keys, s)) diff --git a/tests/topotests/route_scale/test_route_scale1.py b/tests/topotests/route_scale/test_route_scale1.py index ccbdd515954e..68af979c2ffd 100644 --- a/tests/topotests/route_scale/test_route_scale1.py +++ b/tests/topotests/route_scale/test_route_scale1.py @@ -14,11 +14,8 @@ """ import os -import re import sys import pytest -import json -from functools import partial # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -26,9 +23,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers -from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger from scale_test_common import ( scale_build_common, diff --git a/tests/topotests/route_scale/test_route_scale2.py b/tests/topotests/route_scale/test_route_scale2.py index e244d4fbbc02..4be8554a0f2b 100644 --- a/tests/topotests/route_scale/test_route_scale2.py +++ b/tests/topotests/route_scale/test_route_scale2.py @@ -14,11 +14,8 @@ """ import os -import re import sys import pytest -import json -from functools import partial # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -26,9 +23,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers -from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger from scale_test_common import ( scale_build_common, diff --git a/tests/topotests/simple_snmp_test/test_simple_snmp.py b/tests/topotests/simple_snmp_test/test_simple_snmp.py index ee02c7b51993..0387e2927405 100755 --- a/tests/topotests/simple_snmp_test/test_simple_snmp.py +++ b/tests/topotests/simple_snmp_test/test_simple_snmp.py @@ -79,7 +79,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() diff --git a/tests/topotests/srv6_encap_src_addr/test_srv6_encap_src_addr.py b/tests/topotests/srv6_encap_src_addr/test_srv6_encap_src_addr.py index b8bcab8d93e1..854bc1cdade9 100755 --- a/tests/topotests/srv6_encap_src_addr/test_srv6_encap_src_addr.py +++ b/tests/topotests/srv6_encap_src_addr/test_srv6_encap_src_addr.py @@ -18,7 +18,6 @@ import sys import json import pytest -import functools CWD = os.path.dirname(os.path.realpath(__file__)) sys.path.append(os.path.join(CWD, "../")) @@ -56,7 +55,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() diff --git a/tests/topotests/srv6_locator/test_srv6_locator.py b/tests/topotests/srv6_locator/test_srv6_locator.py index 3a27d9c2fc5f..bab6746409ab 100755 --- a/tests/topotests/srv6_locator/test_srv6_locator.py +++ b/tests/topotests/srv6_locator/test_srv6_locator.py @@ -56,7 +56,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() @@ -81,12 +81,12 @@ def _check_sharpd_chunk(router, expected_chunk_file): def check_srv6_locator(router, expected_file): func = functools.partial(_check_srv6_locator, router, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" def check_sharpd_chunk(router, expected_file): func = functools.partial(_check_sharpd_chunk, router, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" # FOR DEVELOPER: diff --git a/tests/topotests/srv6_locator_custom_bits_length/test_srv6_locator_custom_bits_length.py b/tests/topotests/srv6_locator_custom_bits_length/test_srv6_locator_custom_bits_length.py index 92980d3b179e..d3df902aaed1 100755 --- a/tests/topotests/srv6_locator_custom_bits_length/test_srv6_locator_custom_bits_length.py +++ b/tests/topotests/srv6_locator_custom_bits_length/test_srv6_locator_custom_bits_length.py @@ -52,7 +52,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() @@ -77,12 +77,12 @@ def _check_sharpd_chunk(router, expected_chunk_file): def check_srv6_locator(router, expected_file): func = functools.partial(_check_srv6_locator, router, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" def check_sharpd_chunk(router, expected_file): func = functools.partial(_check_sharpd_chunk, router, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" # FOR DEVELOPER: diff --git a/tests/topotests/srv6_locator_usid/test_srv6_locator_usid.py b/tests/topotests/srv6_locator_usid/test_srv6_locator_usid.py index 54187351b2f4..e0c05c517991 100755 --- a/tests/topotests/srv6_locator_usid/test_srv6_locator_usid.py +++ b/tests/topotests/srv6_locator_usid/test_srv6_locator_usid.py @@ -49,7 +49,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() @@ -70,13 +70,13 @@ def _check_sharpd_chunk(router, expected_chunk_file): def check_srv6_locator(router, expected_file): func = functools.partial(_check_srv6_locator, router, expected_file) - success, result = topotest.run_and_expect(func, None, count=5, wait=3) + _, result = topotest.run_and_expect(func, None, count=5, wait=3) assert result is None, "Failed" def check_sharpd_chunk(router, expected_file): func = functools.partial(_check_sharpd_chunk, router, expected_file) - success, result = topotest.run_and_expect(func, None, count=5, wait=3) + _, result = topotest.run_and_expect(func, None, count=5, wait=3) assert result is None, "Failed" diff --git a/tests/topotests/srv6_static_route/test_srv6_route.py b/tests/topotests/srv6_static_route/test_srv6_route.py index 7a4cd39f2ddd..f23e199d4a6f 100755 --- a/tests/topotests/srv6_static_route/test_srv6_route.py +++ b/tests/topotests/srv6_static_route/test_srv6_route.py @@ -55,7 +55,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() @@ -74,7 +74,7 @@ def _check_srv6_static_route(router, expected_route_file): def check_srv6_static_route(router, expected_file): func = functools.partial(_check_srv6_static_route, router, expected_file) - success, result = topotest.run_and_expect(func, None, count=15, wait=1) + _, result = topotest.run_and_expect(func, None, count=15, wait=1) assert result is None, "Failed" # FOR DEVELOPER: diff --git a/tests/topotests/static_routing_mpls/test_static_routing_mpls.py b/tests/topotests/static_routing_mpls/test_static_routing_mpls.py index c1e249cc8f0f..a0f11c0126bc 100644 --- a/tests/topotests/static_routing_mpls/test_static_routing_mpls.py +++ b/tests/topotests/static_routing_mpls/test_static_routing_mpls.py @@ -14,11 +14,8 @@ """ import os -import re import sys import pytest -import json -from functools import partial import functools # Save the Current Working Directory to find configuration files. @@ -113,7 +110,7 @@ def _check_mpls_state(router, interface, configured=True): test_func = functools.partial( _check_mpls_state_interface, router, interface, up=configured ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) return success diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py index e01351506d9e..0d6b3e7b1d68 100644 --- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo2_ebgp.py @@ -150,7 +150,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py index 9d35b7dcd3c8..ff349f279ec1 100644 --- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo3_ebgp.py @@ -134,7 +134,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment diff --git a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py index 3e03055acdc0..c74d8d70a6d1 100644 --- a/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py +++ b/tests/topotests/static_routing_with_ebgp/test_static_routes_topo4_ebgp.py @@ -113,7 +113,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py index abae75e76e2f..926a9909e1c4 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo1_ibgp.py @@ -110,7 +110,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py index 820a736ad7c1..933e5410958b 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo2_ibgp.py @@ -152,7 +152,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py index 1ad963f314e1..9fabd9d5714b 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo3_ibgp.py @@ -133,7 +133,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment diff --git a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py index 0fc81aaf1ed2..f1b7606e79f6 100644 --- a/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py +++ b/tests/topotests/static_routing_with_ibgp/test_static_routes_topo4_ibgp.py @@ -111,7 +111,7 @@ def setup_module(mod): logger.info("Running setup_module() done") -def teardown_module(mod): +def teardown_module(): """ Teardown the pytest environment. diff --git a/tests/topotests/static_simple/test_static_simple.py b/tests/topotests/static_simple/test_static_simple.py index f862d81239c9..bb3580a1d8b2 100644 --- a/tests/topotests/static_simple/test_static_simple.py +++ b/tests/topotests/static_simple/test_static_simple.py @@ -13,11 +13,10 @@ import ipaddress import math import os -import sys import re import pytest -from lib.topogen import TopoRouter, Topogen, get_topogen +from lib.topogen import TopoRouter, Topogen from lib.topolog import logger from lib.common_config import retry, step @@ -80,7 +79,7 @@ def check_kernel(r1, super_prefix, count, add, is_blackhole, vrf, matchvia): kernel = r1.run(f"ip -4 route show{vrfstr}") logger.debug("checking kernel routing table%s:\n%s", vrfstr, kernel) - for i, net in enumerate(get_ip_networks(super_prefix, count)): + for _, net in enumerate(get_ip_networks(super_prefix, count)): if not add: assert str(net) not in kernel continue @@ -116,7 +115,6 @@ def do_config( else: super_prefix = "2001::/48" if do_ipv6 else "10.0.0.0/8" - matchtype = "" matchvia = "" if via == "blackhole": pass @@ -146,7 +144,7 @@ def do_config( if vrf: f.write("vrf {}\n".format(vrf)) - for i, net in enumerate(get_ip_networks(super_prefix, count)): + for _, net in enumerate(get_ip_networks(super_prefix, count)): if add: f.write("ip route {} {}\n".format(net, via)) else: diff --git a/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py index 0b2937c12a28..dc47527c74c2 100644 --- a/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py +++ b/tests/topotests/zebra_multiple_connected/test_zebra_multiple_connected.py @@ -15,7 +15,6 @@ """ import os -import re import sys import pytest import json @@ -29,7 +28,6 @@ # Import topogen and topotest helpers from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger # Required to instantiate the topology builder class. @@ -157,7 +155,7 @@ def test_zebra_noprefix_connected(): test_func = partial( topotest.router_output_cmp, router, "show ip route 192.168.44.0/24", expected ) - result, diff = topotest.run_and_expect(test_func, "", count=20, wait=1) + result, _ = topotest.run_and_expect(test_func, "", count=20, wait=1) assert result, "Connected Route should not have been added" diff --git a/tests/topotests/zebra_netlink/test_zebra_netlink.py b/tests/topotests/zebra_netlink/test_zebra_netlink.py index d970c04ee2d8..3748f9c4e3a6 100644 --- a/tests/topotests/zebra_netlink/test_zebra_netlink.py +++ b/tests/topotests/zebra_netlink/test_zebra_netlink.py @@ -13,9 +13,7 @@ """ # pylint: disable=C0413 import ipaddress -import json import sys -from functools import partial import pytest from lib import topotest @@ -42,7 +40,7 @@ def tgen(request): # Initialize all routers. router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") router.load_config(TopoRouter.RD_SHARP) diff --git a/tests/topotests/zebra_nht_resolution/test_verify_nh_resolution.py b/tests/topotests/zebra_nht_resolution/test_verify_nh_resolution.py index fbef0fefc7c9..16e458062d33 100644 --- a/tests/topotests/zebra_nht_resolution/test_verify_nh_resolution.py +++ b/tests/topotests/zebra_nht_resolution/test_verify_nh_resolution.py @@ -16,7 +16,6 @@ import pytest from lib.common_config import ( - start_topology, verify_rib, verify_ip_nht, step, @@ -24,7 +23,6 @@ ) # pylint: disable=C0413 -from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger diff --git a/tests/topotests/zebra_opaque/test_zebra_opaque.py b/tests/topotests/zebra_opaque/test_zebra_opaque.py index 25fbb97806de..4f49a69bdcaf 100644 --- a/tests/topotests/zebra_opaque/test_zebra_opaque.py +++ b/tests/topotests/zebra_opaque/test_zebra_opaque.py @@ -32,7 +32,7 @@ def setup_module(mod): router_list = tgen.routers() - for i, (rname, router) in enumerate(router_list.items(), 1): + for _, (rname, router) in enumerate(router_list.items(), 1): router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) @@ -49,7 +49,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): tgen = get_topogen() tgen.stop_topology() @@ -98,17 +98,17 @@ def _ospf6_converge(router): router = tgen.gears["r1"] test_func = functools.partial(_bgp_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Cannot see BGP community aliases "{}"'.format(router) router = tgen.gears["r3"] test_func = functools.partial(_ospf_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Cannot see OSPFv2 opaque attributes "{}"'.format(router) router = tgen.gears["r3"] test_func = functools.partial(_ospf6_converge, router) - success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, 'Cannot see OSPFv3 opaque attributes "{}"'.format(router) diff --git a/tests/topotests/zebra_rib/test_zebra_rib.py b/tests/topotests/zebra_rib/test_zebra_rib.py index 05036fa7ad47..93296cd51aa6 100644 --- a/tests/topotests/zebra_rib/test_zebra_rib.py +++ b/tests/topotests/zebra_rib/test_zebra_rib.py @@ -71,7 +71,7 @@ def setup_module(mod): tgen.start_router() -def teardown_module(mod): +def teardown_module(): "Teardown the pytest environment" tgen = get_topogen() tgen.stop_topology() @@ -235,7 +235,7 @@ def check_initial_routes_installed(router): return topotest.json_cmp(output, expected) test_func = partial(check_initial_routes_installed, r1) - success, result = topotest.run_and_expect(test_func, None, count=40, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=40, wait=1) static_rmapfile = "%s/r1/static_rmap.ref" % (thisDir) expected = open(static_rmapfile).read().rstrip() diff --git a/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py b/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py index 4a4cf0624f6b..f94b7d4a9c43 100755 --- a/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py +++ b/tests/topotests/zebra_seg6_route/test_zebra_seg6_route.py @@ -80,7 +80,7 @@ def check_connected(router, dest, expected): expected = open_json_file(os.path.join(CWD, "{}/routes_setup.json".format("r1"))) test_func = partial(check_connected, r1, "2001::/64", expected) - success, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) assert result is None, "Failed to fully setup connected routes needed" manifests = open_json_file(os.path.join(CWD, "{}/routes.json".format("r1"))) @@ -96,7 +96,7 @@ def check_connected(router, dest, expected): ) logger.info("CHECK {} {} {}".format(dest, nh, sid)) test_func = partial(check, r1, dest, manifest["out"]) - success, result = topotest.run_and_expect(test_func, None, count=20, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=20, wait=1) assert result is None, "Failed" diff --git a/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py b/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py index 0dc87741aacc..a90f5c9c9818 100755 --- a/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py +++ b/tests/topotests/zebra_seg6local_route/test_zebra_seg6local_route.py @@ -101,7 +101,7 @@ def check(router, dest, expected): dest, manifest["out"], ) - success, result = topotest.run_and_expect(test_func, None, count=25, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=25, wait=1) assert result is None, "Failed" From 36a310cc9f6ef7694d30fe3527a9462bb7155fd3 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Sat, 8 Jun 2024 07:15:47 +0200 Subject: [PATCH 291/472] zebra, lib: add locator name in sid notify messages In the near future, some daemons may only register SIDs. This may be the case for the pathd daemon when creating SRv6 binding SIDs. When a locator is getting deleted at ZEBRA level, the daemon may have an easy way to find out the SIds to unregister to. This commit proposes to add the locator name to the SID_SRV6_NOTIFY message whenever possible. Only case when an allocation failure happens, the locator will not be present. In all other places, the notify API at procol levels has the locator name extra-parameter. Signed-off-by: Philippe Guibert Signed-off-by: Carmine Scarpitta --- lib/zclient.c | 18 +++++++++++++++++- lib/zclient.h | 3 ++- zebra/zapi_msg.c | 11 ++++++++++- zebra/zapi_msg.h | 2 +- zebra/zebra_srv6.c | 15 ++++++++++++--- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index a1386e501a72..586ee9c2cbe5 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2136,9 +2136,12 @@ bool zapi_iptable_notify_decode(struct stream *s, bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t *func, uint32_t *wide_func, - enum zapi_srv6_sid_notify *note) + enum zapi_srv6_sid_notify *note, + char **p_locator_name) { uint32_t f, wf; + uint16_t len; + static char locator_name[SRV6_LOCNAME_SIZE] = {}; STREAM_GET(note, s, sizeof(*note)); STREAM_GET(ctx, s, sizeof(struct srv6_sid_ctx)); @@ -2151,6 +2154,19 @@ bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, if (wide_func) *wide_func = wf; + STREAM_GETW(s, len); + if (len > SRV6_LOCNAME_SIZE) { + *p_locator_name = NULL; + return false; + } + if (p_locator_name) { + if (len == 0) + *p_locator_name = NULL; + else { + STREAM_GET(locator_name, s, len); + *p_locator_name = locator_name; + } + } return true; stream_failure: diff --git a/lib/zclient.h b/lib/zclient.h index bfe955b7acc7..2877b347d8d0 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -1177,7 +1177,8 @@ bool zapi_ipset_notify_decode(struct stream *s, bool zapi_srv6_sid_notify_decode(struct stream *s, struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t *func, uint32_t *wide_func, - enum zapi_srv6_sid_notify *note); + enum zapi_srv6_sid_notify *note, + char **locator_name); /* Nexthop-group message apis */ extern enum zclient_send_status diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 164c0dd68723..2a1eea9594ee 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -1001,7 +1001,9 @@ void zsend_neighbor_notify(int cmd, struct interface *ifp, void zsend_srv6_sid_notify(struct zserv *client, const struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t func, - uint32_t wide_func, enum zapi_srv6_sid_notify note) + uint32_t wide_func, const char *locator_name, + enum zapi_srv6_sid_notify note) + { struct stream *s; uint16_t cmd = ZEBRA_SRV6_SID_NOTIFY; @@ -1027,6 +1029,13 @@ void zsend_srv6_sid_notify(struct zserv *client, const struct srv6_sid_ctx *ctx, stream_putl(s, func); /* SRv6 wide SID function */ stream_putl(s, wide_func); + /* SRv6 locator name optional */ + if (locator_name) { + stream_putw(s, strlen(locator_name)); + stream_put(s, locator_name, strlen(locator_name)); + } else + stream_putw(s, 0); + stream_putw_at(s, 0, stream_get_endp(s)); zserv_send_message(client, s); diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 3505bc0dc4e3..9e3ea6fb6ecd 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -97,7 +97,7 @@ extern void zsend_neighbor_notify(int cmd, struct interface *ifp, extern void zsend_srv6_sid_notify(struct zserv *client, const struct srv6_sid_ctx *ctx, struct in6_addr *sid_value, uint32_t func, - uint32_t wide_func, + uint32_t wide_func, const char *locator_name, enum zapi_srv6_sid_notify note); extern int zsend_client_close_notify(struct zserv *client, diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index a6db66bbccea..0ca77a49740c 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -2280,7 +2280,7 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, sid_value ? sid_value : &in6addr_any, locator_name); /* Notify client about SID alloc failure */ - zsend_srv6_sid_notify(client, ctx, sid_value, 0, 0, + zsend_srv6_sid_notify(client, ctx, sid_value, 0, 0, NULL, ZAPI_SRV6_SID_FAIL_ALLOC); } else if (ret == 0) { if (IS_ZEBRA_DEBUG_PACKET) @@ -2294,6 +2294,8 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, zsend_srv6_sid_notify(client, ctx, &(*sid)->value, (*sid)->func, (*sid)->wide_func, + (*sid)->locator ? (*sid)->locator->name + : NULL, ZAPI_SRV6_SID_ALLOCATED); } else { if (IS_ZEBRA_DEBUG_PACKET) @@ -2308,6 +2310,9 @@ static int srv6_manager_get_sid_internal(struct zebra_srv6_sid **sid, for (ALL_LIST_ELEMENTS_RO((*sid)->client_list, node, c)) zsend_srv6_sid_notify(c, ctx, &(*sid)->value, (*sid)->func, (*sid)->wide_func, + (*sid)->locator + ? (*sid)->locator->name + : NULL, ZAPI_SRV6_SID_ALLOCATED); } @@ -2366,6 +2371,7 @@ static int srv6_manager_release_sid_internal(struct zserv *client, struct zebra_srv6_sid_ctx *zctx; struct listnode *node, *nnode; char buf[256]; + const char *locator_name = NULL; if (IS_ZEBRA_DEBUG_PACKET) zlog_debug("%s: releasing SRv6 SID associated with ctx %s", @@ -2374,6 +2380,9 @@ static int srv6_manager_release_sid_internal(struct zserv *client, /* Lookup Zebra SID context and release it */ for (ALL_LIST_ELEMENTS(srv6->sids, node, nnode, zctx)) if (memcmp(&zctx->ctx, ctx, sizeof(struct srv6_sid_ctx)) == 0) { + if (zctx->sid && zctx->sid->locator) + locator_name = + (const char *)zctx->sid->locator->name; ret = release_srv6_sid(client, zctx); break; } @@ -2383,10 +2392,10 @@ static int srv6_manager_release_sid_internal(struct zserv *client, srv6_sid_ctx2str(buf, sizeof(buf), ctx)); if (ret == 0) - zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, locator_name, ZAPI_SRV6_SID_RELEASED); else - zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, + zsend_srv6_sid_notify(client, ctx, NULL, 0, 0, locator_name, ZAPI_SRV6_SID_FAIL_RELEASE); return ret; From 83b4706f309a97a1cd6d43e4a028848e94029740 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 18 Jun 2024 12:06:46 +0300 Subject: [PATCH 292/472] lib: Get the weight from Zebra Signed-off-by: Donatas Abraitis --- lib/zclient.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/zclient.c b/lib/zclient.c index 1aab7b48ba8f..ca4880da4361 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2134,6 +2134,7 @@ struct nexthop *nexthop_from_zapi_nexthop(const struct zapi_nexthop *znh) n->ifindex = znh->ifindex; n->gate = znh->gate; n->srte_color = znh->srte_color; + n->weight = znh->weight; /* * This function currently handles labels From dbf83cfd36a2c7d32f26a95d6daa70cb2d6d16e7 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 18 Jun 2024 12:07:23 +0300 Subject: [PATCH 293/472] zebra: Set the weight for non-recursive next-hop If using weighted ECMP, the weight for non-recursive next-hop should be inherited from recursive next-hop. Signed-off-by: Donatas Abraitis --- zebra/zebra_nhg.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 1246e4dba22b..55920102bb0a 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1747,6 +1747,12 @@ static struct nexthop *nexthop_set_resolved(afi_t afi, SET_FLAG(resolved_hop->flags, NEXTHOP_FLAG_ACTIVE); resolved_hop->vrf_id = nexthop->vrf_id; + + /* Using weighted ECMP, we should respect the weight and use + * the same value for non-recursive next-hop. + */ + resolved_hop->weight = nexthop->weight; + switch (newhop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: From 6d5d4f70000622b13ce73c45f69da75092fe35da Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 18 Jun 2024 12:16:54 +0300 Subject: [PATCH 294/472] tests: Check if recursive weighted ECMP works Signed-off-by: Donatas Abraitis --- .../bgp_weighted_ecmp_recursive/__init__.py | 0 .../bgp_weighted_ecmp_recursive/r1/frr.conf | 16 +++ .../bgp_weighted_ecmp_recursive/r2/frr.conf | 20 ++++ .../bgp_weighted_ecmp_recursive/r3/frr.conf | 20 ++++ .../bgp_weighted_ecmp_recursive/r4/frr.conf | 17 +++ .../bgp_weighted_ecmp_recursive/r5/frr.conf | 17 +++ .../test_bgp_weighted_ecmp_recursive.py | 109 ++++++++++++++++++ 7 files changed, 199 insertions(+) create mode 100644 tests/topotests/bgp_weighted_ecmp_recursive/__init__.py create mode 100644 tests/topotests/bgp_weighted_ecmp_recursive/r1/frr.conf create mode 100644 tests/topotests/bgp_weighted_ecmp_recursive/r2/frr.conf create mode 100644 tests/topotests/bgp_weighted_ecmp_recursive/r3/frr.conf create mode 100644 tests/topotests/bgp_weighted_ecmp_recursive/r4/frr.conf create mode 100644 tests/topotests/bgp_weighted_ecmp_recursive/r5/frr.conf create mode 100644 tests/topotests/bgp_weighted_ecmp_recursive/test_bgp_weighted_ecmp_recursive.py diff --git a/tests/topotests/bgp_weighted_ecmp_recursive/__init__.py b/tests/topotests/bgp_weighted_ecmp_recursive/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_weighted_ecmp_recursive/r1/frr.conf b/tests/topotests/bgp_weighted_ecmp_recursive/r1/frr.conf new file mode 100644 index 000000000000..f7c591f75fe5 --- /dev/null +++ b/tests/topotests/bgp_weighted_ecmp_recursive/r1/frr.conf @@ -0,0 +1,16 @@ +! +int r1-eth0 + ip address 192.168.12.1/24 +! +int r1-eth1 + ip address 192.168.13.1/24 +! +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 192.168.12.2 remote-as internal + neighbor 192.168.12.2 timers 1 3 + neighbor 192.168.12.2 timers connect 1 + neighbor 192.168.13.3 remote-as internal + neighbor 192.168.13.3 timers 1 3 + neighbor 192.168.13.3 timers connect 1 +! diff --git a/tests/topotests/bgp_weighted_ecmp_recursive/r2/frr.conf b/tests/topotests/bgp_weighted_ecmp_recursive/r2/frr.conf new file mode 100644 index 000000000000..dc25d4781c74 --- /dev/null +++ b/tests/topotests/bgp_weighted_ecmp_recursive/r2/frr.conf @@ -0,0 +1,20 @@ +! +int r2-eth0 + ip address 192.168.12.2/24 +! +int r2-eth1 + ip address 192.168.24.2/24 +! +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 192.168.12.1 remote-as internal + neighbor 192.168.12.1 timers 1 3 + neighbor 192.168.12.1 timers connect 1 + neighbor 192.168.24.4 remote-as internal + neighbor 192.168.24.4 timers 1 3 + neighbor 192.168.24.4 timers connect 1 + address-family ipv4 unicast + redistribute connected + neighbor 192.168.12.1 route-reflector-client + exit-address-family +! diff --git a/tests/topotests/bgp_weighted_ecmp_recursive/r3/frr.conf b/tests/topotests/bgp_weighted_ecmp_recursive/r3/frr.conf new file mode 100644 index 000000000000..bdeb35b50f21 --- /dev/null +++ b/tests/topotests/bgp_weighted_ecmp_recursive/r3/frr.conf @@ -0,0 +1,20 @@ +! +int r3-eth0 + ip address 192.168.13.3/24 +! +int r3-eth1 + ip address 192.168.35.3/24 +! +router bgp 65000 + no bgp ebgp-requires-policy + neighbor 192.168.13.1 remote-as internal + neighbor 192.168.13.1 timers 1 3 + neighbor 192.168.13.1 timers connect 1 + neighbor 192.168.35.5 remote-as internal + neighbor 192.168.35.5 timers 1 3 + neighbor 192.168.35.5 timers connect 1 + address-family ipv4 unicast + redistribute connected + neighbor 192.168.13.1 route-reflector-client + exit-address-family +! diff --git a/tests/topotests/bgp_weighted_ecmp_recursive/r4/frr.conf b/tests/topotests/bgp_weighted_ecmp_recursive/r4/frr.conf new file mode 100644 index 000000000000..0662a4dc499e --- /dev/null +++ b/tests/topotests/bgp_weighted_ecmp_recursive/r4/frr.conf @@ -0,0 +1,17 @@ +! +int r4-eth0 + ip address 192.168.24.4/24 +! +router bgp 65000 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.24.2 remote-as internal + neighbor 192.168.24.2 timers 1 3 + neighbor 192.168.24.2 timers connect 1 + address-family ipv4 unicast + network 10.10.10.10/32 route-map rmap + exit-address-family +! +route-map rmap permit 10 + set extcommunity bandwidth 4000 +exit diff --git a/tests/topotests/bgp_weighted_ecmp_recursive/r5/frr.conf b/tests/topotests/bgp_weighted_ecmp_recursive/r5/frr.conf new file mode 100644 index 000000000000..bc24a96b519b --- /dev/null +++ b/tests/topotests/bgp_weighted_ecmp_recursive/r5/frr.conf @@ -0,0 +1,17 @@ +! +int r5-eth0 + ip address 192.168.35.5/24 +! +router bgp 65000 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.35.3 remote-as internal + neighbor 192.168.35.3 timers 1 3 + neighbor 192.168.35.3 timers connect 1 + address-family ipv4 unicast + network 10.10.10.10/32 route-map rmap + exit-address-family +! +route-map rmap permit 10 + set extcommunity bandwidth 5000 +exit diff --git a/tests/topotests/bgp_weighted_ecmp_recursive/test_bgp_weighted_ecmp_recursive.py b/tests/topotests/bgp_weighted_ecmp_recursive/test_bgp_weighted_ecmp_recursive.py new file mode 100644 index 000000000000..7a6d068e56bd --- /dev/null +++ b/tests/topotests/bgp_weighted_ecmp_recursive/test_bgp_weighted_ecmp_recursive.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by +# Donatas Abraitis +# + +""" +Test if weighted ECMP works and recursive weight (link bandwidth) is +inherited to non-recursive next-hops. +""" + +import os +import re +import sys +import json +import pytest +import functools + +pytestmark = [pytest.mark.bgpd] + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.common_config import step + + +def setup_module(mod): + topodef = { + "s1": ("r1", "r2"), + "s2": ("r1", "r3"), + "s3": ("r2", "r4"), + "s4": ("r3", "r5"), + } + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_weighted_ecmp_recursive(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + + def _bgp_converge(): + output = json.loads(r1.vtysh_cmd("show ip route 10.10.10.10/32 json")) + expected = { + "10.10.10.10/32": [ + { + "selected": True, + "installed": True, + "nexthops": [ + { + "ip": "192.168.24.4", + "active": True, + "recursive": True, + "weight": 204, + }, + { + "ip": "192.168.12.2", + "active": True, + "resolver": True, + "weight": 204, + }, + { + "ip": "192.168.35.5", + "active": True, + "recursive": True, + "weight": 255, + }, + { + "ip": "192.168.13.3", + "active": True, + "resolver": True, + "weight": 255, + }, + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From 073fec520c75d2468bd0eff0933feaab3283449c Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 18 Jun 2024 12:11:44 +0200 Subject: [PATCH 295/472] lib: add json API to dump and override row naming convention The following table is not compliant with caml format when displayed in json: > ttable_add_row( > tt, > "Vertex|Type|Metric|Next-Hop|Interface|Parent"); > > ttable_json(tt, "ssdsss"); output observed: > [..] > { > "Vertex":"r1", > "Type":"", > "Metric":0, > "Next-Hop":"", > "Interface":"", > "Parent":"" > } output expected: > [..] > { > "vertex":"r1", > "type":"", > "metric":0, > "nextHop":"", > "interface":"", > "parent":"" > } Override the ttable_json() function with a new function which has an extra paramter: this parameter will redefine the initial row value for json: > ttable_json_with_json_text(tt, > "vertex|type|metric|nextHop|interface|parent"); Signed-off-by: Philippe Guibert --- lib/termtable.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-- lib/termtable.h | 15 ++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/lib/termtable.c b/lib/termtable.c index 9b36d5ebfa8b..88cc25bf68c5 100644 --- a/lib/termtable.c +++ b/lib/termtable.c @@ -496,7 +496,9 @@ char *ttable_dump(struct ttable *tt, const char *newline) * l int64 * s string (default) */ -json_object *ttable_json(struct ttable *tt, const char *const formats) +static json_object *ttable_json_internal(struct ttable *tt, + const char *const formats, + const char *row_text[]) { struct ttable_cell *row; /* iteration pointers */ json_object *json = NULL; @@ -522,9 +524,55 @@ json_object *ttable_json(struct ttable *tt, const char *const formats) default: val = json_object_new_string(row[j].text); } - json_object_object_add(jobj, tt->table[0][j].text, val); + if (row_text) + json_object_object_add(jobj, row_text[j], val); + else + json_object_object_add(jobj, + tt->table[0][j].text, + val); } } return json; } + +json_object *ttable_json(struct ttable *tt, const char *const formats) +{ + return ttable_json_internal(tt, formats, NULL); +} + +json_object *ttable_json_with_json_text(struct ttable *tt, + const char *const formats, + const char *json_override_text) +{ + char **row_name; /* iteration pointers */ + char *res, *section, *orig; + int col = 0; + int ncols = 0, j; + json_object *json = NULL; + + if (json_override_text) { + /* count how many columns we have */ + for (j = 0; json_override_text[j]; j++) + ncols += !!(json_override_text[j] == '|'); + ncols++; + } + if (json_override_text == NULL || ncols != tt->ncols) + return ttable_json_internal(tt, formats, NULL); + + /* CALLOC a block of cells */ + row_name = XCALLOC(MTYPE_TTABLE, ncols * sizeof(char *)); + orig = XSTRDUP(MTYPE_TTABLE, json_override_text); + res = orig; + while (res && col < ncols) { + section = strsep(&res, "|"); + row_name[col] = XSTRDUP(MTYPE_TTABLE, section); + col++; + } + json = ttable_json_internal(tt, formats, (const char **)row_name); + for (j = 0; j < col; j++) + XFREE(MTYPE_TTABLE, row_name[j]); + XFREE(MTYPE_TTABLE, row_name); + XFREE(MTYPE_TTABLE, orig); + return json; +} diff --git a/lib/termtable.h b/lib/termtable.h index 7258682bd80a..0782c82abdfd 100644 --- a/lib/termtable.h +++ b/lib/termtable.h @@ -289,6 +289,21 @@ char *ttable_dump(struct ttable *tt, const char *newline); */ json_object *ttable_json(struct ttable *tt, const char *const formats); +/** + * Convert a table to a JSON array of objects. + * + * Caller must free the returned json_object structure. + * + * @param tt the table to convert + * @param formats an array of characters indicating what JSON type should be + * used. + * @param formats an optinal string of row headers that overrids the first row of the table. + * This is useful to get naming convention that align with caml Format. + */ +json_object *ttable_json_with_json_text(struct ttable *tt, + const char *const formats, + const char *json_override_text); + #ifdef __cplusplus } #endif From 73bfc5865f4ded8297096bbdb3cc67b1ba54600f Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 19:40:13 +0100 Subject: [PATCH 296/472] isisd: Add API to get SRv6 locator info Add an API to request information from the SRv6 SID Manager (zebra) regarding a specific SRv6 locator. Signed-off-by: Carmine Scarpitta --- isisd/isis_zebra.c | 18 ++++++++++++++++++ isisd/isis_zebra.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 2412ec5e84c9..f5b3f712be4e 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -1368,6 +1368,24 @@ int isis_zebra_srv6_manager_release_locator_chunk(const char *name) return srv6_manager_release_locator_chunk(zclient, name); } +/** + * Ask the SRv6 Manager (zebra) about a specific locator + * + * @param name Locator name + * @return 0 on success, -1 otherwise + */ +int isis_zebra_srv6_manager_get_locator(const char *name) +{ + if (!name) + return -1; + + /* + * Send the Get Locator request to the SRv6 Manager and return the + * result + */ + return srv6_manager_get_locator(zclient, name); +} + static zclient_handler *const isis_handlers[] = { [ZEBRA_ROUTER_ID_UPDATE] = isis_router_id_update_zebra, [ZEBRA_INTERFACE_ADDRESS_ADD] = isis_zebra_if_address_add, diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index f1684b7c25d4..bfd23f69f495 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -68,4 +68,6 @@ void isis_zebra_srv6_adj_sid_uninstall(struct srv6_adjacency *sra); extern int isis_zebra_srv6_manager_get_locator_chunk(const char *name); extern int isis_zebra_srv6_manager_release_locator_chunk(const char *name); +extern int isis_zebra_srv6_manager_get_locator(const char *name); + #endif /* _ZEBRA_ISIS_ZEBRA_H */ From 3fce2928e293c59bb63ef76455525dca602385dd Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 9 May 2024 11:23:53 +0200 Subject: [PATCH 297/472] isisd: Add API to get/release SRv6 SIDs Add an API to get/release SRv6 SIDs through the SRv6 SID Manager. Signed-off-by: Carmine Scarpitta --- isisd/isis_zebra.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++ isisd/isis_zebra.h | 5 +++ 2 files changed, 102 insertions(+) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index f5b3f712be4e..226ee5679675 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -644,6 +644,40 @@ int isis_zebra_request_label_range(uint32_t base, uint32_t chunk_size) return 0; } +/** + * Request an End.X SID for an IS-IS adjacency. + * + * @param adj IS-IS Adjacency + */ +void isis_zebra_request_srv6_sid_endx(struct isis_adjacency *adj) +{ + struct isis_circuit *circuit = adj->circuit; + struct isis_area *area = circuit->area; + struct in6_addr nexthop; + struct srv6_sid_ctx ctx = {}; + struct in6_addr sid_value = {}; + bool ret; + + if (!area || !area->srv6db.srv6_locator) + return; + + /* Determine nexthop IP address */ + if (!circuit->ipv6_router || !adj->ll_ipv6_count) + return; + + nexthop = adj->ll_ipv6_addrs[0]; + + ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END_X; + ctx.nh6 = nexthop; + ret = isis_zebra_request_srv6_sid(&ctx, &sid_value, + area->srv6db.config.srv6_locator_name); + if (!ret) { + zlog_err("%s: not allocated new End.X SID for IS-IS area %s", + __func__, area->area_tag); + return; + } +} + /** * Release Label Range to the Label Manager. * @@ -1386,6 +1420,69 @@ int isis_zebra_srv6_manager_get_locator(const char *name) return srv6_manager_get_locator(zclient, name); } +/** + * Ask the SRv6 Manager (zebra) to allocate a SID. + * + * Optionally, it is possible to provide an IPv6 address (sid_value parameter). + * + * When sid_value is provided, the SRv6 Manager allocates the requested SID + * address, if the request can be satisfied (explicit allocation). + * + * When sid_value is not provided, the SRv6 Manager allocates any available SID + * from the provided locator (dynamic allocation). + * + * @param ctx Context to be associated with the request SID + * @param sid_value IPv6 address to be associated with the requested SID (optional) + * @param locator_name Name of the locator from which the SID must be allocated + */ +bool isis_zebra_request_srv6_sid(const struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, + const char *locator_name) +{ + int ret; + + if (!ctx || !locator_name) + return false; + + /* + * Send the Get SRv6 SID request to the SRv6 Manager and check the + * result + */ + ret = srv6_manager_get_sid(zclient, ctx, sid_value, locator_name, NULL); + if (ret < 0) { + zlog_warn("%s: error getting SRv6 SID!", __func__); + return false; + } + + return true; +} + +/** + * Ask the SRv6 Manager (zebra) to release a previously allocated SID. + * + * This function is used to tell the SRv6 Manager that IS-IS no longer intends + * to use the SID. + * + * @param ctx Context to be associated with the SID to be released + */ +void isis_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx) +{ + int ret; + + if (!ctx) + return; + + /* + * Send the Release SRv6 SID request to the SRv6 Manager and check the + * result + */ + ret = srv6_manager_release_sid(zclient, ctx); + if (ret < 0) { + zlog_warn("%s: error releasing SRv6 SID!", __func__); + return; + } +} + static zclient_handler *const isis_handlers[] = { [ZEBRA_ROUTER_ID_UPDATE] = isis_router_id_update_zebra, [ZEBRA_INTERFACE_ADDRESS_ADD] = isis_zebra_if_address_add, diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index bfd23f69f495..79da16efac49 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -69,5 +69,10 @@ extern int isis_zebra_srv6_manager_get_locator_chunk(const char *name); extern int isis_zebra_srv6_manager_release_locator_chunk(const char *name); extern int isis_zebra_srv6_manager_get_locator(const char *name); +extern void isis_zebra_request_srv6_sid_endx(struct isis_adjacency *adj); +extern bool isis_zebra_request_srv6_sid(const struct srv6_sid_ctx *ctx, + struct in6_addr *sid_value, + const char *locator_name); +extern void isis_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx); #endif /* _ZEBRA_ISIS_ZEBRA_H */ From 9ae38eede814b14051179fb96f9d77ac04a45bf9 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 9 May 2024 09:17:49 +0200 Subject: [PATCH 298/472] isisd: Deal with SRv6 locator instead of chunk Currently, when SRv6 is enabled in IS-IS, IS-IS requests a locator chunk from Zebra. Zebra assigns a locator chunk to IS-IS, and then IS-IS can allocate SIDs from the locator chunk. Recently, the implementation of SRv6 in Zebra has been improved, and a new API has been introduced for obtaining/releasing the SIDs. Now, the daemons no longer need to request a chunk. Instead, the daemons interact with Zebra to obtain information about the locator and subsequently to allocate/release the SIDs. This commit extends IS-IS to use the new SRv6 API. In particular, it removes the chunk throughout the IS-IS code and modifies IS-IS to request/save/advertise the locator instead of the chunk. Signed-off-by: Carmine Scarpitta --- isisd/isis_lsp.c | 13 +++----- isisd/isis_nb_config.c | 6 ++-- isisd/isis_srv6.c | 74 ++++++++++++++++++++++-------------------- isisd/isis_srv6.h | 8 +++-- isisd/isis_zebra.c | 3 ++ 5 files changed, 53 insertions(+), 51 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index c98cee06a568..13f5148d4ab5 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -1222,17 +1222,11 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) } /* Add SRv6 Locator TLV. */ - if (area->srv6db.config.enabled && - !list_isempty(area->srv6db.srv6_locator_chunks)) { + if (area->srv6db.config.enabled && area->srv6db.srv6_locator) { struct isis_srv6_locator locator = {}; - struct srv6_locator_chunk *chunk; - - /* TODO: support more than one locator */ - chunk = (struct srv6_locator_chunk *)listgetdata( - listhead(area->srv6db.srv6_locator_chunks)); locator.metric = 0; - locator.prefix = chunk->prefix; + locator.prefix = area->srv6db.srv6_locator->prefix; locator.flags = 0; locator.algorithm = 0; @@ -1252,7 +1246,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) isis_tlvs_add_ipv6_reach(lsp->tlvs, isis_area_ipv6_topology(area), - &chunk->prefix, 0, false, NULL); + &area->srv6db.srv6_locator->prefix, 0, + false, NULL); } /* IPv4 address and TE router ID TLVs. diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 763b8b73d270..30c90baa5432 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -3518,10 +3518,10 @@ int isis_instance_segment_routing_srv6_locator_modify( sr_debug("Configured SRv6 locator %s for IS-IS area %s", loc_name, area->area_tag); - sr_debug("Trying to get a chunk from locator %s for IS-IS area %s", - loc_name, area->area_tag); + sr_debug("Trying to get locator %s for IS-IS area %s", loc_name, + area->area_tag); - if (isis_zebra_srv6_manager_get_locator_chunk(loc_name) < 0) + if (isis_zebra_srv6_manager_get_locator(loc_name) < 0) return NB_ERR; return NB_OK; diff --git a/isisd/isis_srv6.c b/isisd/isis_srv6.c index 44fd599cbbcf..7cf1d91b4638 100644 --- a/isisd/isis_srv6.c +++ b/isisd/isis_srv6.c @@ -146,6 +146,10 @@ bool isis_srv6_locator_unset(struct isis_area *area) srv6_locator_chunk_free(&chunk); } + /* Clear locator */ + srv6_locator_free(area->srv6db.srv6_locator); + area->srv6db.srv6_locator = NULL; + /* Clear locator name */ memset(area->srv6db.config.srv6_locator_name, 0, sizeof(area->srv6db.config.srv6_locator_name)); @@ -235,16 +239,16 @@ static bool sid_exist(struct isis_area *area, const struct in6_addr *sid) * Request a SID from the SRv6 locator. * * @param area IS-IS area - * @param chunk SRv6 locator chunk + * @param locator SRv6 locator * @param sid_func The FUNCTION part of the SID to be allocated (a negative * number will allocate the first available SID) * * @return First available SID on success or in6addr_any if the SRv6 - * locator chunk is full + * locator is full */ -static struct in6_addr -srv6_locator_request_sid(struct isis_area *area, - struct srv6_locator_chunk *chunk, int sid_func) +static struct in6_addr srv6_locator_request_sid(struct isis_area *area, + struct srv6_locator *locator, + int sid_func) { struct in6_addr sid; uint8_t offset = 0; @@ -252,22 +256,22 @@ srv6_locator_request_sid(struct isis_area *area, uint32_t func_max; bool allocated = false; - if (!area || !chunk) + if (!area || !locator) return in6addr_any; sr_debug("ISIS-SRv6 (%s): requested new SID from locator %s", - area->area_tag, chunk->locator_name); + area->area_tag, locator->name); /* Let's build the SID, step by step. A SID has the following structure (defined in RFC 8986): LOCATOR:FUNCTION:ARGUMENT.*/ /* First, we encode the LOCATOR in the L most significant bits. */ - sid = chunk->prefix.prefix; + sid = locator->prefix.prefix; /* The next part of the SID is the FUNCTION. Let's compute the length * and the offset of the FUNCTION in the SID */ - func_len = chunk->function_bits_length; - offset = chunk->block_bits_length + chunk->node_bits_length; + func_len = locator->function_bits_length; + offset = locator->block_bits_length + locator->node_bits_length; /* Then, encode the FUNCTION */ if (sid_func >= 0) { @@ -298,7 +302,7 @@ srv6_locator_request_sid(struct isis_area *area, if (!allocated) { /* We ran out of available SIDs */ zlog_warn("ISIS-SRv6 (%s): no SIDs available in locator %s", - area->area_tag, chunk->locator_name); + area->area_tag, locator->name); return in6addr_any; } @@ -312,35 +316,34 @@ srv6_locator_request_sid(struct isis_area *area, * Allocate an SRv6 SID from an SRv6 locator. * * @param area IS-IS area - * @param chunk SRv6 locator chunk + * @param locator SRv6 locator * @param behavior SRv6 Endpoint Behavior bound to the SID * * @result the allocated SID on success, NULL otherwise */ struct isis_srv6_sid * -isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator_chunk *chunk, - enum srv6_endpoint_behavior_codepoint behavior, - int sid_func) +isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator *locator, + enum srv6_endpoint_behavior_codepoint behavior, int sid_func) { struct isis_srv6_sid *sid = NULL; - if (!area || !chunk) + if (!area || !locator) return NULL; sid = XCALLOC(MTYPE_ISIS_SRV6_SID, sizeof(struct isis_srv6_sid)); - sid->sid = srv6_locator_request_sid(area, chunk, sid_func); + sid->sid = srv6_locator_request_sid(area, locator, sid_func); if (IPV6_ADDR_SAME(&sid->sid, &in6addr_any)) { isis_srv6_sid_free(sid); return NULL; } sid->behavior = behavior; - sid->structure.loc_block_len = chunk->block_bits_length; - sid->structure.loc_node_len = chunk->node_bits_length; - sid->structure.func_len = chunk->function_bits_length; - sid->structure.arg_len = chunk->argument_bits_length; - sid->locator = chunk; + sid->structure.loc_block_len = locator->block_bits_length; + sid->structure.loc_node_len = locator->node_bits_length; + sid->structure.func_len = locator->function_bits_length; + sid->structure.arg_len = locator->argument_bits_length; + sid->locator = locator; sid->area = area; return sid; @@ -387,11 +390,10 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup, struct isis_srv6_lan_endx_sid_subtlv *ladj_sid; struct in6_addr nexthop; uint8_t flags = 0; - struct srv6_locator_chunk *chunk; + struct srv6_locator *locator; uint32_t behavior; - if (!area || !area->srv6db.srv6_locator_chunks || - list_isempty(area->srv6db.srv6_locator_chunks)) + if (!area || !area->srv6db.srv6_locator) return; sr_debug("ISIS-SRv6 (%s): Add %s End.X SID", area->area_tag, @@ -401,10 +403,7 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup, if (!circuit->ipv6_router || !adj->ll_ipv6_count) return; - chunk = (struct srv6_locator_chunk *)listgetdata( - listhead(area->srv6db.srv6_locator_chunks)); - if (!chunk) - return; + locator = area->srv6db.srv6_locator; nexthop = adj->ll_ipv6_addrs[0]; @@ -415,21 +414,21 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup, if (circuit->ext == NULL) circuit->ext = isis_alloc_ext_subtlvs(); - behavior = (CHECK_FLAG(chunk->flags, SRV6_LOCATOR_USID)) + behavior = (CHECK_FLAG(locator->flags, SRV6_LOCATOR_USID)) ? SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID : SRV6_ENDPOINT_BEHAVIOR_END_X; sra = XCALLOC(MTYPE_ISIS_SRV6_INFO, sizeof(*sra)); sra->type = backup ? ISIS_SRV6_ADJ_BACKUP : ISIS_SRV6_ADJ_NORMAL; sra->behavior = behavior; - sra->locator = chunk; - sra->structure.loc_block_len = chunk->block_bits_length; - sra->structure.loc_node_len = chunk->node_bits_length; - sra->structure.func_len = chunk->function_bits_length; - sra->structure.arg_len = chunk->argument_bits_length; + sra->locator = locator; + sra->structure.loc_block_len = locator->block_bits_length; + sra->structure.loc_node_len = locator->node_bits_length; + sra->structure.func_len = locator->function_bits_length; + sra->structure.arg_len = locator->argument_bits_length; sra->nexthop = nexthop; - sra->sid = srv6_locator_request_sid(area, chunk, -1); + sra->sid = srv6_locator_request_sid(area, locator, -1); if (IPV6_ADDR_SAME(&sra->sid, &in6addr_any)) { XFREE(MTYPE_ISIS_SRV6_INFO, sra); return; @@ -832,6 +831,9 @@ void isis_srv6_area_term(struct isis_area *area) srv6_locator_chunk_free(&chunk); list_delete(&srv6db->srv6_locator_chunks); + srv6_locator_free(area->srv6db.srv6_locator); + area->srv6db.srv6_locator = NULL; + /* Free SRv6 SIDs list */ list_delete(&srv6db->srv6_sids); list_delete(&srv6db->srv6_endx_sids); diff --git a/isisd/isis_srv6.h b/isisd/isis_srv6.h index 7f16712ae306..6abc6d73451a 100644 --- a/isisd/isis_srv6.h +++ b/isisd/isis_srv6.h @@ -44,7 +44,7 @@ struct isis_srv6_sid { struct isis_srv6_sid_structure structure; /* Parent SRv6 locator */ - struct srv6_locator_chunk *locator; + struct srv6_locator *locator; /* Backpointer to IS-IS area */ struct isis_area *area; @@ -89,7 +89,7 @@ struct srv6_adjacency { struct isis_srv6_sid_structure structure; /* Parent SRv6 locator */ - struct srv6_locator_chunk *locator; + struct srv6_locator *locator; /* Adjacency-SID nexthop information */ struct in6_addr nexthop; @@ -109,6 +109,8 @@ struct srv6_adjacency { /* Per-area IS-IS SRv6 Data Base (SRv6 DB) */ struct isis_srv6_db { + /* List of SRv6 Locator */ + struct srv6_locator *srv6_locator; /* List of SRv6 Locator chunks */ struct list *srv6_locator_chunks; @@ -149,7 +151,7 @@ bool isis_srv6_locator_unset(struct isis_area *area); void isis_srv6_interface_set(struct isis_area *area, const char *ifname); struct isis_srv6_sid * -isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator_chunk *chunk, +isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator *locator, enum srv6_endpoint_behavior_codepoint behavior, int sid_func); extern void isis_srv6_sid_free(struct isis_srv6_sid *sid); diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 226ee5679675..44ef182ba97f 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -1369,6 +1369,9 @@ static int isis_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS) } } + srv6_locator_free(area->srv6db.srv6_locator); + area->srv6db.srv6_locator = NULL; + /* Regenerate LSPs to advertise that the locator no longer * exists */ lsp_regenerate_schedule(area, area->is_type, 0); From 1224d15653b98db5b6a7c671501b7ec80b3ce649 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Mon, 25 Mar 2024 00:41:50 +0100 Subject: [PATCH 299/472] isisd: Receive SRv6 locator info from zebra This commit extends IS-IS to process locator information received from SRv6 Manager (zebra) and save the locator info in the SRv6 database. Signed-off-by: Carmine Scarpitta --- isisd/isis_zebra.c | 107 +++++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 29 deletions(-) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 44ef182ba97f..be8bb5c40668 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -678,6 +678,36 @@ void isis_zebra_request_srv6_sid_endx(struct isis_adjacency *adj) } } +static void request_srv6_sids(struct isis_area *area) +{ + struct srv6_sid_ctx ctx = {}; + struct in6_addr sid_value = {}; + struct listnode *node; + struct isis_adjacency *adj; + bool ret; + + if (!area || !area->srv6db.config.enabled || !area->srv6db.srv6_locator) + return; + + sr_debug("Requesting SRv6 SIDs for IS-IS area %s", area->area_tag); + + /* Request new SRv6 End SID */ + ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END; + ret = isis_zebra_request_srv6_sid(&ctx, &sid_value, + area->srv6db.config.srv6_locator_name); + if (!ret) { + zlog_err("%s: not allocated new End SID for IS-IS area %s", + __func__, area->area_tag); + return; + } + + /* Create SRv6 End.X SIDs from existing IS-IS Adjacencies */ + for (ALL_LIST_ELEMENTS_RO(area->adjacency_list, node, adj)) { + if (adj->ll_ipv6_count > 0) + isis_zebra_request_srv6_sid_endx(adj); + } +} + /** * Release Label Range to the Label Manager. * @@ -1251,6 +1281,53 @@ static int isis_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) return 0; } +/** + * Internal function to process an SRv6 locator + * + * @param locator The locator to be processed + */ +static int isis_zebra_process_srv6_locator_internal(struct srv6_locator *locator) +{ + struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct isis_area *area; + struct listnode *node; + + if (!isis || !locator) + return -1; + + zlog_info("%s: Received SRv6 locator %s %pFX, loc-block-len=%u, loc-node-len=%u func-len=%u, arg-len=%u", + __func__, locator->name, &locator->prefix, + locator->block_bits_length, locator->node_bits_length, + locator->function_bits_length, locator->argument_bits_length); + + /* Walk through all areas of the ISIS instance */ + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + /* + * Check if the IS-IS area is configured to use the received + * locator + */ + if (strncmp(area->srv6db.config.srv6_locator_name, locator->name, + sizeof(area->srv6db.config.srv6_locator_name)) != 0) { + zlog_err("%s: SRv6 Locator name unmatch %s:%s", + __func__, area->srv6db.config.srv6_locator_name, + locator->name); + continue; + } + + sr_debug("SRv6 locator (locator %s, prefix %pFX) set for IS-IS area %s", + locator->name, &locator->prefix, area->area_tag); + + /* Store the locator in the IS-IS area */ + area->srv6db.srv6_locator = srv6_locator_alloc(locator->name); + srv6_locator_copy(area->srv6db.srv6_locator, locator); + + /* Request SIDs from the locator */ + request_srv6_sids(area); + } + + return 0; +} + /** * Callback to process an SRv6 locator received from SRv6 Manager (zebra). * @@ -1260,8 +1337,6 @@ static int isis_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS) { struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); struct srv6_locator loc = {}; - struct listnode *node; - struct isis_area *area; if (!isis) return -1; @@ -1270,33 +1345,7 @@ static int isis_zebra_process_srv6_locator_add(ZAPI_CALLBACK_ARGS) if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0) return -1; - sr_debug( - "New SRv6 locator allocated in zebra: name %s, " - "prefix %pFX, block_len %u, node_len %u, func_len %u, arg_len %u", - loc.name, &loc.prefix, loc.block_bits_length, - loc.node_bits_length, loc.function_bits_length, - loc.argument_bits_length); - - /* Lookup on the IS-IS areas */ - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { - /* If SRv6 is enabled on this area and the configured locator - * corresponds to the new locator, then request a chunk from the - * locator */ - if (area->srv6db.config.enabled && - strncmp(area->srv6db.config.srv6_locator_name, loc.name, - sizeof(area->srv6db.config.srv6_locator_name)) == 0) { - sr_debug( - "Sending a request to get a chunk from the SRv6 locator %s (%pFX) " - "for IS-IS area %s", - loc.name, &loc.prefix, area->area_tag); - - if (isis_zebra_srv6_manager_get_locator_chunk( - loc.name) < 0) - return -1; - } - } - - return 0; + return isis_zebra_process_srv6_locator_internal(&loc); } /** From 38a62df517bf86941ce60410ab332d893c6b8b2e Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 9 May 2024 13:00:30 +0200 Subject: [PATCH 300/472] isisd: Request SRv6 SIDs to SID Manager Currently, IS-IS allocates SIDs without interacting with Zebra. Recently, the SRv6 implementation has been improved. Now, the daemons need to interact with Zebra through ZAPI to obtain and release SIDs. This commit extends IS-IS to request SIDs from Zebra instead of allocating the SIDs on its own. Signed-off-by: Carmine Scarpitta --- isisd/isis_srv6.c | 27 +++++++++++---------------- isisd/isis_srv6.h | 6 +++--- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/isisd/isis_srv6.c b/isisd/isis_srv6.c index 7cf1d91b4638..0cd7f847f8ff 100644 --- a/isisd/isis_srv6.c +++ b/isisd/isis_srv6.c @@ -318,25 +318,23 @@ static struct in6_addr srv6_locator_request_sid(struct isis_area *area, * @param area IS-IS area * @param locator SRv6 locator * @param behavior SRv6 Endpoint Behavior bound to the SID + * @param sid_value SRv6 SID value * * @result the allocated SID on success, NULL otherwise */ struct isis_srv6_sid * isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator *locator, - enum srv6_endpoint_behavior_codepoint behavior, int sid_func) + enum srv6_endpoint_behavior_codepoint behavior, + struct in6_addr *sid_value) { struct isis_srv6_sid *sid = NULL; - if (!area || !locator) + if (!area || !locator || !sid_value) return NULL; sid = XCALLOC(MTYPE_ISIS_SRV6_SID, sizeof(struct isis_srv6_sid)); - sid->sid = srv6_locator_request_sid(area, locator, sid_func); - if (IPV6_ADDR_SAME(&sid->sid, &in6addr_any)) { - isis_srv6_sid_free(sid); - return NULL; - } + sid->sid = *sid_value; sid->behavior = behavior; sid->structure.loc_block_len = locator->block_bits_length; @@ -379,9 +377,10 @@ void isis_area_delete_backup_srv6_endx_sids(struct isis_area *area, int level) * @param adj IS-IS Adjacency * @param backup True to initialize backup Adjacency SID * @param nexthops List of backup nexthops (for backup End.X SIDs only) + * @param sid_value SID value associated to be associated with the adjacency */ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup, - struct list *nexthops) + struct list *nexthops, struct in6_addr *sid_value) { struct isis_circuit *circuit = adj->circuit; struct isis_area *area = circuit->area; @@ -428,11 +427,7 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup, sra->structure.arg_len = locator->argument_bits_length; sra->nexthop = nexthop; - sra->sid = srv6_locator_request_sid(area, locator, -1); - if (IPV6_ADDR_SAME(&sra->sid, &in6addr_any)) { - XFREE(MTYPE_ISIS_SRV6_INFO, sra); - return; - } + sra->sid = *sid_value; switch (circuit->circ_type) { /* SRv6 LAN End.X SID for Broadcast interface section #8.2 */ @@ -504,9 +499,9 @@ void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup, * * @param adj IS-IS Adjacency */ -void srv6_endx_sid_add(struct isis_adjacency *adj) +void srv6_endx_sid_add(struct isis_adjacency *adj, struct in6_addr *sid_value) { - srv6_endx_sid_add_single(adj, false, NULL); + srv6_endx_sid_add_single(adj, false, NULL, sid_value); } /** @@ -609,7 +604,7 @@ static int srv6_adj_ip_enabled(struct isis_adjacency *adj, int family, family != AF_INET6) return 0; - srv6_endx_sid_add(adj); + isis_zebra_request_srv6_sid_endx(adj); return 0; } diff --git a/isisd/isis_srv6.h b/isisd/isis_srv6.h index 6abc6d73451a..bde14965f6aa 100644 --- a/isisd/isis_srv6.h +++ b/isisd/isis_srv6.h @@ -153,7 +153,7 @@ void isis_srv6_interface_set(struct isis_area *area, const char *ifname); struct isis_srv6_sid * isis_srv6_sid_alloc(struct isis_area *area, struct srv6_locator *locator, enum srv6_endpoint_behavior_codepoint behavior, - int sid_func); + struct in6_addr *sid_value); extern void isis_srv6_sid_free(struct isis_srv6_sid *sid); extern void isis_srv6_area_init(struct isis_area *area); @@ -171,8 +171,8 @@ void isis_srv6_locator2tlv(const struct isis_srv6_locator *loc, struct isis_srv6_locator_tlv *loc_tlv); void srv6_endx_sid_add_single(struct isis_adjacency *adj, bool backup, - struct list *nexthops); -void srv6_endx_sid_add(struct isis_adjacency *adj); + struct list *nexthops, struct in6_addr *sid_value); +void srv6_endx_sid_add(struct isis_adjacency *adj, struct in6_addr *sid_value); void srv6_endx_sid_del(struct srv6_adjacency *sra); struct srv6_adjacency *isis_srv6_endx_sid_find(struct isis_adjacency *adj, enum srv6_adj_type type); From 7c203a05bf1b3c9e734a819ad42874673aff2e47 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 9 May 2024 13:03:45 +0200 Subject: [PATCH 301/472] isisd: Release SRv6 SIDs to SID Manager Currently, IS-IS allocates SIDs without interacting with Zebra. Recently, the SRv6 implementation has been improved. Now, the daemons need to interact with Zebra through ZAPI to obtain and release SIDs. This commit extends IS-IS to release SIDs to Zebra when they are no longer needed. Signed-off-by: Carmine Scarpitta --- isisd/isis_srv6.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/isisd/isis_srv6.c b/isisd/isis_srv6.c index 0cd7f847f8ff..c7bc7f069290 100644 --- a/isisd/isis_srv6.c +++ b/isisd/isis_srv6.c @@ -102,6 +102,7 @@ bool isis_srv6_locator_unset(struct isis_area *area) struct srv6_locator_chunk *chunk; struct isis_srv6_sid *sid; struct srv6_adjacency *sra; + struct srv6_sid_ctx ctx = {}; if (strncmp(area->srv6db.config.srv6_locator_name, "", sizeof(area->srv6db.config.srv6_locator_name)) == 0) { @@ -120,13 +121,31 @@ bool isis_srv6_locator_unset(struct isis_area *area) * Zebra */ isis_zebra_srv6_sid_uninstall(area, sid); + /* + * Inform the SID Manager that IS-IS will no longer use the SID, so + * that the SID Manager can remove the SID context ownership from IS-IS + * and release/free the SID context if it is not yes by other protocols. + */ + ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END; + isis_zebra_release_srv6_sid(&ctx); + listnode_delete(area->srv6db.srv6_sids, sid); isis_srv6_sid_free(sid); } /* Uninstall all local Adjacency-SIDs. */ - for (ALL_LIST_ELEMENTS(area->srv6db.srv6_endx_sids, node, nnode, sra)) + for (ALL_LIST_ELEMENTS(area->srv6db.srv6_endx_sids, node, nnode, sra)) { + /* + * Inform the SID Manager that IS-IS will no longer use the SID, so + * that the SID Manager can remove the SID context ownership from IS-IS + * and release/free the SID context if it is not yes by other protocols. + */ + ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END_X; + ctx.nh6 = sra->nexthop; + isis_zebra_release_srv6_sid(&ctx); + srv6_endx_sid_del(sra); + } /* Inform Zebra that we are releasing the SRv6 locator */ ret = isis_zebra_srv6_manager_release_locator_chunk( From 0af0f4616d32879b8114386e2c44fc6b3250cb14 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 9 May 2024 11:51:16 +0200 Subject: [PATCH 302/472] isisd: Receive SRv6 SIDs notifications from zebra Zebra sends a SRV6_SID_NOTIFY notification to inform clients about the result of a SID alloc/release operation. This commit adds a handler to process a SRV6_SID_NOTIFY notification received from zebra. If the notification indicates that a SID allocation operation was successful, then it stores the allocated SID in the SRv6 database, installs the SID into the RIB, and advertises the SID to the other IS-IS routers. If the notification indicates that an operation has failed, it logs the error. Signed-off-by: Carmine Scarpitta --- isisd/isis_zebra.c | 146 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index be8bb5c40668..99fd7398ee68 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -1535,6 +1535,151 @@ void isis_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx) } } +static int isis_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS) +{ + struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); + struct srv6_sid_ctx ctx; + struct in6_addr sid_addr; + enum zapi_srv6_sid_notify note; + uint32_t sid_func; + struct isis_area *area; + struct listnode *node, *nnode, *n; + char buf[256]; + struct srv6_locator *locator; + struct prefix_ipv6 tmp_prefix; + struct srv6_adjacency *sra; + enum srv6_endpoint_behavior_codepoint behavior; + struct isis_srv6_sid *sid; + struct isis_adjacency *adj; + + if (!isis) + return -1; + + /* Decode the received notification message */ + if (!zapi_srv6_sid_notify_decode(zclient->ibuf, &ctx, &sid_addr, + &sid_func, NULL, ¬e)) { + zlog_err("%s : error in msg decode", __func__); + return -1; + } + + sr_debug("%s: received SRv6 SID notify: ctx %s sid_value %pI6 sid_func %u note %s", + __func__, srv6_sid_ctx2str(buf, sizeof(buf), &ctx), &sid_addr, + sid_func, zapi_srv6_sid_notify2str(note)); + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + if (!area->srv6db.config.enabled || !area->srv6db.srv6_locator) + continue; + + locator = area->srv6db.srv6_locator; + + /* Verify that the received SID belongs to the configured locator */ + if (note == ZAPI_SRV6_SID_ALLOCATED) { + tmp_prefix.family = AF_INET6; + tmp_prefix.prefixlen = IPV6_MAX_BITLEN; + tmp_prefix.prefix = sid_addr; + + if (!prefix_match((struct prefix *)&locator->prefix, + (struct prefix *)&tmp_prefix)) { + sr_debug("%s : ignoring SRv6 SID notify: locator (area %s) does not match", + __func__, area->area_tag); + continue; + } + } + + /* Handle notification */ + switch (note) { + case ZAPI_SRV6_SID_ALLOCATED: + sr_debug("SRv6 SID %pI6 %s ALLOCATED", &sid_addr, + srv6_sid_ctx2str(buf, sizeof(buf), &ctx)); + + if (ctx.behavior == ZEBRA_SEG6_LOCAL_ACTION_END) { + /* Remove old End SIDs, if any */ + for (ALL_LIST_ELEMENTS(area->srv6db.srv6_sids, + node, nnode, sid)) { + isis_zebra_srv6_sid_uninstall(area, sid); + listnode_delete(area->srv6db.srv6_sids, + sid); + } + + /* Allocate new SRv6 End SID */ + behavior = + (CHECK_FLAG(locator->flags, + SRV6_LOCATOR_USID)) + ? SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID + : SRV6_ENDPOINT_BEHAVIOR_END; + sid = isis_srv6_sid_alloc(area, + area->srv6db + .srv6_locator, + behavior, &sid_addr); + if (!sid) { + zlog_warn("%s: isis_srv6_sid_alloc failed", + __func__); + return -1; + } + + /* + * Install the new SRv6 End SID in the forwarding plane through + * Zebra + */ + isis_zebra_srv6_sid_install(area, sid); + + /* Store the SID */ + listnode_add(area->srv6db.srv6_sids, sid); + + } else if (ctx.behavior == + ZEBRA_SEG6_LOCAL_ACTION_END_X) { + for (ALL_LIST_ELEMENTS_RO(area->adjacency_list, + n, adj)) { + /* Check if the End.X SID is for this adjacecny */ + if (adj->ll_ipv6_count == 0 || + memcmp(&adj->ll_ipv6_addrs[0], + &ctx.nh6, + sizeof(struct in6_addr)) != 0) + continue; + + /* Remove old End.X SIDs, if any */ + for (ALL_LIST_ELEMENTS(adj->srv6_endx_sids, + node, nnode, sra)) + srv6_endx_sid_del(sra); + + /* Allocate new End.X SID for the adjacency */ + srv6_endx_sid_add_single(adj, false, + NULL, + &sid_addr); + } + } else { + zlog_warn("%s: unsupported behavior %u", + __func__, ctx.behavior); + return -1; + } + break; + case ZAPI_SRV6_SID_RELEASED: + sr_debug("SRv6 SID %pI6 %s: RELEASED", &sid_addr, + srv6_sid_ctx2str(buf, sizeof(buf), &ctx)); + break; + case ZAPI_SRV6_SID_FAIL_ALLOC: + sr_debug("SRv6 SID %pI6 %s: Failed to allocate", + &sid_addr, + srv6_sid_ctx2str(buf, sizeof(buf), &ctx)); + + /* Error will be logged by zebra module */ + break; + case ZAPI_SRV6_SID_FAIL_RELEASE: + zlog_warn("%s: SRv6 SID %pI6 %s failure to release", + __func__, &sid_addr, + srv6_sid_ctx2str(buf, sizeof(buf), &ctx)); + + /* Error will be logged by zebra module */ + break; + } + + /* Regenerate LSPs to advertise the new locator and the SID */ + lsp_regenerate_schedule(area, area->is_type, 0); + } + + return 0; +} + static zclient_handler *const isis_handlers[] = { [ZEBRA_ROUTER_ID_UPDATE] = isis_router_id_update_zebra, [ZEBRA_INTERFACE_ADDRESS_ADD] = isis_zebra_if_address_add, @@ -1551,6 +1696,7 @@ static zclient_handler *const isis_handlers[] = { isis_zebra_process_srv6_locator_chunk, [ZEBRA_SRV6_LOCATOR_ADD] = isis_zebra_process_srv6_locator_add, [ZEBRA_SRV6_LOCATOR_DELETE] = isis_zebra_process_srv6_locator_delete, + [ZEBRA_SRV6_SID_NOTIFY] = isis_zebra_srv6_sid_notify, }; void isis_zebra_init(struct event_loop *master, int instance) From a2b83a9dec6a9c1021ccbc368c55b2cd6b362d42 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sat, 23 Mar 2024 21:43:17 +0100 Subject: [PATCH 303/472] isisd: Cleanup related to SRv6 Remove unused SRv6 code. Signed-off-by: Carmine Scarpitta --- isisd/isis_srv6.c | 111 --------------------------------------------- isisd/isis_zebra.c | 101 ----------------------------------------- 2 files changed, 212 deletions(-) diff --git a/isisd/isis_srv6.c b/isisd/isis_srv6.c index c7bc7f069290..b5974b1a6276 100644 --- a/isisd/isis_srv6.c +++ b/isisd/isis_srv6.c @@ -220,117 +220,6 @@ void isis_srv6_interface_set(struct isis_area *area, const char *ifname) } } -/** - * Encode SID function in the SRv6 SID. - * - * @param sid - * @param func - * @param offset - * @param len - */ -static void encode_sid_func(struct in6_addr *sid, uint32_t func, uint8_t offset, - uint8_t len) -{ - for (uint8_t idx = 0; idx < len; idx++) { - uint8_t tidx = offset + idx; - sid->s6_addr[tidx / 8] &= ~(0x1 << (7 - tidx % 8)); - if (func >> (len - 1 - idx) & 0x1) - sid->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8); - } -} - -static bool sid_exist(struct isis_area *area, const struct in6_addr *sid) -{ - struct listnode *node; - struct isis_srv6_sid *s; - struct srv6_adjacency *sra; - - for (ALL_LIST_ELEMENTS_RO(area->srv6db.srv6_sids, node, s)) - if (sid_same(&s->sid, sid)) - return true; - for (ALL_LIST_ELEMENTS_RO(area->srv6db.srv6_endx_sids, node, sra)) - if (sid_same(&sra->sid, sid)) - return true; - return false; -} - -/** - * Request a SID from the SRv6 locator. - * - * @param area IS-IS area - * @param locator SRv6 locator - * @param sid_func The FUNCTION part of the SID to be allocated (a negative - * number will allocate the first available SID) - * - * @return First available SID on success or in6addr_any if the SRv6 - * locator is full - */ -static struct in6_addr srv6_locator_request_sid(struct isis_area *area, - struct srv6_locator *locator, - int sid_func) -{ - struct in6_addr sid; - uint8_t offset = 0; - uint8_t func_len = 0; - uint32_t func_max; - bool allocated = false; - - if (!area || !locator) - return in6addr_any; - - sr_debug("ISIS-SRv6 (%s): requested new SID from locator %s", - area->area_tag, locator->name); - - /* Let's build the SID, step by step. A SID has the following structure - (defined in RFC 8986): LOCATOR:FUNCTION:ARGUMENT.*/ - - /* First, we encode the LOCATOR in the L most significant bits. */ - sid = locator->prefix.prefix; - - /* The next part of the SID is the FUNCTION. Let's compute the length - * and the offset of the FUNCTION in the SID */ - func_len = locator->function_bits_length; - offset = locator->block_bits_length + locator->node_bits_length; - - /* Then, encode the FUNCTION */ - if (sid_func >= 0) { - /* SID FUNCTION has been specified. We need to allocate a SID - * with the requested FUNCTION. */ - encode_sid_func(&sid, sid_func, offset, func_len); - if (sid_exist(area, &sid)) { - zlog_warn( - "ISIS-SRv6 (%s): the requested SID %pI6 is already used", - area->area_tag, &sid); - return sid; - } - allocated = true; - } else { - /* SID FUNCTION not specified. We need to choose a FUNCTION that - * is not already used. So let's iterate through all possible - * functions and get the first available one. */ - func_max = (1 << func_len) - 1; - for (uint32_t func = 1; func < func_max; func++) { - encode_sid_func(&sid, func, offset, func_len); - if (sid_exist(area, &sid)) - continue; - allocated = true; - break; - } - } - - if (!allocated) { - /* We ran out of available SIDs */ - zlog_warn("ISIS-SRv6 (%s): no SIDs available in locator %s", - area->area_tag, locator->name); - return in6addr_any; - } - - sr_debug("ISIS-SRv6 (%s): allocating new SID %pI6", area->area_tag, - &sid); - - return sid; -} - /** * Allocate an SRv6 SID from an SRv6 locator. * diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 99fd7398ee68..021ed1ff49e3 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -1182,105 +1182,6 @@ void isis_zebra_srv6_adj_sid_uninstall(struct srv6_adjacency *sra) ifp->ifindex, action, NULL); } -/** - * Callback to process an SRv6 locator chunk received from SRv6 Manager (zebra). - * - * @result 0 on success, -1 otherwise - */ -static int isis_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS) -{ - struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); - struct stream *s = NULL; - struct listnode *node; - struct isis_area *area; - struct srv6_locator_chunk *c; - struct srv6_locator_chunk *chunk = srv6_locator_chunk_alloc(); - struct isis_srv6_sid *sid; - struct isis_adjacency *adj; - enum srv6_endpoint_behavior_codepoint behavior; - bool allocated = false; - - if (!isis) { - srv6_locator_chunk_free(&chunk); - return -1; - } - - /* Decode the received zebra message */ - s = zclient->ibuf; - if (zapi_srv6_locator_chunk_decode(s, chunk) < 0) { - srv6_locator_chunk_free(&chunk); - return -1; - } - - sr_debug( - "Received SRv6 locator chunk from zebra: name %s, " - "prefix %pFX, block_len %u, node_len %u, func_len %u, arg_len %u", - chunk->locator_name, &chunk->prefix, chunk->block_bits_length, - chunk->node_bits_length, chunk->function_bits_length, - chunk->argument_bits_length); - - /* Walk through all areas of the ISIS instance */ - for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { - if (strncmp(area->srv6db.config.srv6_locator_name, - chunk->locator_name, - sizeof(area->srv6db.config.srv6_locator_name)) != 0) - continue; - - for (ALL_LIST_ELEMENTS_RO(area->srv6db.srv6_locator_chunks, - node, c)) { - if (!prefix_cmp(&c->prefix, &chunk->prefix)) { - srv6_locator_chunk_free(&chunk); - return 0; - } - } - - sr_debug( - "SRv6 locator chunk (locator %s, prefix %pFX) assigned to IS-IS area %s", - chunk->locator_name, &chunk->prefix, area->area_tag); - - /* Add the SRv6 Locator chunk to the per-area chunks list */ - listnode_add(area->srv6db.srv6_locator_chunks, chunk); - - /* Decide which behavior to use,depending on the locator type - * (i.e. uSID vs classic locator) */ - behavior = (CHECK_FLAG(chunk->flags, SRV6_LOCATOR_USID)) - ? SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID - : SRV6_ENDPOINT_BEHAVIOR_END; - - /* Allocate new SRv6 End SID */ - sid = isis_srv6_sid_alloc(area, chunk, behavior, 0); - if (!sid) - return -1; - - /* Install the new SRv6 End SID in the forwarding plane through - * Zebra */ - isis_zebra_srv6_sid_install(area, sid); - - /* Store the SID */ - listnode_add(area->srv6db.srv6_sids, sid); - - /* Create SRv6 End.X SIDs from existing IS-IS Adjacencies */ - for (ALL_LIST_ELEMENTS_RO(area->adjacency_list, node, adj)) { - if (adj->ll_ipv6_count > 0) - srv6_endx_sid_add(adj); - } - - /* Regenerate LSPs to advertise the new locator and the SID */ - lsp_regenerate_schedule(area, area->is_type, 0); - - allocated = true; - break; - } - - if (!allocated) { - sr_debug("No IS-IS area configured for the locator %s", - chunk->locator_name); - srv6_locator_chunk_free(&chunk); - } - - return 0; -} - /** * Internal function to process an SRv6 locator * @@ -1692,8 +1593,6 @@ static zclient_handler *const isis_handlers[] = { [ZEBRA_CLIENT_CLOSE_NOTIFY] = isis_zebra_client_close_notify, - [ZEBRA_SRV6_MANAGER_GET_LOCATOR_CHUNK] = - isis_zebra_process_srv6_locator_chunk, [ZEBRA_SRV6_LOCATOR_ADD] = isis_zebra_process_srv6_locator_add, [ZEBRA_SRV6_LOCATOR_DELETE] = isis_zebra_process_srv6_locator_delete, [ZEBRA_SRV6_SID_NOTIFY] = isis_zebra_srv6_sid_notify, From 9e1803a772510114148b0f8ca9bfb3dcbed76721 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Thu, 6 Jun 2024 14:50:06 +0200 Subject: [PATCH 304/472] tests: Update IS-IS SRv6 topotests The locator is no longer split in multiple chunks. Signed-off-by: Carmine Scarpitta --- .../isis_srv6_topo1/rt1/step1/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt1/step3/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt1/step5/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt1/step7/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt1/step9/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step1/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step2/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step3/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step4/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step5/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step6/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step7/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step8/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt2/step9/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step1/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step2/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step3/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step4/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step5/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step6/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step7/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step8/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt3/step9/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step1/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step2/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step3/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step4/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step5/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step6/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step7/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step8/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt4/step9/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step1/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step2/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step3/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step4/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step5/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step6/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step7/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step8/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt5/step9/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step1/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step2/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step3/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step4/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step5/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step6/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step7/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step8/show_srv6_locator_table.ref | 4 ---- .../isis_srv6_topo1/rt6/step9/show_srv6_locator_table.ref | 4 ---- 50 files changed, 200 deletions(-) diff --git a/tests/topotests/isis_srv6_topo1/rt1/step1/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt1/step1/show_srv6_locator_table.ref index bb10aba9424d..c4a5d7507b45 100644 --- a/tests/topotests/isis_srv6_topo1/rt1/step1/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt1/step1/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:1::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt1/step3/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt1/step3/show_srv6_locator_table.ref index bb10aba9424d..c4a5d7507b45 100644 --- a/tests/topotests/isis_srv6_topo1/rt1/step3/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt1/step3/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:1::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt1/step5/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt1/step5/show_srv6_locator_table.ref index bb10aba9424d..c4a5d7507b45 100644 --- a/tests/topotests/isis_srv6_topo1/rt1/step5/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt1/step5/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:1::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt1/step7/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt1/step7/show_srv6_locator_table.ref index bb10aba9424d..c4a5d7507b45 100644 --- a/tests/topotests/isis_srv6_topo1/rt1/step7/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt1/step7/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:1::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt1/step9/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt1/step9/show_srv6_locator_table.ref index bb10aba9424d..c4a5d7507b45 100644 --- a/tests/topotests/isis_srv6_topo1/rt1/step9/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt1/step9/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:1::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step1/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step1/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step1/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step1/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step2/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step2/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step2/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step2/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step3/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step3/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step3/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step3/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step4/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step4/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step4/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step4/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step5/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step5/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step5/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step5/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step6/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step6/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step6/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step6/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step7/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step7/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step7/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step7/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step8/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step8/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step8/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step8/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt2/step9/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt2/step9/show_srv6_locator_table.ref index f3399319f3e5..f8a5d93f3c78 100644 --- a/tests/topotests/isis_srv6_topo1/rt2/step9/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt2/step9/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:2::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step1/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step1/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step1/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step1/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step2/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step2/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step2/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step2/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step3/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step3/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step3/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step3/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step4/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step4/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step4/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step4/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step5/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step5/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step5/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step5/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step6/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step6/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step6/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step6/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step7/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step7/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step7/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step7/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step8/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step8/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step8/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step8/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt3/step9/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt3/step9/show_srv6_locator_table.ref index ffa626123da8..c62870587bf3 100644 --- a/tests/topotests/isis_srv6_topo1/rt3/step9/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt3/step9/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:3::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step1/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step1/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step1/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step1/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step2/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step2/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step2/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step2/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step3/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step3/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step3/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step3/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step4/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step4/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step4/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step4/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step5/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step5/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step5/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step5/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step6/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step6/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step6/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step6/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step7/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step7/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step7/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step7/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step8/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step8/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step8/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step8/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt4/step9/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt4/step9/show_srv6_locator_table.ref index 189943f737a5..cb052dbbb5fb 100644 --- a/tests/topotests/isis_srv6_topo1/rt4/step9/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt4/step9/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:4::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step1/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step1/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step1/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step1/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step2/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step2/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step2/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step2/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step3/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step3/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step3/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step3/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step4/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step4/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step4/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step4/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step5/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step5/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step5/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step5/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step6/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step6/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step6/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step6/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step7/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step7/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step7/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step7/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step8/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step8/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step8/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step8/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt5/step9/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt5/step9/show_srv6_locator_table.ref index 54780fce8adc..ec55f24d7b95 100644 --- a/tests/topotests/isis_srv6_topo1/rt5/step9/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt5/step9/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:5::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step1/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step1/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step1/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step1/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step2/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step2/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step2/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step2/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step3/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step3/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step3/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step3/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step4/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step4/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step4/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step4/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step5/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step5/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step5/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step5/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step6/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step6/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step6/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step6/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step7/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step7/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step7/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step7/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step8/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step8/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step8/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step8/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] diff --git a/tests/topotests/isis_srv6_topo1/rt6/step9/show_srv6_locator_table.ref b/tests/topotests/isis_srv6_topo1/rt6/step9/show_srv6_locator_table.ref index 35aa61d8e6d5..abcdeddea4ef 100644 --- a/tests/topotests/isis_srv6_topo1/rt6/step9/show_srv6_locator_table.ref +++ b/tests/topotests/isis_srv6_topo1/rt6/step9/show_srv6_locator_table.ref @@ -9,10 +9,6 @@ "argumentBitsLength":0, "statusUp":true, "chunks":[ - { - "prefix":"fc00:0:6::/48", - "proto":"isis" - } ] } ] From fe5b03a10b583d0a95104a43389a9b60ca9bc397 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Sat, 8 Jun 2024 07:15:47 +0200 Subject: [PATCH 305/472] isisd: add locator name in sid notify messages In the near future, some daemons may only register SIDs. This may be the case for the pathd daemon when creating SRv6 binding SIDs. When a locator is getting deleted at ZEBRA level, the daemon may have an easy way to find out the SIds to unregister to. This commit proposes to add the locator name to the SID_SRV6_NOTIFY message whenever possible. Only case when an allocation failure happens, the locator will not be present. In all other places, the notify API at procol levels has the locator name extra-parameter. Signed-off-by: Philippe Guibert Signed-off-by: Carmine Scarpitta --- isisd/isis_zebra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 021ed1ff49e3..ce4eb74ec66f 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -1458,7 +1458,7 @@ static int isis_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS) /* Decode the received notification message */ if (!zapi_srv6_sid_notify_decode(zclient->ibuf, &ctx, &sid_addr, - &sid_func, NULL, ¬e)) { + &sid_func, NULL, ¬e, NULL)) { zlog_err("%s : error in msg decode", __func__); return -1; } From d10bd26e802eac70395da713423683a5cb624c57 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 14 Jun 2024 11:32:06 -0400 Subject: [PATCH 306/472] bgpd: Convert over to using vrf name instead of id Use the name for when putting out debugs in bgp_zebra.c. Additionally add an evpn flag for announce_route_actual. Signed-off-by: Donald Sharp --- bgpd/bgp_zebra.c | 73 ++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 8fab0d1c055d..4d18078a43cb 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -195,7 +195,7 @@ static int bgp_ifp_destroy(struct interface *ifp) bgp = ifp->vrf->info; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx Intf del VRF %u IF %s", ifp->vrf->vrf_id, + zlog_debug("Rx Intf del VRF %s IF %s", ifp->vrf->name, ifp->name); if (bgp) { @@ -220,8 +220,7 @@ static int bgp_ifp_up(struct interface *ifp) bgp_mac_add_mac_entry(ifp); if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx Intf up VRF %u IF %s", ifp->vrf->vrf_id, - ifp->name); + zlog_debug("Rx Intf up VRF %s IF %s", ifp->vrf->name, ifp->name); if (!bgp) return 0; @@ -259,7 +258,7 @@ static int bgp_ifp_down(struct interface *ifp) bgp_mac_del_mac_entry(ifp); if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx Intf down VRF %u IF %s", ifp->vrf->vrf_id, + zlog_debug("Rx Intf down VRF %s IF %s", ifp->vrf->name, ifp->name); if (!bgp) @@ -320,8 +319,8 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS) return 0; if (bgp_debug_zebra(ifc->address)) - zlog_debug("Rx Intf address add VRF %u IF %s addr %pFX", vrf_id, - ifc->ifp->name, ifc->address); + zlog_debug("Rx Intf address add VRF %s IF %s addr %pFX", + ifc->ifp->vrf->name, ifc->ifp->name, ifc->address); if (!bgp) return 0; @@ -417,8 +416,8 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS) return 0; if (bgp_debug_zebra(ifc->address)) - zlog_debug("Rx Intf address del VRF %u IF %s addr %pFX", vrf_id, - ifc->ifp->name, ifc->address); + zlog_debug("Rx Intf address del VRF %s IF %s addr %pFX", + ifc->ifp->vrf->name, ifc->ifp->name, ifc->address); if (bgp && if_is_operative(ifc->ifp)) { bgp_connected_delete(bgp, ifc); @@ -480,8 +479,8 @@ static int bgp_interface_nbr_address_add(ZAPI_CALLBACK_ARGS) return 0; if (bgp_debug_zebra(ifc->address)) - zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %pFX", - vrf_id, ifc->ifp->name, ifc->address); + zlog_debug("Rx Intf neighbor add VRF %s IF %s addr %pFX", + ifc->ifp->vrf->name, ifc->ifp->name, ifc->address); if (if_is_operative(ifc->ifp)) { bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -503,8 +502,8 @@ static int bgp_interface_nbr_address_delete(ZAPI_CALLBACK_ARGS) return 0; if (bgp_debug_zebra(ifc->address)) - zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %pFX", - vrf_id, ifc->ifp->name, ifc->address); + zlog_debug("Rx Intf neighbor del VRF %s IF %s addr %pFX", + ifc->ifp->vrf->name, ifc->ifp->name, ifc->address); if (if_is_operative(ifc->ifp)) { bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -586,13 +585,14 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS) if (add) { inet_ntop(api.prefix.family, &nexthop, buf, sizeof(buf)); - zlog_debug( - "Rx route ADD VRF %u %s[%d] %pFX nexthop %s (type %d if %u) metric %u distance %u tag %" ROUTE_TAG_PRI, - vrf_id, zebra_route_string(api.type), - api.instance, &api.prefix, buf, nhtype, ifindex, - api.metric, api.distance, api.tag); + zlog_debug("Rx route ADD %s %s[%d] %pFX nexthop %s (type %d if %u) metric %u distance %u tag %" ROUTE_TAG_PRI, + bgp->name_pretty, + zebra_route_string(api.type), api.instance, + &api.prefix, buf, nhtype, ifindex, + api.metric, api.distance, api.tag); } else { - zlog_debug("Rx route DEL VRF %u %s[%d] %pFX", vrf_id, + zlog_debug("Rx route DEL %s %s[%d] %pFX", + bgp->name_pretty, zebra_route_string(api.type), api.instance, &api.prefix); } @@ -1671,11 +1671,11 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, } if (bgp_debug_zebra(p)) { - zlog_debug( - "Tx route %s VRF %u %pFX metric %u tag %" ROUTE_TAG_PRI - " count %d nhg %d", - is_add ? "add" : "delete", bgp->vrf_id, &api.prefix, - api.metric, api.tag, api.nexthop_num, nhg_id); + zlog_debug("Tx route %s %s %pFX metric %u tag %" ROUTE_TAG_PRI + " count %d nhg %d", + is_add ? "add" : "delete", bgp->name_pretty, + &api.prefix, api.metric, api.tag, api.nexthop_num, + nhg_id); bgp_debug_zebra_nh(&api); zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)", @@ -1764,7 +1764,7 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest, } if (bgp_debug_zebra(p)) - zlog_debug("Tx route delete VRF %u %pFX", bgp->vrf_id, + zlog_debug("Tx route delete %s %pFX", bgp->name_pretty, &api.prefix); return zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); @@ -1805,8 +1805,9 @@ static void bgp_handle_route_announcements_to_zebra(struct event *e) is_evpn = true; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("BGP %s route %pBD(%s) with dest %p and flags 0x%x to zebra", - install ? "announcing" : "withdrawing", dest, + zlog_debug("BGP %s%s route %pBD(%s) with dest %p and flags 0x%x to zebra", + install ? "announcing" : "withdrawing", + is_evpn ? " evpn" : " ", dest, table->bgp->name_pretty, dest, dest->flags); if (install) { @@ -2085,8 +2086,8 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, return CMD_SUCCESS; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Tx redistribute add VRF %u afi %d %s %d", - bgp->vrf_id, afi, zebra_route_string(type), + zlog_debug("Tx redistribute add %s afi %d %s %d", + bgp->name_pretty, afi, zebra_route_string(type), instance); /* Send distribute add message to zebra. */ @@ -2106,8 +2107,8 @@ int bgp_redistribute_resend(struct bgp *bgp, afi_t afi, int type, return -1; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Tx redistribute del/add VRF %u afi %d %s %d", - bgp->vrf_id, afi, zebra_route_string(type), + zlog_debug("Tx redistribute del/add %s afi %d %s %d", + bgp->name_pretty, afi, zebra_route_string(type), instance); /* Send distribute add message to zebra. */ @@ -2201,9 +2202,9 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type, if (bgp_install_info_to_zebra(bgp)) { /* Send distribute delete message to zebra. */ if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Tx redistribute del VRF %u afi %d %s %d", - bgp->vrf_id, afi, zebra_route_string(type), - instance); + zlog_debug("Tx redistribute del %s afi %d %s %d", + bgp->name_pretty, afi, + zebra_route_string(type), instance); zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, instance, bgp->vrf_id); } @@ -2306,7 +2307,7 @@ void bgp_zebra_instance_register(struct bgp *bgp) return; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Registering VRF %u", bgp->vrf_id); + zlog_debug("Registering %s", bgp->name_pretty); /* Register for router-id, interfaces, redistributed routes. */ zclient_send_reg_requests(zclient, bgp->vrf_id); @@ -2328,7 +2329,7 @@ void bgp_zebra_instance_deregister(struct bgp *bgp) return; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Deregistering VRF %u", bgp->vrf_id); + zlog_debug("Deregistering %s", bgp->name_pretty); /* For EVPN instance, unregister learning about VNIs, if appropriate. */ if (bgp->advertise_all_vni) @@ -3341,7 +3342,7 @@ static int bgp_ifp_create(struct interface *ifp) struct bgp *bgp; if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("Rx Intf add VRF %u IF %s", ifp->vrf->vrf_id, + zlog_debug("Rx Intf add VRF %s IF %s", ifp->vrf->name, ifp->name); bgp = ifp->vrf->info; From b47a92e2e51595f820609e4d909f2b0abb9d6309 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Mon, 17 Jun 2024 13:58:03 -0700 Subject: [PATCH 307/472] bgpd: backpressure - fix evpn route sync to zebra In scaled EVPN + ipv4/ipv6 uni route sync to zebra, some of the ipv4/ipv6 routes skipped reinstallation due to incorrect local variable's stale value. Once the local variable value reset in each loop iteration all skipped routes synced to zebra properly. Ticket: #3948828 Signed-off-by: Rajasekar Raja Signed-off-by: Chirag Shah --- bgpd/bgp_zebra.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 8fab0d1c055d..c79d7dff16c1 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1794,6 +1794,8 @@ static void bgp_handle_route_announcements_to_zebra(struct event *e) bool install; while (count < ZEBRA_ANNOUNCEMENTS_LIMIT) { + is_evpn = false; + dest = zebra_announce_pop(&bm->zebra_announce_head); if (!dest) From 0db469958c9b7c7b763797da457e84d2f033a2f7 Mon Sep 17 00:00:00 2001 From: zhou-run <166502045+zhou-run@users.noreply.github.com> Date: Mon, 17 Jun 2024 18:00:04 +0800 Subject: [PATCH 308/472] isisd: Even after configuring "no hostname dynamic", the topology still displays the hostname. The command "show isis topology" calls print_sys_hostname() to display the system ID or hostname, but it does not check the area->dynhostname flag. Signed-off-by: zhou-run --- isisd/isis_misc.c | 8 +++++--- isisd/isisd.c | 27 +++++++++++++++++++++++++-- isisd/isisd.h | 2 ++ tests/isisd/test_isis_spf.c | 13 +++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c index e4ef6c8dfa3c..833d5143412e 100644 --- a/isisd/isis_misc.c +++ b/isisd/isis_misc.c @@ -370,18 +370,20 @@ const char *print_sys_hostname(const uint8_t *sysid) struct isis_dynhn *dyn; struct isis *isis = NULL; struct listnode *node; + struct isis_area *area = NULL; if (!sysid) return "nullsysid"; /* For our system ID return our host name */ - isis = isis_lookup_by_sysid(sysid); - if (isis && !CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) + area = isis_area_lookup_by_sysid(sysid); + if (area && area->dynhostname && !CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) return cmd_hostname_get(); for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { + area = isis_area_lookup_by_sysid(isis->sysid); dyn = dynhn_find_by_id(isis, sysid); - if (dyn) + if (area && area->dynhostname && dyn) return dyn->hostname; } diff --git a/isisd/isisd.c b/isisd/isisd.c index 982df0839b9b..1f119dbcc88f 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -272,7 +272,7 @@ void isis_area_del_circuit(struct isis_area *area, struct isis_circuit *circuit) isis_csm_state_change(ISIS_DISABLE, circuit, area); } -static void delete_area_addr(void *arg) +void isis_area_address_delete(void *arg) { struct iso_address *addr = (struct iso_address *)arg; @@ -330,7 +330,7 @@ struct isis_area *isis_area_create(const char *area_tag, const char *vrf_name) area->circuit_list = list_new(); area->adjacency_list = list_new(); area->area_addrs = list_new(); - area->area_addrs->del = delete_area_addr; + area->area_addrs->del = isis_area_address_delete; if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) event_add_timer(master, lsp_tick, area, 1, &area->t_tick); @@ -471,6 +471,29 @@ struct isis_area *isis_area_lookup(const char *area_tag, vrf_id_t vrf_id) return NULL; } +struct isis_area *isis_area_lookup_by_sysid(const uint8_t *sysid) +{ + struct isis_area *area; + struct listnode *node; + struct isis *isis; + struct iso_address *addr = NULL; + + isis = isis_lookup_by_sysid(sysid); + if (isis == NULL) + return NULL; + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + if (listcount(area->area_addrs) > 0) { + addr = listgetdata(listhead(area->area_addrs)); + if (!memcmp(addr->area_addr + addr->addr_len, sysid, + ISIS_SYS_ID_LEN)) + return area; + } + } + + return NULL; +} + int isis_area_get(struct vty *vty, const char *area_tag) { struct isis_area *area; diff --git a/isisd/isisd.h b/isisd/isisd.h index f5042e4ad5c2..2ed7dd0f1095 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -285,10 +285,12 @@ void isis_area_add_circuit(struct isis_area *area, void isis_area_del_circuit(struct isis_area *area, struct isis_circuit *circuit); +void isis_area_address_delete(void *arg); struct isis_area *isis_area_create(const char *, const char *); struct isis_area *isis_area_lookup(const char *, vrf_id_t vrf_id); struct isis_area *isis_area_lookup_by_vrf(const char *area_tag, const char *vrf_name); +struct isis_area *isis_area_lookup_by_sysid(const uint8_t *sysid); int isis_area_get(struct vty *vty, const char *area_tag); void isis_area_destroy(struct isis_area *area); void isis_filter_update(struct access_list *access); diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index 4ea28cda2ff8..317ebd729e49 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -245,12 +245,25 @@ static int test_run(struct vty *vty, const struct isis_topology *topology, struct isis_area *area; struct lfa_protected_resource protected_resource = {}; uint8_t fail_id[ISIS_SYS_ID_LEN] = {}; + static char sysidstr[ISO_SYSID_STRLEN]; + char net_title[255]; + uint8_t buff[255]; + struct iso_address *addr = NULL; /* Init topology. */ area = isis_area_create("1", NULL); memcpy(area->isis->sysid, root->sysid, sizeof(area->isis->sysid)); area->is_type = IS_LEVEL_1_AND_2; area->srdb.enabled = true; + area->area_addrs = list_new(); + area->area_addrs->del = isis_area_address_delete; + addr = XMALLOC(MTYPE_ISIS_AREA_ADDR, sizeof(struct iso_address)); + snprintfrr(sysidstr, sizeof(sysidstr), "%pSY", area->isis->sysid); + snprintf(net_title, sizeof(net_title), "49.%s.00", sysidstr); + addr->addr_len = dotformat2buff(buff, net_title); + memcpy(addr->area_addr, buff, addr->addr_len); + addr->addr_len -= (ISIS_SYS_ID_LEN + ISIS_NSEL_LEN); + listnode_add(area->area_addrs, addr); if (test_topology_load(topology, area, area->lspdb) != 0) { vty_out(vty, "%% Failed to load topology\n"); return CMD_WARNING; From c25c7e929d550c2faca3af74a29593b8c0b75db3 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 19 Jun 2024 14:09:00 +0300 Subject: [PATCH 309/472] bgpd: Set last reset reason to admin shutdown if it was manually Before this patch, we always printed the last reason "Waiting for OPEN", but if it's a manual shutdown, then we technically are not waiting for OPEN. Signed-off-by: Donatas Abraitis --- bgpd/bgpd.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 869d2b455214..0ad97166331a 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -4829,6 +4829,8 @@ void bgp_shutdown_enable(struct bgp *bgp, const char *msg) /* iterate through peers of BGP instance */ for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + peer->last_reset = PEER_DOWN_USER_SHUTDOWN; + /* continue, if peer is already in administrative shutdown. */ if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) continue; @@ -4883,8 +4885,10 @@ void bgp_shutdown_disable(struct bgp *bgp) /* clear the BGP instances shutdown flag */ UNSET_FLAG(bgp->flags, BGP_FLAG_SHUTDOWN); - for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { bgp_timer_set(peer->connection); + peer->last_reset = PEER_DOWN_WAITING_OPEN; + } } /* Change specified peer flag. */ @@ -4956,6 +4960,10 @@ static int peer_flag_modify(struct peer *peer, uint64_t flag, int set) bgp_zebra_terminate_radv(peer->bgp, peer); } + if (flag == PEER_FLAG_SHUTDOWN) + peer->last_reset = set ? PEER_DOWN_USER_SHUTDOWN + : PEER_DOWN_WAITING_OPEN; + /* Execute flag action on peer. */ if (action.type == peer_change_reset) peer_flag_modify_action(peer, flag); @@ -4991,6 +4999,10 @@ static int peer_flag_modify(struct peer *peer, uint64_t flag, int set) set ? bgp_zebra_initiate_radv(member->bgp, member) : bgp_zebra_terminate_radv(member->bgp, member); + if (flag == PEER_FLAG_SHUTDOWN) + member->last_reset = set ? PEER_DOWN_USER_SHUTDOWN + : PEER_DOWN_WAITING_OPEN; + /* Execute flag action on peer-group member. */ if (action.type == peer_change_reset) peer_flag_modify_action(member, flag); From b5bd626a82b2541bee8e3120139e19ba05e444c8 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 19 Jun 2024 14:32:16 +0300 Subject: [PATCH 310/472] bgpd: Remove redundant whitespace before printing the reason of the failed peer Before: ``` Neighbor EstdCnt DropCnt ResetTime Reason 127.0.0.1 0 0 never Waiting for peer OPEN (n/a) ``` After: ``` Neighbor EstdCnt DropCnt ResetTime Reason 127.0.0.1 0 0 never Waiting for peer OPEN (n/a) ``` Signed-off-by: Donatas Abraitis --- bgpd/bgp_vty.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index fbe1db9d2a00..230fedf4ece8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11661,10 +11661,9 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer, BGP_NOTIFY_CEASE_HARD_RESET) : ""); } else { - vty_out(vty, " %s (%s)\n", + vty_out(vty, " %s (%s)\n", peer_down_str[(int)peer->last_reset], - peer->soft_version ? peer->soft_version - : "n/a"); + peer->soft_version ? peer->soft_version : "n/a"); } } } From 69b36cdf071a83f57a10206fd69db6cc7da5d10f Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 31 May 2024 12:03:22 -0400 Subject: [PATCH 311/472] lib: Discourage usage of deprecated data structures Put some verbiage in place to warn people that we are actively discouraging new development that uses an older data structure. Signed-off-by: Donald Sharp --- lib/hash.h | 12 ++++++++++++ lib/linklist.h | 12 ++++++++++++ lib/openbsd-queue.h | 16 ++++++++++++++++ lib/openbsd-tree.h | 15 +++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/lib/hash.h b/lib/hash.h index 2d00a334bea7..efa7011bc205 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -13,6 +13,18 @@ extern "C" { #endif +/* + * NOTICE: + * + * If you are reading this file in an effort to add a new hash structure + * this is the wrong place to be using it. Please see the typesafe + * data structures, or ask one of the other developers. + * + * If you are reading this file as a way to update an existing usage + * of this data structure, please consider just converting the data + * structure to one of the typesafe data structures instead. + */ + /* Default hash table size. */ #define HASH_INITIAL_SIZE 256 /* Expansion threshold */ diff --git a/lib/linklist.h b/lib/linklist.h index fd953d0769b8..f922891df95f 100644 --- a/lib/linklist.h +++ b/lib/linklist.h @@ -10,6 +10,18 @@ extern "C" { #endif +/* + * NOTICE: + * + * If you are reading this file in an effort to add a new list structure + * this is the wrong place to be using it. Please see the typesafe + * data structures, or ask one of the other developers. + * + * If you are reading this file as a way to update an existing usage + * of this data structure, please consider just converting the data + * structure to one of the typesafe data structures instead. + */ + /* listnodes must always contain data to be valid. Adding an empty node * to a list is invalid */ diff --git a/lib/openbsd-queue.h b/lib/openbsd-queue.h index df3bbd720fe1..a2df521f5828 100644 --- a/lib/openbsd-queue.h +++ b/lib/openbsd-queue.h @@ -16,6 +16,22 @@ extern "C" { #endif +/* + * NOTICE: + * + * If you are reading this file in an effort to add a new queue structure + * this is the wrong place to be using it. Please see the typesafe + * data structures, or ask one of the other developers. + * + * If you are reading this file as a way to update an existing usage + * of this data structure, please consider just converting the data + * structure to one of the typesafe data structures instead. However, + * among converting datastrucutres, the the BSD ones are the lowest + * priority / should be converted last. They are already typesafe and + * use inline linking nodes, so the only gain is consistency. Please + * convert uses of linklist.h and hash.h first. + */ + /* * This file defines five types of data structures: singly-linked lists, * lists, simple queues, tail queues and XOR simple queues. diff --git a/lib/openbsd-tree.h b/lib/openbsd-tree.h index 4f3985bbca04..ecc3a68f157f 100644 --- a/lib/openbsd-tree.h +++ b/lib/openbsd-tree.h @@ -10,6 +10,21 @@ #ifdef __cplusplus extern "C" { #endif +/* + * NOTICE: + * + * If you are reading this file in an effort to add a new tree structure + * this is the wrong place to be using it. Please see the typesafe + * data structures, or ask one of the other developers. + * + * If you are reading this file as a way to update an existing usage + * of this data structure, please consider just converting the data + * structure to one of the typesafe data structures instead. However, + * among converting datastrucutres, the the BSD ones are the lowest + * priority / should be converted last. They are already typesafe and + * use inline linking nodes, so the only gain is consistency. Please + * convert uses of linklist.h and hash.h first. + */ /* * This file defines data structures for different types of trees: From 248bf31a4f2880133c57e36a4a2bfbbdcf3d9a9a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 19 Jun 2024 08:01:16 -0400 Subject: [PATCH 312/472] doc: Document the usage of --enable-undefined-sanitizer Signed-off-by: Donald Sharp --- doc/developer/workflow.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index f720f6279ef2..166c96da33c6 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -1306,6 +1306,16 @@ MemorySanitizer to ``configure``. +UndefinedSanitizer + Similar to AddressSanitizer, this tool provides runtime instrumentation for + detecting use of undefined behavior in C. Testing your own code with this + tool before submission is encouraged. You can enable it by passing:: + + --enable-undefined-sanitizer + + to ``configure``. If you run FRR with this you will probably also have + to set ``sudo sysctl vm.mmap_rnd_bits=28`` + All of the above tools are available in the Clang/LLVM toolchain since 3.4. AddressSanitizer and ThreadSanitizer are available in recent versions of GCC, but are no longer actively maintained. MemorySanitizer is not available in GCC. From 8aeac1f005d5b462314c73db098878042fe6c444 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 19 Jun 2024 21:36:17 +0200 Subject: [PATCH 313/472] tests/lib: fix seqlock test seqlock_bump() used to return the value before bumping, but that's unhelpful if you were to actually need it. I had changed it to return the value after, but the update to the test got lost at some point. The return value is not in fact used anywhere in FRR, so while it is a bug, it has zero impact. NB: yes, test_seqlock is not run, which sounds wrong. The problem here is that (a) the test itself uses sleeps and is timing sensitive, which would raise false positives. And (b), the test is meaningless if executed once. It needs to be run millions of times under various conditions (e.g. load) to catch rare races, and it needs to be run on machines with "odd" memory models (in this case I used BE ppc32 and ppc64 systems as test platforms.) Fixes: 6046b690b53 ("lib/seqlock: avoid syscalls in no-waiter cases") Signed-off-by: David Lamparter --- tests/lib/test_seqlock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/lib/test_seqlock.c b/tests/lib/test_seqlock.c index 288d4a8c2554..35501cbd4a6a 100644 --- a/tests/lib/test_seqlock.c +++ b/tests/lib/test_seqlock.c @@ -82,11 +82,11 @@ int main(int argc, char **argv) assert(seqlock_held(&sqlo)); assert(seqlock_cur(&sqlo) == 1); - assert(seqlock_bump(&sqlo) == 1); - assert(seqlock_cur(&sqlo) == 5); assert(seqlock_bump(&sqlo) == 5); + assert(seqlock_cur(&sqlo) == 5); assert(seqlock_bump(&sqlo) == 9); assert(seqlock_bump(&sqlo) == 13); + assert(seqlock_bump(&sqlo) == 17); assert(seqlock_cur(&sqlo) == 17); assert(seqlock_held(&sqlo)); From 1f67dfb1438e74e5258786d4a769084354fd375b Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 19 Jun 2024 22:32:54 +0200 Subject: [PATCH 314/472] lib: fix typo in rcu_do() I lost an underscore somewhere along the way. Which never caused issues because we don't use that function macro. It is, however, useful for testing, so fix it. Signed-off-by: David Lamparter --- lib/frrcu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/frrcu.h b/lib/frrcu.h index 9f07a69b5226..81ab5528a9dd 100644 --- a/lib/frrcu.h +++ b/lib/frrcu.h @@ -156,7 +156,7 @@ extern void rcu_enqueue(struct rcu_head *head, const struct rcu_action *action); #define rcu_call(func, ptr, field) \ do { \ typeof(ptr) _ptr = (ptr); \ - void (*fptype)(typeof(ptr)); \ + void (*_fptype)(typeof(ptr)); \ struct rcu_head *_rcu_head = &_ptr->field; \ static const struct rcu_action _rcu_action = { \ .type = RCUA_CALL, \ From 4836ac071409bfff65f833ce82bd5f0338d0a8ae Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 20 Jun 2024 10:56:18 +0200 Subject: [PATCH 315/472] tests: silence TSAN warning on test_seqlock exit TSAN warns about leaving the second thread dangling. Doesn't really matter, but just add a pthread_join to get rid of the warning. Signed-off-by: David Lamparter --- tests/lib/test_seqlock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/test_seqlock.c b/tests/lib/test_seqlock.c index 35501cbd4a6a..937b3f34f55f 100644 --- a/tests/lib/test_seqlock.c +++ b/tests/lib/test_seqlock.c @@ -111,4 +111,5 @@ int main(int argc, char **argv) writestr("main @release\n"); seqlock_release(&sqlo); sleep(1); + pthread_join(thr1, NULL); } From b9541fe77fcb706c3f265d704e15f810b0a98c14 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 20 Jun 2024 11:13:20 +0200 Subject: [PATCH 316/472] lib: use seqlock slow path with TSAN TSAN doesn't understand the OS specific "fast" seqlock code. Use the pthread mutex/condvar based path when TSAN is enabled. Signed-off-by: David Lamparter --- lib/seqlock.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/seqlock.c b/lib/seqlock.c index 62ce316920dd..e74e6718bfef 100644 --- a/lib/seqlock.c +++ b/lib/seqlock.c @@ -26,6 +26,39 @@ * OS specific synchronization wrappers * ****************************************/ +#ifndef __has_feature /* not available on old GCC */ +#define __has_feature(x) 0 +#endif + +#if (defined(__SANITIZE_THREAD__) || __has_feature(thread_sanitizer)) +/* TSAN really does not understand what is going on with the low-level + * futex/umtx calls. This leads to a whole bunch of warnings, a lot of which + * also have _extremely_ misleading text - since TSAN does not understand that + * there is in fact a synchronization primitive involved, it can end up pulling + * in completely unrelated things. + * + * What does work is the "unsupported platform" seqlock implementation based + * on a pthread mutex + condvar, since TSAN of course suppports these. + * + * It may be possible to also fix this with TSAN annotations (__tsan_acquire + * and __tsan_release), but using those (correctly) is not easy either, and + * for now just get things rolling. + */ + +#ifdef HAVE_SYNC_LINUX_FUTEX +#undef HAVE_SYNC_LINUX_FUTEX +#endif + +#ifdef HAVE_SYNC_OPENBSD_FUTEX +#undef HAVE_SYNC_OPENBSD_FUTEX +#endif + +#ifdef HAVE_SYNC_UMTX_OP +#undef HAVE_SYNC_UMTX_OP +#endif + +#endif /* TSAN */ + /* * Linux: sys_futex() */ From 17fdfe92ab666605070b7d3733332e4e02354ab8 Mon Sep 17 00:00:00 2001 From: Martin Winter Date: Wed, 15 May 2024 10:32:33 +0200 Subject: [PATCH 317/472] debian: Add option to build pkg with grpc support Signed-off-by: Martin Winter --- debian/control | 16 +++++++++++++++- debian/copyright | 25 +++++++++++++++++++++++++ debian/frr-grpc.install | 2 ++ debian/rules | 7 +++++++ doc/developer/packaging-debian.rst | 2 ++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 debian/frr-grpc.install diff --git a/debian/control b/debian/control index 12b80a77f362..4a02a36b71d1 100644 --- a/debian/control +++ b/debian/control @@ -33,7 +33,11 @@ Build-Depends: bison, python3-sphinx:native, texinfo (>= 4.7), lua5.3 , - liblua5.3-dev + liblua5.3-dev , + libgrpc-dev (>=1.16.1) , + libgrpc++-dev (>=1.16.1) , + protobuf-compiler (>=3.6.1) , + protobuf-compiler-grpc (>=1.16.1) Standards-Version: 4.5.0.3 Homepage: https://www.frrouting.org/ Vcs-Browser: https://github.com/FRRouting/frr/tree/debian/master @@ -136,3 +140,13 @@ Description: FRRouting suite - Python tools . Without this package installed, "reload" (as a systemd or init script invocation) will not work for the FRR daemons. + +Package: frr-grpc +Architecture: linux-any +Depends: frr (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends} +Description: FRRouting suite - GRPC interface + This provides the GRPC interface to the daemons. +Build-Profiles: + diff --git a/debian/copyright b/debian/copyright index edd73020bd22..e1a944b338ad 100644 --- a/debian/copyright +++ b/debian/copyright @@ -4,6 +4,13 @@ Upstream-Contact: maintainers@frrouting.org, security@frrouting.org Source: https://www.frrouting.org/ Files: * +Comment: Note: GPL Versions of FRR binaries + If GRPC module is installed then please be aware that the + combination of the GRPC (licensed under Apache License) and + FRR (Licensed under GPLv2+) will force the resulting grpc + modules and related binaries to GPLv3 + Impacted binary files: frr/libfrrgrpc_pb.* frr/modules/grpc.so + FRR built or used without GRPC is not impacted Copyright: 1996-2003 by the original Zebra authors: Kunihiro Ishiguro Toshiaki Takada @@ -377,6 +384,24 @@ License: LGPL-2.1+ License version 2.1 can be found in the file `/usr/share/common-licenses/LGPL-2.1'. +License: GPL-3 + This package 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 3 of the License, or + (at your option) any later version. + . + This package 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 package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of the GNU General + Public License can be found in `/usr/share/common-licenses/GPL-3'. + License: BSD-0-clause Redistribution and use in source and binary forms, with or without modification, are permitted. diff --git a/debian/frr-grpc.install b/debian/frr-grpc.install new file mode 100644 index 000000000000..d006439e6fab --- /dev/null +++ b/debian/frr-grpc.install @@ -0,0 +1,2 @@ +usr/lib/*/frr/libfrrgrpc_pb.* +usr/lib/*/frr/modules/grpc.so diff --git a/debian/rules b/debian/rules index 0f841457180e..ec8f92f755f6 100755 --- a/debian/rules +++ b/debian/rules @@ -33,6 +33,12 @@ else CONF_PIM6=--disable-pim6d endif +ifeq ($(filter pkg.frr.grpc,$(DEB_BUILD_PROFILES)),) + CONF_GRPC=--disable-grpc +else + CONF_GRPC=--enable-grpc +endif + export PYTHON=python3 %: @@ -51,6 +57,7 @@ override_dh_auto_configure: $(CONF_RPKI) \ $(CONF_LUA) \ $(CONF_PIM6) \ + $(CONF_GRPC) \ --with-libpam \ --enable-doc \ --enable-doc-html \ diff --git a/doc/developer/packaging-debian.rst b/doc/developer/packaging-debian.rst index c2c3b7e7e1eb..4109057ee5e5 100644 --- a/doc/developer/packaging-debian.rst +++ b/doc/developer/packaging-debian.rst @@ -68,6 +68,8 @@ buster.) +----------------+-------------------+-----------------------------------------+ | pkg.frr.pim6d | pkg.frr.nopim6d | builds pim6d (default enabled) | +----------------+-------------------+-----------------------------------------+ + | pkg.frr.grpc | pkg.frr.nogrpc | builds with grpc support (default: no) | + +----------------+-------------------+-----------------------------------------+ * the ``-uc -us`` options to disable signing the packages with your GPG key From a761db826c323c1d69eba59db31ac1f53d13e0b4 Mon Sep 17 00:00:00 2001 From: Martin Winter Date: Wed, 29 May 2024 19:13:19 +0200 Subject: [PATCH 318/472] redhat: Add option to build pkg with grpc support Signed-off-by: Martin Winter --- doc/developer/packaging-redhat.rst | 31 ++++++++++++++++-------------- redhat/frr.spec.in | 29 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/doc/developer/packaging-redhat.rst b/doc/developer/packaging-redhat.rst index d88f449926b3..8037873461a5 100644 --- a/doc/developer/packaging-redhat.rst +++ b/doc/developer/packaging-redhat.rst @@ -67,24 +67,27 @@ Tested on CentOS 6, CentOS 7, CentOS 8 and Fedora 24. ############### FRRouting (FRR) configure options ################# # with-feature options - %{!?with_pam: %global with_pam 0 } - %{!?with_ospfclient: %global with_ospfclient 1 } - %{!?with_ospfapi: %global with_ospfapi 1 } - %{!?with_irdp: %global with_irdp 1 } - %{!?with_rtadv: %global with_rtadv 1 } + %{!?with_babeld: %global with_babeld 1 } + %{!?with_bfdd: %global with_bfdd 1 } + %{!?with_bgp_vnc: %global with_bgp_vnc 0 } + %{!?with_cumulus: %global with_cumulus 0 } + %{!?with_eigrpd: %global with_eigrpd 1 } + %{!?with_fpm: %global with_fpm 1 } + %{!?with_mgmtd_test_be_client: %global with_mgmtd_test_be_client 0 } %{!?with_ldpd: %global with_ldpd 1 } - %{!?with_nhrpd: %global with_nhrpd 1 } - %{!?with_eigrp: %global with_eigrpd 1 } - %{!?with_shared: %global with_shared 1 } %{!?with_multipath: %global with_multipath 256 } - %{!?frr_user: %global frr_user frr } - %{!?vty_group: %global vty_group frrvty } - %{!?with_fpm: %global with_fpm 0 } - %{!?with_watchfrr: %global with_watchfrr 1 } - %{!?with_bgp_vnc: %global with_bgp_vnc 0 } + %{!?with_nhrpd: %global with_nhrpd 1 } + %{!?with_ospfapi: %global with_ospfapi 1 } + %{!?with_ospfclient: %global with_ospfclient 1 } + %{!?with_pam: %global with_pam 0 } + %{!?with_pbrd: %global with_pbrd 1 } %{!?with_pimd: %global with_pimd 1 } %{!?with_pim6d: %global with_pim6d 1 } - %{!?with_rpki: %global with_rpki 0 } + %{!?with_vrrpd: %global with_vrrpd 1 } + %{!?with_rtadv: %global with_rtadv 1 } + %{!?with_watchfrr: %global with_watchfrr 1 } + %{!?with_pathd: %global with_pathd 1 } + %{!?with_grpc: %global with_grpc 0 } 8. Build the RPM:: diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in index f42079cd5041..d6775e6e9cae 100644 --- a/redhat/frr.spec.in +++ b/redhat/frr.spec.in @@ -30,6 +30,7 @@ %{!?with_rtadv: %global with_rtadv 1 } %{!?with_watchfrr: %global with_watchfrr 1 } %{!?with_pathd: %global with_pathd 1 } +%{!?with_grpc: %global with_grpc 0 } # user and group %{!?frr_user: %global frr_user frr } @@ -201,6 +202,12 @@ BuildRequires: python3-devel BuildRequires: python3-sphinx %endif %endif +%if %{with_grpc} +BuildRequires: grpc-devel >= 1.16.1 +BuildRequires: protobuf-devel >= 3.6.1 +BuildRequires: protobuf-compiler >= 3.6.1 +BuildRequires: protobuf-c-devel +%endif %if 0%{?rhel} > 7 #platform-python-devel is needed for /usr/bin/pathfix.py BuildRequires: platform-python-devel @@ -301,6 +308,17 @@ through the AgentX protocol. Provides read-only access to current routing state through standard SNMP MIBs. +%if %{with_grpc} +%package grpc +Summary: GRPC support for FRR daemons +Group: System Environment/Daemons +License: GPLv3+ +Requires: %{name} = %{version}-%{release} + +%description grpc +Adds GRPC support to the individual FRR daemons. +%endif + %prep %setup -q -n frr-%{frrversion} @@ -424,6 +442,11 @@ routing state through standard SNMP MIBs. --enable-pathd \ %else --disable-pathd \ +%endif +%if %{with_grpc} + --enable-grpc \ +%else + --disable-grpc \ %endif --enable-snmp # end @@ -783,6 +806,12 @@ sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons %{_libdir}/frr/modules/*snmp.so +%if %{with_grpc} +%files grpc +%{_libdir}/libfrrgrpc_pb.* +%{_libdir}/frr/modules/grpc.so +%endif + %files devel %{_libdir}/lib*.so %dir %{_includedir}/%{name} From f18cb4fb58cd443fad02ed991387b301885aaaea Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 8 May 2024 19:27:22 +0200 Subject: [PATCH 319/472] pimd: make clang-format slightly less annoying The YANG module list is really better as 1-item-per-line. Signed-off-by: David Lamparter --- pimd/pim6_main.c | 2 +- pimd/pim_main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pimd/pim6_main.c b/pimd/pim6_main.c index 5ce6985c4520..24443404eb5e 100644 --- a/pimd/pim6_main.c +++ b/pimd/pim6_main.c @@ -94,6 +94,7 @@ struct frr_signal_t pim6d_signals[] = { }, }; +/* clang-format off */ static const struct frr_yang_module_info *const pim6d_yang_modules[] = { &frr_filter_info, &frr_interface_info, @@ -105,7 +106,6 @@ static const struct frr_yang_module_info *const pim6d_yang_modules[] = { &frr_gmp_info, }; -/* clang-format off */ FRR_DAEMON_INFO(pim6d, PIM6, .vty_port = PIM6D_VTY_PORT, .proghelp = "Protocol Independent Multicast (RFC7761) for IPv6", diff --git a/pimd/pim_main.c b/pimd/pim_main.c index 400db396c289..8f2ce0bed335 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -59,6 +59,7 @@ struct zebra_privs_t pimd_privs = { .cap_num_p = array_size(_caps_p), .cap_num_i = 0}; +/* clang-format off */ static const struct frr_yang_module_info *const pimd_yang_modules[] = { &frr_filter_info, &frr_interface_info, @@ -70,7 +71,6 @@ static const struct frr_yang_module_info *const pimd_yang_modules[] = { &frr_gmp_info, }; -/* clang-format off */ FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT, .proghelp = "Implementation of the PIM routing protocol.", From 1f223ae1eed80f2552a279ee34464edf363bba6f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 11 Jul 2022 21:58:27 +0200 Subject: [PATCH 320/472] pimd: add debugs for i-am-RP state This proved helpful in debugging the Candidate-RP code. Signed-off-by: David Lamparter --- pimd/pim_rp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index d8d25712a30f..b0fb8a509af2 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -543,6 +543,9 @@ int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group, pim_zebra_update_all_interfaces(pim); pim_rp_check_interfaces(pim, rp_all); + if (rp_all->i_am_rp && PIM_DEBUG_PIM_NHT_RP) + zlog_debug("new RP %pPA for %pFX is ourselves", + &rp_all->rp.rpf_addr, &rp_all->group); pim_rp_refresh_group_to_rp_mapping(pim); pim_find_or_track_nexthop(pim, nht_p, NULL, rp_all, NULL); @@ -634,6 +637,9 @@ int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group, pim_zebra_update_all_interfaces(pim); pim_rp_check_interfaces(pim, rp_info); + if (rp_info->i_am_rp && PIM_DEBUG_PIM_NHT_RP) + zlog_debug("new RP %pPA for %pFX is ourselves", + &rp_info->rp.rpf_addr, &rp_info->group); pim_rp_refresh_group_to_rp_mapping(pim); /* Register addr with Zebra NHT */ From 18b82f64c9538b6fd3b9f61c86dfff8cbdc8c6b6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 8 May 2024 19:25:55 +0200 Subject: [PATCH 321/472] pimd: add prefix_* and IANA_AFI v4/v6 defines The Candidate-RP code is about to use these. Signed-off-by: David Lamparter --- pimd/pim_addr.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h index ecba739a5a4e..7b0c3f0350e2 100644 --- a/pimd/pim_addr.h +++ b/pimd/pim_addr.h @@ -14,11 +14,13 @@ #if PIM_IPV == 4 typedef struct in_addr pim_addr; +typedef struct prefix_ipv4 prefix_pim; #define PIM_ADDRSTRLEN INET_ADDRSTRLEN #define PIM_AF AF_INET #define PIM_AFI AFI_IP #define PIM_PROTO_REG IPPROTO_RAW +#define PIM_IANA_AFI IANA_AFI_IPV4 #define PIM_IPADDR IPADDR_V4 #define ipaddr_pim ipaddr_v4 #define PIM_MAX_BITLEN IPV4_MAX_BITLEN @@ -44,11 +46,13 @@ union pimprefixconstptr { #else typedef struct in6_addr pim_addr; +typedef struct prefix_ipv6 prefix_pim; #define PIM_ADDRSTRLEN INET6_ADDRSTRLEN #define PIM_AF AF_INET6 #define PIM_AFI AFI_IP6 #define PIM_PROTO_REG IPPROTO_PIM +#define PIM_IANA_AFI IANA_AFI_IPV6 #define PIM_IPADDR IPADDR_V6 #define ipaddr_pim ipaddr_v6 #define PIM_MAX_BITLEN IPV6_MAX_BITLEN From cca9bc193edfebbd93fbdd76bd4c3b8310f007d6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 9 Jul 2022 18:47:43 +0200 Subject: [PATCH 322/472] pimd: allow sending packets without pinned iface The upcoming Candidate-RP code needs to send PIM packets that go through normal unicast routing, without forcing a specific output interface. Allow passing in NULL ifp to do that. Signed-off-by: David Lamparter --- pimd/pim_pim.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index 1bc265b138f6..6a7e8924f2f6 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -636,17 +636,15 @@ static int pim_msg_send_frame(pim_addr src, pim_addr dst, ifindex_t ifindex, int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg, int pim_msg_size, struct interface *ifp) { - struct pim_interface *pim_ifp; - + if (ifp) { + struct pim_interface *pim_ifp = ifp->info; - pim_ifp = ifp->info; - - if (pim_ifp->pim_passive_enable) { - if (PIM_DEBUG_PIM_PACKETS) - zlog_debug( - "skip sending PIM message on passive interface %s", - ifp->name); - return 0; + if (pim_ifp->pim_passive_enable) { + if (PIM_DEBUG_PIM_PACKETS) + zlog_debug("skip sending PIM message on passive interface %s", + ifp->name); + return 0; + } } #if PIM_IPV == 4 @@ -710,7 +708,7 @@ int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg, if (PIM_DEBUG_PIM_PACKETS) zlog_debug("%s: to %pPA on %s: msg_size=%d checksum=%x", - __func__, &dst, ifp->name, pim_msg_size, + __func__, &dst, ifp ? ifp->name : "*", pim_msg_size, header->checksum); if (PIM_DEBUG_PIM_PACKETDUMP_SEND) { @@ -718,7 +716,7 @@ int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg, } pim_msg_send_frame(fd, (char *)buffer, sendlen, (struct sockaddr *)&to, - tolen, ifp->name); + tolen, ifp ? ifp->name : "*"); return 0; #else @@ -727,7 +725,7 @@ int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg, iovector[0].iov_base = pim_msg; iovector[0].iov_len = pim_msg_size; - pim_msg_send_frame(src, dst, ifp->ifindex, &iovector[0], fd); + pim_msg_send_frame(src, dst, ifp ? ifp->ifindex : 0, &iovector[0], fd); return 0; #endif From b9a02da83b65fa7066ef17f71a32f5aa0648e28e Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 25 Jun 2021 11:42:38 +0200 Subject: [PATCH 323/472] pimd: prepare NHT for tracking BSM C-RPs For BSMs, we should track which of the RP candidates in the BSM message are actually available, before trying to use them (which also puts them in NHT for that). This applies for both BSRs as well as BSM receivers. Signed-off-by: David Lamparter --- pimd/pim_bsm.c | 5 +++++ pimd/pim_nht.c | 47 ++++++++++++++++++++++++++++++++++++++++------- pimd/pim_nht.h | 7 +++++++ 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index df9161943d37..2d451718a983 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -1451,3 +1451,8 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf, return 0; } + +void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc) +{ + /* stub for Candidate-RP */ +} diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 32cdf4bf8289..57dcff3b4710 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -161,18 +161,27 @@ void pim_nht_bsr_add(struct pim_instance *pim, pim_addr addr) pnc->bsr_count++; } +bool pim_nht_candrp_add(struct pim_instance *pim, pim_addr addr) +{ + struct pim_nexthop_cache *pnc; + + pnc = pim_nht_get(pim, addr); + + pnc->candrp_count++; + return CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID); +} + static void pim_nht_drop_maybe(struct pim_instance *pim, struct pim_nexthop_cache *pnc) { if (PIM_DEBUG_PIM_NHT) - zlog_debug( - "%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u", - __func__, &pnc->rpf.rpf_addr, pim->vrf->name, - pnc->rp_list->count, pnc->upstream_hash->count, - pnc->bsr_count); + zlog_debug("%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u Cand-RP count:%u", + __func__, &pnc->rpf.rpf_addr, pim->vrf->name, + pnc->rp_list->count, pnc->upstream_hash->count, + pnc->bsr_count, pnc->candrp_count); - if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0 - && pnc->bsr_count == 0) { + if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0 && + pnc->bsr_count == 0 && pnc->candrp_count == 0) { struct zclient *zclient = pim_zebra_zclient_get(); pim_sendmsg_zebra_rnh(pim, zclient, pnc, @@ -258,6 +267,27 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr addr) pim_nht_drop_maybe(pim, pnc); } +void pim_nht_candrp_del(struct pim_instance *pim, pim_addr addr) +{ + struct pim_nexthop_cache *pnc = NULL; + struct pim_nexthop_cache lookup; + + lookup.rpf.rpf_addr = addr; + + pnc = hash_lookup(pim->rpf_hash, &lookup); + + if (!pnc) { + zlog_warn("attempting to delete nonexistent NHT C-RP entry %pPA", + &addr); + return; + } + + assertf(pnc->candrp_count > 0, "addr=%pPA", &addr); + pnc->candrp_count--; + + pim_nht_drop_maybe(pim, pnc); +} + bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr, struct interface *src_ifp, pim_addr src_ip) { @@ -900,6 +930,9 @@ void pim_nexthop_update(struct vrf *vrf, struct prefix *match, pim_update_rp_nh(pim, pnc); if (pnc->upstream_hash->count) pim_update_upstream_nh(pim, pnc); + + if (pnc->candrp_count) + pim_crp_nht_update(pim, pnc); } int pim_ecmp_nexthop_lookup(struct pim_instance *pim, diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h index a1feb76e3b73..e74b375dc6d2 100644 --- a/pimd/pim_nht.h +++ b/pimd/pim_nht.h @@ -38,6 +38,7 @@ struct pim_nexthop_cache { * same BSR */ uint32_t bsr_count; + uint32_t candrp_count; }; struct pnc_hash_walk_data { @@ -71,4 +72,10 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr bsr_addr); bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr, struct interface *src_ifp, pim_addr src_ip); void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp); + +/* wrappers for usage with Candidate RPs in BSMs */ +bool pim_nht_candrp_add(struct pim_instance *pim, pim_addr addr); +void pim_nht_candrp_del(struct pim_instance *pim, pim_addr addr); +void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc); + #endif From e14c94f2b77692126210f4b7b51cf097d7f847e0 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 20 Jun 2024 12:02:25 +0200 Subject: [PATCH 324/472] tests: fix TSAN warnings in atomlist test The atomlist test consists of a sequence of (MT) sub-tests, from which counters are collected and verified. TSAN doesn't know that these counters are synchronized by way of the sub-test starting and finishing, so it complains. Just use atomics to get rid of the warning. (This is solely an issue with the test, not the atomlist code. There are no warnings from that.) Signed-off-by: David Lamparter --- tests/lib/test_atomlist.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/lib/test_atomlist.c b/tests/lib/test_atomlist.c index b50216cf9292..afcfa9879138 100644 --- a/tests/lib/test_atomlist.c +++ b/tests/lib/test_atomlist.c @@ -62,7 +62,7 @@ static struct asort_head shead; static struct testthread { pthread_t pt; struct seqlock sqlo; - size_t counter, nullops; + _Atomic size_t counter, nullops; } thr[NTHREADS]; struct testrun { @@ -97,10 +97,10 @@ static void trfunc_##name(unsigned int offset) \ { \ size_t i = 0, n = 0; -#define endtestrun \ - thr[offset].counter = i; \ - thr[offset].nullops = n; \ -} +#define endtestrun \ + atomic_store_explicit(&thr[offset].counter, i, memory_order_seq_cst); \ + atomic_store_explicit(&thr[offset].nullops, n, memory_order_seq_cst); \ + } deftestrun(add, "add vs. add", 0, false) for (; i < NITEM / NTHREADS; i++) @@ -288,10 +288,10 @@ static void run_tr(struct testrun *tr) sv = seqlock_bump(&sqlo) - SEQLOCK_INCR; for (size_t i = 0; i < NTHREADS; i++) { seqlock_wait(&thr[i].sqlo, seqlock_cur(&sqlo)); - s += thr[i].counter; - n += thr[i].nullops; - thr[i].counter = 0; - thr[i].nullops = 0; + s += atomic_load_explicit(&thr[i].counter, memory_order_seq_cst); + n += atomic_load_explicit(&thr[i].nullops, memory_order_seq_cst); + atomic_store_explicit(&thr[i].counter, 0, memory_order_seq_cst); + atomic_store_explicit(&thr[i].nullops, 0, memory_order_seq_cst); } delta = monotime_since(&tv, NULL); From c494702929d15141e8f3fd4a1d9f85095076a4b7 Mon Sep 17 00:00:00 2001 From: Acee Lindem Date: Fri, 31 May 2024 14:08:04 +0000 Subject: [PATCH 325/472] ospfd: Improve OSPF neighbor retransmission list granularity and precision The current OSPF neighbor retransmission operates on a single per-neighbor periodic timer that sends all LSAs on the list when it expires. Additionally, since it skips the first retransmission of received LSAs so that at least the retransmission interval (resulting in a delay of between the retransmission interval and twice the interval. In environments where the links are lossy on P2MP networks with "delay-reflood" configured (which relies on neighbor retransmission in partial meshs), the implementation is sub-optimal (to say the least). This commit reimplements OSPF neighbor retransmission as follows: 1. A new data structure making use the application managed typesafe.h doubly linked list implements an OSPF LSA list where each node includes a timestamp. 2. The existing neighbor LS retransmission LSDB data structure is augmented with a pointer to the list node on the LSA list to faciliate O(1) removal when the LSA is acknowledged. 3. The neighbor LS retransmission timer is set to the expiration timer of the LSA at the top of the list. 4. When the timer expires, LSAs are retransmitted that within the window of the current time and a small delta (50 milli-secs default). The LSAs that are retransmited are given an updated retransmission time and moved to the end of the LSA list. 5. Configuration is added to set the "retransmission-window" to a value other than 50 milliseconds. 6. Neighbor and interface LSA retransmission counters are added to provide insight into the lossiness of the links. However, these will increment quickly on non-fully meshed P2MP networks with "delay-reflood" configured. 7. Added a topotest to exercise the implementation on a non-fully meshed P2MP network with "delay-reflood" configured. The alternative was to use existing mechanisms to instroduce loss but these seem less determistic in a topotest. Signed-off-by: Acee Lindem --- doc/developer/ospf-ls-retrans.rst | 69 +++++++++ doc/developer/ospf.rst | 1 + doc/user/ospfd.rst | 12 +- lib/libospf.h | 1 + ospfd/ospf_flood.c | 146 +++++++++++++++--- ospfd/ospf_flood.h | 22 +++ ospfd/ospf_interface.c | 5 + ospfd/ospf_interface.h | 3 + ospfd/ospf_lsdb.c | 53 +++++++ ospfd/ospf_lsdb.h | 23 +++ ospfd/ospf_memory.c | 2 + ospfd/ospf_memory.h | 2 + ospfd/ospf_neighbor.c | 8 +- ospfd/ospf_neighbor.h | 7 +- ospfd/ospf_nsm.c | 6 +- ospfd/ospf_packet.c | 91 ++++++----- ospfd/ospf_packet.h | 2 +- ospfd/ospf_vty.c | 140 +++++++++++++---- .../r1/show_ip_ospf_interface.ref | 2 + tests/topotests/ospf_p2mp/r1/frr-p2mp.conf | 6 + tests/topotests/ospf_p2mp/r2/frr-p2mp.conf | 6 + tests/topotests/ospf_p2mp/r3/frr-p2mp.conf | 6 + tests/topotests/ospf_p2mp/r4/frr-p2mp.conf | 6 + .../ospf_p2mp/test_ospf_p2mp_broadcast.py | 112 ++++++++++++-- 24 files changed, 620 insertions(+), 111 deletions(-) create mode 100644 doc/developer/ospf-ls-retrans.rst diff --git a/doc/developer/ospf-ls-retrans.rst b/doc/developer/ospf-ls-retrans.rst new file mode 100644 index 000000000000..230d7a1c5d95 --- /dev/null +++ b/doc/developer/ospf-ls-retrans.rst @@ -0,0 +1,69 @@ +OSPF Neighor Retransmission List +================================ + +Overview +-------- + +OSPF neighbor link-state retransmission lists are implemented using +both a sparse Link State Database (LSDB) and a doubly-linked list. +Rather than previous per-neighbor periodic timer, a per-neighbor +timer is set to the expiration time of the next scheduled LSA +retransmission. + +Sparse Link State Database (LSDB) +--------------------------------- + +When an explicit or implied acknowledgment is recieved from a +neighbor in 2-way state or higher, the acknowledge LSA must be +removed from the neighbor's link state retransmission list. In order +to do this efficiently, a sparse LSDB is utilized. LSDB entries also +include a pointer to the corresponding list entry so that it may be +efficiently removed from the doubly-linked list. + +The sparse LSDB is implemented using the OSPF functions is +ospf_lsdb.[c,h]. OSPF LSDBs are implemented as an array of route +tables (lib/table.[c,h]). What is unique of the LS Retransmission +list LSDB is that each entry also has a pointer into the doubly-linked +list to facilitate fast deletions. + +Doubly-Linked List +------------------ + +In addition to the sparse LSDB, LSAs on a neighbor LS retransmission +list are also maintained in a linked-list order chronologically +with the LSA scheduled for the next retransmission at the head of +the list. + +The doubly-link list is implemented using the dlist macros in +lib/typesafe.h. + +LSA LS Retransmission List Addition +------------------------------------ + +When an LSA is added to a neighbor retransmission list, it is +added to both the sparse LSDB and the doubly-linked list with a pointer +in the LSDB route-table node to the list entry. The LSA is added to +the tail of the list with the expiration time set to the current time +with the retransmission interval added. If the neighbor retransmission +timer is not set, it is set to expire at the time of the newly added +LSA. + +LSA LS Retransmission List Deletion +----------------------------------- + +When an LSA is deleted from a neighbor retransmission list, it is +deleted from eboth the sparse LSDB and the doubly-linked list with the +pointer the LSDB route-table node used to efficiently delete the entry +from the list. If the LSA at the head of the list was removed, then +the neighbor retransmission timer is reset to the expiration of the +LSA at the head of the list or canceled if the list is empty. + +Neighbor LS Retransmission List Expiration +------------------------------------------ + +When the neighbor retransmission timer expires, the LSA at the top of +list and any in a configured window (e.g., 50 milliseconds) are +retransmitted. The LSAs that have been retransmitted are removed from +the list and readded to the tail of the list with a new expiration time +which is retransmit-interval seconds in the future. + diff --git a/doc/developer/ospf.rst b/doc/developer/ospf.rst index 837a0bd18598..da4802533c03 100644 --- a/doc/developer/ospf.rst +++ b/doc/developer/ospf.rst @@ -8,6 +8,7 @@ OSPFD :maxdepth: 2 ospf-api + ospf-ls-retrans ospf-sr cspf diff --git a/doc/user/ospfd.rst b/doc/user/ospfd.rst index 70c15e73deb0..b80adba7f046 100644 --- a/doc/user/ospfd.rst +++ b/doc/user/ospfd.rst @@ -738,7 +738,17 @@ Interfaces retransmitting Database Description and Link State Request packets. The default value is 5 seconds. -.. clicmd:: ip ospf transmit-delay (1-65535) [A.B.C.D] +.. clicmd:: ip ospf retransmit-window (20-1000) + + + Set number of milliseconds in the window for neighbor LSA retransmission. + When a neighbor Link State (LS) retransmission timer expires, LSAs scheduled + to be retransmitted within the number of milliseconds configured are + retransmitted to the neighbor. Any expiring after the window will be + retransmitted the next time the neighbor LS retransmission timer expires. + The default is 50 milliseconds. + + .. clicmd:: ip ospf transmit-delay (1-65535) [A.B.C.D] Set number of seconds for InfTransDelay value. LSAs' age should be diff --git a/lib/libospf.h b/lib/libospf.h index 0ac490a00ece..f2dc5d61d9eb 100644 --- a/lib/libospf.h +++ b/lib/libospf.h @@ -58,6 +58,7 @@ extern "C" { #define OSPF_HELLO_DELAY_DEFAULT 10 #define OSPF_ROUTER_PRIORITY_DEFAULT 1 #define OSPF_RETRANSMIT_INTERVAL_DEFAULT 5 +#define OSPF_RETRANSMIT_WINDOW_DEFAULT 50 /* milliseconds */ #define OSPF_TRANSMIT_DELAY_DEFAULT 1 #define OSPF_DEFAULT_BANDWIDTH 10000 /* Mbps */ diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index e15871ac81cd..e9797ce935a7 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -1015,7 +1015,7 @@ void ospf_ls_request_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) ospf_lsdb_delete(&nbr->ls_req, lsa); } -/* Remove all LSA from neighbor's ls-requenst list. */ +/* Remove all LSAs from neighbor's ls-request list. */ void ospf_ls_request_delete_all(struct ospf_neighbor *nbr) { ospf_lsa_unlock(&nbr->ls_req_last); @@ -1061,58 +1061,114 @@ int ospf_ls_retransmit_isempty(struct ospf_neighbor *nbr) /* Add LSA to be retransmitted to neighbor's ls-retransmit list. */ void ospf_ls_retransmit_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { - struct ospf_lsa *old; + struct ospf_lsdb_linked_node *ls_rxmt_node; + struct ospf_lsa_list_entry *ls_rxmt_list_entry; + struct ospf_lsa *old = NULL; + bool rxmt_head_replaced = false; - old = ospf_ls_retransmit_lookup(nbr, lsa); + ls_rxmt_node = ospf_lsdb_linked_lookup(&nbr->ls_rxmt, lsa); + if (ls_rxmt_node) + old = ls_rxmt_node->info; if (ospf_lsa_more_recent(old, lsa) < 0) { if (old) { old->retransmit_counter--; + if (ls_rxmt_node->lsa_list_entry == + ospf_lsa_list_first(&nbr->ls_rxmt_list)) + rxmt_head_replaced = true; + ospf_lsa_list_del(&nbr->ls_rxmt_list, + ls_rxmt_node->lsa_list_entry); + XFREE(MTYPE_OSPF_LSA_LIST, ls_rxmt_node->lsa_list_entry); + ospf_lsdb_delete(&nbr->ls_rxmt, old); if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) - zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]", + zlog_debug("RXmtL(%lu) NBR(%pI4(%s)) Old Delete LSA[%s] on Add", ospf_ls_retransmit_count(nbr), &nbr->router_id, ospf_get_name(nbr->oi->ospf), - dump_lsa_key(old)); - ospf_lsdb_delete(&nbr->ls_rxmt, old); + dump_lsa_key(lsa)); + ospf_lsa_unlock(&old); } lsa->retransmit_counter++; + ls_rxmt_list_entry = XCALLOC(MTYPE_OSPF_LSA_LIST, + sizeof(struct ospf_lsa_list_entry)); + /* + * Set the LSA retransmission time for the neighbor; + */ + monotime(&ls_rxmt_list_entry->list_entry_time); + ls_rxmt_list_entry->list_entry_time.tv_sec += nbr->v_ls_rxmt; + + /* + * Add the LSA to the neighbor retransmission list. + */ + ls_rxmt_list_entry->lsa = ospf_lsa_lock(lsa); + ospf_lsa_list_add_tail(&nbr->ls_rxmt_list, ls_rxmt_list_entry); + ospf_lsdb_add(&nbr->ls_rxmt, lsa); + /* - * We cannot make use of the newly introduced callback function - * "lsdb->new_lsa_hook" to replace debug output below, just - * because - * it seems no simple and smart way to pass neighbor information - * to - * the common function "ospf_lsdb_add()" -- endo. + * Look up the newly added node and set the list pointer. */ + ls_rxmt_node = ospf_lsdb_linked_lookup(&nbr->ls_rxmt, lsa); + ls_rxmt_node->lsa_list_entry = ls_rxmt_list_entry; + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) - zlog_debug("RXmtL(%lu)++, NBR(%pI4(%s)), LSA[%s]", + zlog_debug("RXmtL(%lu) NBR(%pI4(%s)) Add LSA[%s] retrans at (%ld/%ld)", ospf_ls_retransmit_count(nbr), - &nbr->router_id, - ospf_get_name(nbr->oi->ospf), - dump_lsa_key(lsa)); - ospf_lsdb_add(&nbr->ls_rxmt, lsa); + &nbr->router_id, ospf_get_name(nbr->oi->ospf), + dump_lsa_key(lsa), + (long)ls_rxmt_list_entry->list_entry_time + .tv_sec, + (long)ls_rxmt_list_entry->list_entry_time + .tv_usec); + /* + * Reset the neighbor LSA retransmission timer if isn't currently + * running or the LSA at the head of the list was updated. + */ + if (!nbr->t_ls_rxmt || rxmt_head_replaced) + ospf_ls_retransmit_set_timer(nbr); } } /* Remove LSA from neibghbor's ls-retransmit list. */ void ospf_ls_retransmit_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { - if (ospf_ls_retransmit_lookup(nbr, lsa)) { + struct ospf_lsdb_linked_node *ls_rxmt_node; + + ls_rxmt_node = ospf_lsdb_linked_lookup(&nbr->ls_rxmt, lsa); + + if (ls_rxmt_node) { + bool rxmt_timer_reset; + + if (ls_rxmt_node->lsa_list_entry == + ospf_lsa_list_first(&nbr->ls_rxmt_list)) + rxmt_timer_reset = true; + else + rxmt_timer_reset = false; + lsa->retransmit_counter--; - if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */ - zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]", + ospf_lsa_list_del(&nbr->ls_rxmt_list, + ls_rxmt_node->lsa_list_entry); + XFREE(MTYPE_OSPF_LSA_LIST, ls_rxmt_node->lsa_list_entry); + ospf_lsdb_delete(&nbr->ls_rxmt, lsa); + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("RXmtL(%lu) NBR(%pI4(%s)) Delete LSA[%s]", ospf_ls_retransmit_count(nbr), - &nbr->router_id, - ospf_get_name(nbr->oi->ospf), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa)); - ospf_lsdb_delete(&nbr->ls_rxmt, lsa); + ospf_lsa_unlock(&lsa); + + /* + * If the LS retransmission entry at the head of the list was + * deleted, reset the timer. + */ + if (rxmt_timer_reset) + ospf_ls_retransmit_set_timer(nbr); } } /* Clear neighbor's ls-retransmit list. */ void ospf_ls_retransmit_clear(struct ospf_neighbor *nbr) { + struct ospf_lsa_list_entry *ls_rxmt_list_entry; struct ospf_lsdb *lsdb; int i; @@ -1128,10 +1184,54 @@ void ospf_ls_retransmit_clear(struct ospf_neighbor *nbr) ospf_ls_retransmit_delete(nbr, lsa); } + frr_each_safe (ospf_lsa_list, &nbr->ls_rxmt_list, ls_rxmt_list_entry) { + ospf_lsa_list_del(&nbr->ls_rxmt_list, ls_rxmt_list_entry); + ospf_lsa_unlock(&ls_rxmt_list_entry->lsa); + XFREE(MTYPE_OSPF_LSA_LIST, ls_rxmt_list_entry); + } + ospf_lsa_unlock(&nbr->ls_req_last); nbr->ls_req_last = NULL; } +/* + * Set the neighbor's ls-retransmit timer based on the next + * LSA retransmit time. + */ +void ospf_ls_retransmit_set_timer(struct ospf_neighbor *nbr) +{ + struct ospf_lsa_list_entry *ls_rxmt_list_entry; + + if (nbr->t_ls_rxmt) + EVENT_OFF(nbr->t_ls_rxmt); + + ls_rxmt_list_entry = ospf_lsa_list_first(&nbr->ls_rxmt_list); + if (ls_rxmt_list_entry) { + struct timeval current_time, delay; + unsigned long delay_milliseconds; + + monotime(¤t_time); + if (timercmp(¤t_time, + &ls_rxmt_list_entry->list_entry_time, >=)) + delay_milliseconds = 10; + else { + timersub(&ls_rxmt_list_entry->list_entry_time, + ¤t_time, &delay); + delay_milliseconds = (delay.tv_sec * 1000) + + (delay.tv_usec / 1000); + } + + event_add_timer_msec(master, ospf_ls_rxmt_timer, nbr, + delay_milliseconds, &nbr->t_ls_rxmt); + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("RXmtL(%lu) NBR(%pI4(%s)) retrans timer set in %ld msecs - Head LSA(%s)", + ospf_ls_retransmit_count(nbr), + &nbr->router_id, ospf_get_name(nbr->oi->ospf), + delay_milliseconds, + dump_lsa_key(ls_rxmt_list_entry->lsa)); + } +} + /* Lookup LSA from neighbor's ls-retransmit list. */ struct ospf_lsa *ospf_ls_retransmit_lookup(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h index 3757400d0cec..d9d953735148 100644 --- a/ospfd/ospf_flood.h +++ b/ospfd/ospf_flood.h @@ -7,6 +7,26 @@ #ifndef _ZEBRA_OSPF_FLOOD_H #define _ZEBRA_OSPF_FLOOD_H +/* + * OSPF Temporal LSA List + */ +PREDECL_DLIST(ospf_lsa_list); + +struct ospf_lsa_list_entry { + /* Linkage for LSA List */ + struct ospf_lsa_list_item list_linkage; + + /* + * Time associated with the list entry. For example, for a neigbhor + * link retransmission list, this is the retransmission time. + */ + struct timeval list_entry_time; + + struct ospf_lsa *lsa; +}; + +DECLARE_DLIST(ospf_lsa_list, struct ospf_lsa_list_entry, list_linkage); + extern int ospf_flood(struct ospf *, struct ospf_neighbor *, struct ospf_lsa *, struct ospf_lsa *); extern int ospf_flood_through(struct ospf *, struct ospf_neighbor *, @@ -36,6 +56,8 @@ extern void ospf_ls_retransmit_add(struct ospf_neighbor *, struct ospf_lsa *); extern void ospf_ls_retransmit_delete(struct ospf_neighbor *, struct ospf_lsa *); extern void ospf_ls_retransmit_clear(struct ospf_neighbor *); +extern void ospf_ls_retransmit_set_timer(struct ospf_neighbor *nbr); + extern struct ospf_lsa *ospf_ls_retransmit_lookup(struct ospf_neighbor *, struct ospf_lsa *); extern void ospf_ls_retransmit_delete_nbr_area(struct ospf_area *, diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 11ac7af7c9ed..803c36861dcd 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -542,6 +542,7 @@ static struct ospf_if_params *ospf_new_if_params(void) UNSET_IF_PARAM(oip, output_cost_cmd); UNSET_IF_PARAM(oip, transmit_delay); UNSET_IF_PARAM(oip, retransmit_interval); + UNSET_IF_PARAM(oip, retransmit_window); UNSET_IF_PARAM(oip, passive_interface); UNSET_IF_PARAM(oip, v_hello); UNSET_IF_PARAM(oip, fast_hello); @@ -599,6 +600,7 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr) if (!OSPF_IF_PARAM_CONFIGURED(oip, output_cost_cmd) && !OSPF_IF_PARAM_CONFIGURED(oip, transmit_delay) && !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_interval) && + !OSPF_IF_PARAM_CONFIGURED(oip, retransmit_window) && !OSPF_IF_PARAM_CONFIGURED(oip, passive_interface) && !OSPF_IF_PARAM_CONFIGURED(oip, v_hello) && !OSPF_IF_PARAM_CONFIGURED(oip, fast_hello) && @@ -695,6 +697,9 @@ int ospf_if_new_hook(struct interface *ifp) IF_DEF_PARAMS(ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; + SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_window); + IF_DEF_PARAMS(ifp)->retransmit_window = OSPF_RETRANSMIT_WINDOW_DEFAULT; + SET_IF_PARAM(IF_DEF_PARAMS(ifp), priority); IF_DEF_PARAMS(ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT; diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 45d0b7943a24..a944847b5d9b 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -47,6 +47,8 @@ struct ospf_if_params { output_cost_cmd); /* Command Interface Output Cost */ DECLARE_IF_PARAM(uint32_t, retransmit_interval); /* Retransmission Interval */ + DECLARE_IF_PARAM(uint32_t, + retransmit_window); /* Retransmission Window */ DECLARE_IF_PARAM(uint8_t, passive_interface); /* OSPF Interface is passive: no sending or receiving (no need to @@ -296,6 +298,7 @@ struct ospf_interface { uint32_t ls_ack_out; /* LS Ack message output count. */ uint32_t discarded; /* discarded input count by error. */ uint32_t state_change; /* Number of status change. */ + uint32_t ls_rxmt_lsa; /* Number of LSAs retransmitted. */ uint32_t full_nbrs; diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c index 0111c4924ec2..d1b3eb0d354b 100644 --- a/ospfd/ospf_lsdb.c +++ b/ospfd/ospf_lsdb.c @@ -34,6 +34,59 @@ void ospf_lsdb_init(struct ospf_lsdb *lsdb) lsdb->type[i].db = route_table_init(); } +static struct route_node * +ospf_lsdb_linked_node_create(route_table_delegate_t *delegate, + struct route_table *table) +{ + struct ospf_lsdb_linked_node *node; + + node = XCALLOC(MTYPE_OSPF_LSDB_NODE, + sizeof(struct ospf_lsdb_linked_node)); + + return (struct route_node *)node; +} + +static void ospf_lsdb_linked_node_destroy(route_table_delegate_t *delegate, + struct route_table *table, + struct route_node *node) +{ + struct ospf_lsdb_linked_node *lsdb_linked_node = + (struct ospf_lsdb_linked_node *)node; + + XFREE(MTYPE_OSPF_LSDB_NODE, lsdb_linked_node); +} + +static route_table_delegate_t ospf_lsdb_linked_table_delegate = { + .create_node = ospf_lsdb_linked_node_create, + .destroy_node = ospf_lsdb_linked_node_destroy, +}; + +void ospf_lsdb_linked_init(struct ospf_lsdb *lsdb) +{ + int i; + + for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) + lsdb->type[i].db = route_table_init_with_delegate( + &ospf_lsdb_linked_table_delegate); +} + +struct ospf_lsdb_linked_node *ospf_lsdb_linked_lookup(struct ospf_lsdb *lsdb, + struct ospf_lsa *lsa) +{ + struct ospf_lsdb_linked_node *lsdb_linked_node; + struct route_table *table; + struct prefix_ls lp; + + table = lsdb->type[lsa->data->type].db; + ls_prefix_set(&lp, lsa); + lsdb_linked_node = (struct ospf_lsdb_linked_node *) + route_node_lookup(table, (struct prefix *)&lp); + if (lsdb_linked_node) + route_unlock_node((struct route_node *)lsdb_linked_node); + + return lsdb_linked_node; +} + void ospf_lsdb_free(struct ospf_lsdb *lsdb) { ospf_lsdb_cleanup(lsdb); diff --git a/ospfd/ospf_lsdb.h b/ospfd/ospf_lsdb.h index bf295ca8306a..e5e3be8baa0b 100644 --- a/ospfd/ospf_lsdb.h +++ b/ospfd/ospf_lsdb.h @@ -7,6 +7,9 @@ #ifndef _ZEBRA_OSPF_LSDB_H #define _ZEBRA_OSPF_LSDB_H +#include "prefix.h" +#include "table.h" + /* OSPF LSDB structure. */ struct ospf_lsdb { struct { @@ -43,9 +46,29 @@ struct ospf_lsdb { #define AREA_LSDB(A,T) ((A)->lsdb->type[(T)].db) #define AS_LSDB(O,T) ((O)->lsdb->type[(T)].db) +/* + * Alternate route node structure for LSDB nodes linked to + * list elements. + */ +struct ospf_lsdb_linked_node { + /* + * Caution these must be the very first fields + */ + ROUTE_NODE_FIELDS + + /* + * List entry on an LSA list, e.g., a neighbor + * retransmission list. + */ + struct ospf_lsa_list_entry *lsa_list_entry; +}; + /* OSPF LSDB related functions. */ extern struct ospf_lsdb *ospf_lsdb_new(void); extern void ospf_lsdb_init(struct ospf_lsdb *); +extern void ospf_lsdb_linked_init(struct ospf_lsdb *lsdb); +extern struct ospf_lsdb_linked_node * +ospf_lsdb_linked_lookup(struct ospf_lsdb *lsdb, struct ospf_lsa *lsa); extern void ospf_lsdb_free(struct ospf_lsdb *); extern void ospf_lsdb_cleanup(struct ospf_lsdb *); extern void ls_prefix_set(struct prefix_ls *lp, struct ospf_lsa *lsa); diff --git a/ospfd/ospf_memory.c b/ospfd/ospf_memory.c index 9854c8cae80b..478af323d30b 100644 --- a/ospfd/ospf_memory.c +++ b/ospfd/ospf_memory.c @@ -45,3 +45,5 @@ DEFINE_MTYPE(OSPFD, OSPF_GR_HELPER, "OSPF Graceful Restart Helper"); DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_RT_AGGR, "OSPF External Route Summarisation"); DEFINE_MTYPE(OSPFD, OSPF_P_SPACE, "OSPF TI-LFA P-Space"); DEFINE_MTYPE(OSPFD, OSPF_Q_SPACE, "OSPF TI-LFA Q-Space"); +DEFINE_MTYPE(OSPFD, OSPF_LSA_LIST, "OSPF LSA List"); +DEFINE_MTYPE(OSPFD, OSPF_LSDB_NODE, "OSPF LSDB Linked Node"); diff --git a/ospfd/ospf_memory.h b/ospfd/ospf_memory.h index d11b69abb01b..e2139b517b17 100644 --- a/ospfd/ospf_memory.h +++ b/ospfd/ospf_memory.h @@ -44,5 +44,7 @@ DECLARE_MTYPE(OSPF_GR_HELPER); DECLARE_MTYPE(OSPF_EXTERNAL_RT_AGGR); DECLARE_MTYPE(OSPF_P_SPACE); DECLARE_MTYPE(OSPF_Q_SPACE); +DECLARE_MTYPE(OSPF_LSA_LIST); +DECLARE_MTYPE(OSPF_LSDB_NODE); #endif /* _QUAGGA_OSPF_MEMORY_H */ diff --git a/ospfd/ospf_neighbor.c b/ospfd/ospf_neighbor.c index d47d5816057a..2514fc0ab3b9 100644 --- a/ospfd/ospf_neighbor.c +++ b/ospfd/ospf_neighbor.c @@ -68,7 +68,7 @@ struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi) nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait); nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval); nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval); - nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval); + nbr->v_ls_rxmt = OSPF_IF_PARAM(oi, retransmit_interval); nbr->priority = -1; /* DD flags. */ @@ -80,8 +80,10 @@ struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi) nbr->nbr_nbma = NULL; ospf_lsdb_init(&nbr->db_sum); - ospf_lsdb_init(&nbr->ls_rxmt); + + ospf_lsdb_linked_init(&nbr->ls_rxmt); ospf_lsdb_init(&nbr->ls_req); + ospf_lsa_list_init(&nbr->ls_rxmt_list); nbr->crypt_seqnum = 0; @@ -128,7 +130,7 @@ void ospf_nbr_free(struct ospf_neighbor *nbr) EVENT_OFF(nbr->t_inactivity); EVENT_OFF(nbr->t_db_desc); EVENT_OFF(nbr->t_ls_req); - EVENT_OFF(nbr->t_ls_upd); + EVENT_OFF(nbr->t_ls_rxmt); /* Cancel all events. */ /* Thread lookup cost would be negligible. */ event_cancel_event(master, nbr); diff --git a/ospfd/ospf_neighbor.h b/ospfd/ospf_neighbor.h index 07d095f03d1b..0e041f9e6df2 100644 --- a/ospfd/ospf_neighbor.h +++ b/ospfd/ospf_neighbor.h @@ -9,6 +9,7 @@ #include #include +#include /* Neighbor Data Structure */ struct ospf_neighbor { @@ -44,6 +45,7 @@ struct ospf_neighbor { /* LSA data. */ struct ospf_lsdb ls_rxmt; + struct ospf_lsa_list_head ls_rxmt_list; struct ospf_lsdb db_sum; struct ospf_lsdb ls_req; struct ospf_lsa *ls_req_last; @@ -54,13 +56,13 @@ struct ospf_neighbor { uint32_t v_inactivity; uint32_t v_db_desc; uint32_t v_ls_req; - uint32_t v_ls_upd; + uint32_t v_ls_rxmt; /* Threads. */ struct event *t_inactivity; struct event *t_db_desc; struct event *t_ls_req; - struct event *t_ls_upd; + struct event *t_ls_rxmt; struct event *t_hello_reply; /* NBMA configured neighbour */ @@ -71,6 +73,7 @@ struct ospf_neighbor { struct timeval ts_last_regress; /* last regressive NSM change */ const char *last_regress_str; /* Event which last regressed NSM */ uint32_t state_change; /* NSM state change counter */ + uint32_t ls_rxmt_lsa; /* Number of LSAs retransmited. */ /* BFD information */ struct bfd_session_params *bfd_session; diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index c466ddcc6f90..079a1fa55ed3 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -112,18 +112,16 @@ static void nsm_timer_set(struct ospf_neighbor *nbr) case NSM_Init: case NSM_TwoWay: EVENT_OFF(nbr->t_db_desc); - EVENT_OFF(nbr->t_ls_upd); + EVENT_OFF(nbr->t_ls_rxmt); EVENT_OFF(nbr->t_ls_req); break; case NSM_ExStart: OSPF_NSM_TIMER_ON(nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc); - EVENT_OFF(nbr->t_ls_upd); + EVENT_OFF(nbr->t_ls_rxmt); EVENT_OFF(nbr->t_ls_req); break; case NSM_Exchange: - OSPF_NSM_TIMER_ON(nbr->t_ls_upd, ospf_ls_upd_timer, - nbr->v_ls_upd); if (!IS_SET_DD_MS(nbr->dd_flags)) EVENT_OFF(nbr->t_db_desc); break; diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 87aaccad920b..86f877b6214e 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -292,54 +292,66 @@ void ospf_ls_req_event(struct ospf_neighbor *nbr) event_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req); } -/* Cyclic timer function. Fist registered in ospf_nbr_new () in - ospf_neighbor.c */ -void ospf_ls_upd_timer(struct event *thread) +/* + * OSPF neighbor link state retransmission timer handler. Unicast + * unacknowledged LSAs to the neigbhors. + */ +void ospf_ls_rxmt_timer(struct event *thread) { struct ospf_neighbor *nbr; + int retransmit_interval, retransmit_window, rxmt_lsa_count = 0; nbr = EVENT_ARG(thread); - nbr->t_ls_upd = NULL; + nbr->t_ls_rxmt = NULL; + retransmit_interval = nbr->v_ls_rxmt; + retransmit_window = OSPF_IF_PARAM(nbr->oi, retransmit_window); /* Send Link State Update. */ if (ospf_ls_retransmit_count(nbr) > 0) { + struct ospf_lsa_list_entry *ls_rxmt_list_entry; + struct timeval current_time, latest_rxmt_time, next_rxmt_time; + struct timeval rxmt_interval = { retransmit_interval, 0 }; + struct timeval rxmt_window; struct list *update; - struct ospf_lsdb *lsdb; - int i; - int retransmit_interval; - retransmit_interval = - OSPF_IF_PARAM(nbr->oi, retransmit_interval); + /* + * Set the retransmission window based on the configured value + * in milliseconds. + */ + rxmt_window.tv_sec = retransmit_window / 1000; + rxmt_window.tv_usec = (retransmit_window % 1000) * 1000; + + /* + * Calculate the latest retransmit time for LSAs transmited in + * this timer pass by adding the retransmission window to the + * current time. Calculate the next retransmission time by adding + * the retransmit interval to the current time. + */ + monotime(¤t_time); + timeradd(¤t_time, &rxmt_window, &latest_rxmt_time); + timeradd(¤t_time, &rxmt_interval, &next_rxmt_time); - lsdb = &nbr->ls_rxmt; update = list_new(); + while ((ls_rxmt_list_entry = + ospf_lsa_list_first(&nbr->ls_rxmt_list))) { + if (timercmp(&ls_rxmt_list_entry->list_entry_time, + &latest_rxmt_time, >)) + break; - for (i = OSPF_MIN_LSA; i < OSPF_MAX_LSA; i++) { - struct route_table *table = lsdb->type[i].db; - struct route_node *rn; - - for (rn = route_top(table); rn; rn = route_next(rn)) { - struct ospf_lsa *lsa; - - if ((lsa = rn->info) != NULL) { - /* Don't retransmit an LSA if we - received it within - the last RxmtInterval seconds - this - is to allow the - neighbour a chance to acknowledge the - LSA as it may - have ben just received before the - retransmit timer - fired. This is a small tweak to what - is in the RFC, - but it will cut out out a lot of - retransmit traffic - - MAG */ - if (monotime_since(&lsa->tv_recv, NULL) - >= retransmit_interval * 1000000LL) - listnode_add(update, rn->info); - } - } + listnode_add(update, ls_rxmt_list_entry->lsa); + rxmt_lsa_count++; + + /* + * Set the next retransmit time for the LSA and move it + * to the end of the neighbor's retransmission list. + */ + ls_rxmt_list_entry->list_entry_time = next_rxmt_time; + ospf_lsa_list_del(&nbr->ls_rxmt_list, + ls_rxmt_list_entry); + ospf_lsa_list_add_tail(&nbr->ls_rxmt_list, + ls_rxmt_list_entry); + nbr->ls_rxmt_lsa++; + nbr->oi->ls_rxmt_lsa++; } if (listcount(update) > 0) @@ -348,8 +360,13 @@ void ospf_ls_upd_timer(struct event *thread) list_delete(&update); } + if (IS_DEBUG_OSPF_EVENT) + zlog_debug("RXmtL(%lu) NBR(%pI4(%s)) timer event - sent %u LSAs", + ospf_ls_retransmit_count(nbr), &nbr->router_id, + ospf_get_name(nbr->oi->ospf), rxmt_lsa_count); + /* Set LS Update retransmission timer. */ - OSPF_NSM_TIMER_ON(nbr->t_ls_upd, ospf_ls_upd_timer, nbr->v_ls_upd); + ospf_ls_retransmit_set_timer(nbr); } void ospf_ls_ack_timer(struct event *thread) diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 234738979e95..2c9dba6c8819 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -140,7 +140,7 @@ extern void ospf_ls_ack_send_delayed(struct ospf_interface *); extern void ospf_ls_retransmit(struct ospf_interface *, struct ospf_lsa *); extern void ospf_ls_req_event(struct ospf_neighbor *); -extern void ospf_ls_upd_timer(struct event *thread); +extern void ospf_ls_rxmt_timer(struct event *thread); extern void ospf_ls_ack_timer(struct event *thread); extern void ospf_poll_timer(struct event *thread); extern void ospf_hello_reply_timer(struct event *thread); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 3a11b2123210..7a7a684dd6f6 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -815,6 +815,7 @@ struct ospf_vl_config_data { int del_keychain; int hello_interval; /* Obvious what these are... */ int retransmit_interval; + int retransmit_window; int transmit_delay; int dead_interval; }; @@ -957,6 +958,12 @@ static int ospf_vl_set_timers(struct ospf_vl_data *vl_data, vl_config->retransmit_interval; } + if (vl_config->retransmit_window) { + SET_IF_PARAM(IF_DEF_PARAMS(ifp), retransmit_window); + IF_DEF_PARAMS(ifp)->retransmit_window = + vl_config->retransmit_window; + } + if (vl_config->transmit_delay) { SET_IF_PARAM(IF_DEF_PARAMS(ifp), transmit_delay); IF_DEF_PARAMS(ifp)->transmit_delay = vl_config->transmit_delay; @@ -1012,14 +1019,16 @@ static int ospf_vl_set(struct ospf *ospf, struct ospf_vl_config_data *vl_config) "Use null authentication\n" \ "Use message-digest authentication\n" -#define VLINK_HELPSTR_TIME_PARAM \ - "Time between HELLO packets\n" \ - "Seconds\n" \ - "Time between retransmitting lost link state advertisements\n" \ - "Seconds\n" \ - "Link state transmit delay\n" \ - "Seconds\n" \ - "Interval time after which a neighbor is declared down\n" \ +#define VLINK_HELPSTR_TIME_PARAM \ + "Time between HELLO packets\n" \ + "Seconds\n" \ + "Time between retransmitting lost link state advertisements\n" \ + "Seconds\n" \ + "Window for LSA retransmit - Retransmit LSAs expiring in this window\n" \ + "Milliseconds\n" \ + "Link state transmit delay\n" \ + "Seconds\n" \ + "Interval time after which a neighbor is declared down\n" \ "Seconds\n" #define VLINK_HELPSTR_AUTH_SIMPLE \ @@ -1204,7 +1213,7 @@ DEFUN (no_ospf_area_vlink, DEFUN (ospf_area_vlink_intervals, ospf_area_vlink_intervals_cmd, - "area virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|transmit-delay (1-65535)|dead-interval (1-65535)}", + "area virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|retransmit-window (20-10000)|transmit-delay (1-65535)|dead-interval (1-65535)}", VLINK_HELPSTR_IPADDR VLINK_HELPSTR_TIME_PARAM) { @@ -1236,6 +1245,9 @@ DEFUN (ospf_area_vlink_intervals, else if (strmatch(argv[idx]->text, "retransmit-interval")) vl_config.retransmit_interval = strtol(argv[++idx]->arg, NULL, 10); + else if (strmatch(argv[idx]->text, "retransmit-window")) + vl_config.retransmit_window = strtol(argv[++idx]->arg, + NULL, 10); else if (strmatch(argv[idx]->text, "transmit-delay")) vl_config.transmit_delay = strtol(argv[++idx]->arg, NULL, 10); @@ -1250,7 +1262,7 @@ DEFUN (ospf_area_vlink_intervals, DEFUN (no_ospf_area_vlink_intervals, no_ospf_area_vlink_intervals_cmd, - "no area virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|transmit-delay (1-65535)|dead-interval (1-65535)}", + "no area virtual-link A.B.C.D {hello-interval (1-65535)|retransmit-interval (1-65535)|retransmit-window (20-1000)|transmit-delay (1-65535)|dead-interval (1-65535)}", NO_STR VLINK_HELPSTR_IPADDR VLINK_HELPSTR_TIME_PARAM) @@ -1282,6 +1294,9 @@ DEFUN (no_ospf_area_vlink_intervals, else if (strmatch(argv[idx]->text, "retransmit-interval")) vl_config.retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT; + else if (strmatch(argv[idx]->text, "retransmit-window")) + vl_config.retransmit_window = + OSPF_RETRANSMIT_WINDOW_DEFAULT; else if (strmatch(argv[idx]->text, "transmit-delay")) vl_config.transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT; else if (strmatch(argv[idx]->text, "dead-interval")) @@ -3846,6 +3861,10 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, json_object_int_add( json_interface_sub, "timerRetransmitSecs", OSPF_IF_PARAM(oi, retransmit_interval)); + json_object_int_add(json_interface_sub, + "timerRetransmitWindowMsecs", + OSPF_IF_PARAM(oi, + retransmit_window)); } else { vty_out(vty, " Timer intervals configured,"); vty_out(vty, " Hello "); @@ -3964,6 +3983,16 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, "nbrFilterPrefixList", "N/A"); } + + /* Non-Traffic interface counters + */ + if (use_json) + json_object_int_add(json_interface_sub, + "lsaRetransmissions", + oi->ls_rxmt_lsa); + else + vty_out(vty, " LSA retransmissions: %u\n", + oi->ls_rxmt_lsa); } } @@ -5177,12 +5206,20 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, lookup_msg(ospf_ism_state_msg, ospf_nbr_ism_state(nbr), NULL)); } + /* Show state changes. */ if (use_json) json_object_int_add(json_neigh, "stateChangeCounter", nbr->state_change); else - vty_out(vty, " %d state changes\n", nbr->state_change); + vty_out(vty, " %d state changes\n", nbr->state_change); + + /* Show LSA retransmissions. */ + if (use_json) + json_object_int_add(json_neigh, "lsaRetransmissions", + nbr->ls_rxmt_lsa); + else + vty_out(vty, " %u LSA retransmissions\n", nbr->ls_rxmt_lsa); if (nbr->ts_last_progress.tv_sec || nbr->ts_last_progress.tv_usec) { struct timeval res; @@ -5231,7 +5268,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, if (DR(oi).s_addr == INADDR_ANY) { if (!use_json) vty_out(vty, - " No designated router on this network\n"); + " No designated router on this network\n"); } else { nbr_dr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi)); if (nbr_dr) { @@ -5250,14 +5287,14 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, if (nbr_bdr == NULL) { if (!use_json) vty_out(vty, - " No backup designated router on this network\n"); + " No backup designated router on this network\n"); } else { if (use_json) json_object_string_addf(json_neigh, "routerDesignatedBackupId", "%pI4", &nbr_bdr->router_id); else - vty_out(vty, " BDR is %pI4\n", &nbr_bdr->router_id); + vty_out(vty, " BDR is %pI4\n", &nbr_bdr->router_id); } /* Show options. */ @@ -5347,7 +5384,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, /* Show Link State Update Retransmission thread. */ if (use_json) { - if (nbr->t_ls_upd != NULL) + if (nbr->t_ls_rxmt != NULL) json_object_string_add( json_neigh, "threadLinkStateUpdateRetransmission", @@ -5355,7 +5392,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty, } else vty_out(vty, " Thread Link State Update Retransmission %s\n\n", - nbr->t_ls_upd != NULL ? "on" : "off"); + nbr->t_ls_rxmt != NULL ? "on" : "off"); if (!use_json) { vty_out(vty, " Graceful restart Helper info:\n"); @@ -7993,7 +8030,7 @@ static void ospf_nbr_timer_update(struct ospf_interface *oi) nbr->v_inactivity = OSPF_IF_PARAM(oi, v_wait); nbr->v_db_desc = OSPF_IF_PARAM(oi, retransmit_interval); nbr->v_ls_req = OSPF_IF_PARAM(oi, retransmit_interval); - nbr->v_ls_upd = OSPF_IF_PARAM(oi, retransmit_interval); + nbr->v_ls_rxmt = OSPF_IF_PARAM(oi, retransmit_interval); } } @@ -8728,6 +8765,40 @@ DEFUN_HIDDEN (no_ospf_retransmit_interval, return no_ip_ospf_retransmit_interval(self, vty, argc, argv); } +DEFPY(ip_ospf_retransmit_window, ip_ospf_retransmit_window_addr_cmd, + "[no] ip ospf retransmit-window ![(20-1000)]$retransmit-window [A.B.C.D]$ip_addr", NO_STR + "IP Information\n" + "OSPF interface commands\n" + "Window for LSA retransmit - Retransmit LSAs expiring in this window\n" + "Milliseconds\n" + "Address of interface\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct ospf_if_params *params; + + params = IF_DEF_PARAMS(ifp); + + if (ip_addr.s_addr != INADDR_ANY) { + params = ospf_get_if_params(ifp, ip_addr); + ospf_if_update_params(ifp, ip_addr); + } + + if (no) { + UNSET_IF_PARAM(params, retransmit_window); + params->retransmit_window = OSPF_RETRANSMIT_WINDOW_DEFAULT; + } else { + SET_IF_PARAM(params, retransmit_window); + params->retransmit_window = retransmit_window; + } + + /* + * There is nothing to do when the retransmit-window changes, any + * change will take effect the next time the interface LSA retransmision + * timer expires. + */ + return CMD_SUCCESS; +} + DEFPY (ip_ospf_gr_hdelay, ip_ospf_gr_hdelay_cmd, "ip ospf graceful-restart hello-delay (1-1800)", @@ -12210,6 +12281,17 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf) vty_out(vty, "\n"); } + /* Retransmit Window print. */ + if (OSPF_IF_PARAM_CONFIGURED(params, retransmit_window) && + params->retransmit_window != + OSPF_RETRANSMIT_WINDOW_DEFAULT) { + vty_out(vty, " ip ospf retransmit-window %u", + params->retransmit_window); + if (params != IF_DEF_PARAMS(ifp) && rn) + vty_out(vty, " %pI4", &rn->p.u.prefix4); + vty_out(vty, "\n"); + } + /* Transmit Delay print. */ if (OSPF_IF_PARAM_CONFIGURED(params, transmit_delay) && params->transmit_delay @@ -12567,19 +12649,22 @@ static int config_write_virtual_link(struct vty *vty, struct ospf *ospf) oi = vl_data->vl_oi; /* timers */ - if (OSPF_IF_PARAM(oi, v_hello) - != OSPF_HELLO_INTERVAL_DEFAULT - || OSPF_IF_PARAM(oi, v_wait) - != OSPF_ROUTER_DEAD_INTERVAL_DEFAULT - || OSPF_IF_PARAM(oi, retransmit_interval) - != OSPF_RETRANSMIT_INTERVAL_DEFAULT - || OSPF_IF_PARAM(oi, transmit_delay) - != OSPF_TRANSMIT_DELAY_DEFAULT) + if (OSPF_IF_PARAM(oi, v_hello) != + OSPF_HELLO_INTERVAL_DEFAULT || + OSPF_IF_PARAM(oi, v_wait) != + OSPF_ROUTER_DEAD_INTERVAL_DEFAULT || + OSPF_IF_PARAM(oi, retransmit_interval) != + OSPF_RETRANSMIT_INTERVAL_DEFAULT || + OSPF_IF_PARAM(oi, retransmit_window) != + OSPF_RETRANSMIT_WINDOW_DEFAULT || + OSPF_IF_PARAM(oi, transmit_delay) != + OSPF_TRANSMIT_DELAY_DEFAULT) vty_out(vty, - " area %s virtual-link %pI4 hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n", + " area %s virtual-link %pI4 hello-interval %d retransmit-interval %d retransmit-window %d transmit-delay %d dead-interval %d\n", buf, &vl_data->vl_peer, OSPF_IF_PARAM(oi, v_hello), OSPF_IF_PARAM(oi, retransmit_interval), + OSPF_IF_PARAM(oi, retransmit_window), OSPF_IF_PARAM(oi, transmit_delay), OSPF_IF_PARAM(oi, v_wait)); else @@ -13112,6 +13197,9 @@ static void ospf_vty_if_init(void) install_element(INTERFACE_NODE, &no_ip_ospf_retransmit_interval_addr_cmd); + /* "ip ospf retransmit-window" commands. */ + install_element(INTERFACE_NODE, &ip_ospf_retransmit_window_addr_cmd); + /* "ip ospf transmit-delay" commands. */ install_element(INTERFACE_NODE, &ip_ospf_transmit_delay_addr_cmd); install_element(INTERFACE_NODE, &no_ip_ospf_transmit_delay_addr_cmd); diff --git a/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref b/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref index f52b51d9d8b6..e4e329011163 100644 --- a/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref +++ b/tests/topotests/all_protocol_startup/r1/show_ip_ospf_interface.ref @@ -11,6 +11,7 @@ r1-eth0 is up Hello due in XX.XXXs Neighbor Count is 0, Adjacent neighbor count is 0 Graceful Restart hello delay: 10s + LSA retransmissions: 0 r1-eth3 is up ifindex X, MTU 1500 bytes, BW XX Mbit Internet Address 192.168.3.1/26, Broadcast 192.168.3.63, Area 0.0.0.0 @@ -24,3 +25,4 @@ r1-eth3 is up Hello due in XX.XXXs Neighbor Count is 0, Adjacent neighbor count is 0 Graceful Restart hello delay: 10s + LSA retransmissions: 0 diff --git a/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf index cb4538c0e342..89f255bb44ea 100644 --- a/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r1/frr-p2mp.conf @@ -1,4 +1,10 @@ ! +!log file ospfd.log debug +! debug ospf event +! debug ospf client +! debug ospf lsa +! debug ospf packet all + hostname r1 password zebra log file /tmp/r1-frr.log diff --git a/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf index 0ca8aec3bf38..429330987e06 100644 --- a/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r2/frr-p2mp.conf @@ -1,4 +1,10 @@ ! +!log file ospfd.log debug +! debug ospf event +! debug ospf client +! debug ospf lsa +! debug ospf packet all +! hostname r2 password zebra log file /tmp/r1-frr.log diff --git a/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf index 41ea70d4439c..eada78450e81 100644 --- a/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r3/frr-p2mp.conf @@ -1,4 +1,10 @@ ! +!log file ospfd.log debug +! debug ospf event +! debug ospf client +! debug ospf lsa +! debug ospf packet all +! hostname r3 password zebra log file /tmp/r1-frr.log diff --git a/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf b/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf index 21fa9c72f9a9..3146ea095762 100644 --- a/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf +++ b/tests/topotests/ospf_p2mp/r4/frr-p2mp.conf @@ -1,4 +1,10 @@ ! +!log file ospfd.log debug +! debug ospf event +! debug ospf client +! debug ospf lsa +! debug ospf packet all +! hostname r4 password zebra log file /tmp/r1-frr.log diff --git a/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py b/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py index d52c8147fe48..455c737f0d71 100644 --- a/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py +++ b/tests/topotests/ospf_p2mp/test_ospf_p2mp_broadcast.py @@ -9,6 +9,7 @@ import os import sys +from time import sleep from functools import partial import pytest @@ -113,7 +114,9 @@ def teardown_module(): tgen.stop_topology() -def verify_p2mp_interface(tgen, router, nbr_cnt, nbr_adj_cnt, nbr_filter): +def verify_p2mp_interface( + tgen, router, nbr_cnt, nbr_adj_cnt, delay_reflood, nbr_filter +): "Verify the P2MP Configuration and interface settings" topo_router = tgen.gears[router] @@ -147,7 +150,7 @@ def verify_p2mp_interface(tgen, router, nbr_cnt, nbr_adj_cnt, nbr_filter): "nbrCount": nbr_cnt, "nbrAdjacentCount": nbr_adj_cnt, "prefixSuppression": False, - "p2mpDelayReflood": False, + "p2mpDelayReflood": delay_reflood, "nbrFilterPrefixList": nbr_filter, } } @@ -280,7 +283,7 @@ def test_p2mp_broadcast_interface(): pytest.skip("Skipped because of router(s) failure") step("Verify router r1 interface r1-eth0 p2mp configuration") - verify_p2mp_interface(tgen, "r1", 3, 3, "N/A") + verify_p2mp_interface(tgen, "r1", 3, 3, False, "N/A") step("Verify router r1 p2mp interface r1-eth0 neighbors") verify_p2mp_neighbor( @@ -305,7 +308,7 @@ def test_p2mp_broadcast_interface(): step("Verify router r1 interface r1-eth0 p2mp configuration application") r1.vtysh_cmd("conf t\ninterface r1-eth0\nip ospf network point-to-multipoint") - verify_p2mp_interface(tgen, "r1", 3, 3, "N/A") + verify_p2mp_interface(tgen, "r1", 3, 3, False, "N/A") step("Verify restablishment of r1-eth0 p2mp neighbors") verify_p2mp_neighbor( @@ -324,14 +327,14 @@ def test_p2mp_broadcast_interface(): verify_p2mp_route(tgen, "r1", "10.1.4.0/24", 24, "10.1.0.4", "r1-eth0") -def test_p2mp_broadcast_neighbor_filter(): +def p2mp_broadcast_neighbor_filter_common(delay_reflood): tgen = get_topogen() if tgen.routers_have_failure(): pytest.skip("Skipped because of router(s) failure") step("Verify router r1 interface r1-eth0 p2mp configuration") - verify_p2mp_interface(tgen, "r1", 3, 3, "N/A") + verify_p2mp_interface(tgen, "r1", 3, 3, delay_reflood, "N/A") step("Verify router r1 p2mp interface r1-eth0 neighbors") verify_p2mp_neighbor( @@ -362,7 +365,7 @@ def test_p2mp_broadcast_neighbor_filter(): assert neighbor_filter_cfg == " ip ospf neighbor-filter nbr-filter", assertmsg step("Verify non-existent neighbor-filter is not applied to r1 interfaces") - verify_p2mp_interface(tgen, "r1", 3, 3, "N/A") + verify_p2mp_interface(tgen, "r1", 3, 3, delay_reflood, "N/A") step("Add nbr-filter prefix-list configuration to r1") r1.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 200 permit any") @@ -370,7 +373,7 @@ def test_p2mp_broadcast_neighbor_filter(): step( "Verify neighbor-filter is now applied to r1 interface and neighbors still adjacent" ) - verify_p2mp_interface(tgen, "r1", 3, 3, "nbr-filter") + verify_p2mp_interface(tgen, "r1", 3, 3, delay_reflood, "nbr-filter") step("Add nbr-filter prefix-list configuration to block r4") r1.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 10 deny 10.1.0.4/32") @@ -378,7 +381,7 @@ def test_p2mp_broadcast_neighbor_filter(): step( "Verify neighbor-filter is now applied to r1 interface and r4 is no longer adjacent" ) - verify_p2mp_interface(tgen, "r1", 2, 2, "nbr-filter") + verify_p2mp_interface(tgen, "r1", 2, 2, delay_reflood, "nbr-filter") verify_p2mp_neighbor_missing(tgen, "r1", "4.4.4.4") step("Verify route to r4 subnet is now through r2") @@ -390,7 +393,7 @@ def test_p2mp_broadcast_neighbor_filter(): step( "Verify neighbor-filter is now applied to r1 interface and r2 is no longer adjacent" ) - verify_p2mp_interface(tgen, "r1", 1, 1, "nbr-filter") + verify_p2mp_interface(tgen, "r1", 1, 1, delay_reflood, "nbr-filter") verify_p2mp_neighbor_missing(tgen, "r1", "2.2.2.2") step("Verify route to r4 and r2 subnet are now through r3") @@ -406,24 +409,105 @@ def test_p2mp_broadcast_neighbor_filter(): assert rc, assertmsg step("Verify interface neighbor-filter is removed and neighbors present") - verify_p2mp_interface(tgen, "r1", 3, 3, "N/A") + verify_p2mp_interface(tgen, "r1", 3, 3, delay_reflood, "N/A") step("Add neighbor filter configuration and verify neighbors are filtered") r1.vtysh_cmd("conf t\ninterface r1-eth0\nip ospf neighbor-filter nbr-filter") - verify_p2mp_interface(tgen, "r1", 1, 1, "nbr-filter") + verify_p2mp_interface(tgen, "r1", 1, 1, delay_reflood, "nbr-filter") verify_p2mp_neighbor_missing(tgen, "r1", "2.2.2.2") verify_p2mp_neighbor_missing(tgen, "r1", "4.4.4.4") step("Remove nbr-filter prefix-list configuration to block r2 and verify neighbor") r1.vtysh_cmd("conf t\nno ip prefix-list nbr-filter seq 20") - verify_p2mp_interface(tgen, "r1", 2, 2, "nbr-filter") + verify_p2mp_interface(tgen, "r1", 2, 2, delay_reflood, "nbr-filter") verify_p2mp_neighbor( tgen, "r1", "2.2.2.2", "Full/DROther", "10.1.0.2", "r1-eth0:10.1.0.1" ) step("Delete nbr-filter prefix-list and verify neighbors are present") r1.vtysh_cmd("conf t\nno ip prefix-list nbr-filter") - verify_p2mp_interface(tgen, "r1", 3, 3, "N/A") + verify_p2mp_interface(tgen, "r1", 3, 3, delay_reflood, "N/A") + + +def test_p2mp_broadcast_neighbor_filter(): + p2mp_broadcast_neighbor_filter_common(False) + + +def test_p2mp_broadcast_neighbor_filter_delay_reflood(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip("Skipped because of router(s) failure") + + step("Modify router r1 interface r1-eth0 p2mp delay-reflood configuration") + r1 = tgen.gears["r1"] + r1.vtysh_cmd( + "conf t\ninterface r1-eth0\nip ospf network point-to-multipoint delay-reflood" + ) + verify_p2mp_interface(tgen, "r1", 3, 3, True, "N/A") + + step("Modify router r2 interface r2-eth0 p2mp delay-reflood configuration") + r2 = tgen.gears["r2"] + r2.vtysh_cmd( + "conf t\ninterface r2-eth0\nip ospf network point-to-multipoint delay-reflood" + ) + + step("Modify router r3 interface r3-eth0 p2mp delay-reflood configuration") + r3 = tgen.gears["r3"] + r3.vtysh_cmd( + "conf t\ninterface r3-eth0\nip ospf network point-to-multipoint delay-reflood" + ) + + step("Modify router r4 interface r4-eth0 p2mp delay-reflood configuration") + r4 = tgen.gears["r4"] + r4.vtysh_cmd( + "conf t\ninterface r4-eth0\nip ospf network point-to-multipoint delay-reflood" + ) + + p2mp_broadcast_neighbor_filter_common(True) + + step("Recreate a partial P2MP mesh with neighbor filters") + step("Add nbr-filter prefix-list configuration to block r4") + r1.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 30 permit any") + r1.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 10 deny 10.1.0.3/32") + r1.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 20 deny 10.1.0.4/32") + r1.vtysh_cmd("conf t\ninterface r1-eth0\nip ospf neighbor-filter nbr-filter") + + r2.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 30 permit any") + r2.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 10 deny 10.1.0.4/32") + r2.vtysh_cmd("conf t\ninterface r2-eth0\nip ospf neighbor-filter nbr-filter") + + r3.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 30 permit any") + r3.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 10 deny 10.1.0.1/32") + r3.vtysh_cmd("conf t\ninterface r3-eth0\nip ospf neighbor-filter nbr-filter") + + r4.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 30 permit any") + r4.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 10 deny 10.1.0.1/32") + r4.vtysh_cmd("conf t\nip prefix-list nbr-filter seq 20 deny 10.1.0.2/32") + r4.vtysh_cmd("conf t\ninterface r4-eth0\nip ospf neighbor-filter nbr-filter") + + step( + "Add redistribution and spaced static routes to r1 to test delay flood retransmission" + ) + r1.vtysh_cmd("conf t\nrouter ospf\nredistribute static") + r1.vtysh_cmd("conf t\nip route 20.1.1.1/32 null0") + sleep(1) + r1.vtysh_cmd("conf t\nip route 20.1.1.2/32 null0") + sleep(1) + r1.vtysh_cmd("conf t\nip route 20.1.1.3/32 null0") + sleep(1) + r1.vtysh_cmd("conf t\nip route 20.1.1.4/32 null0") + sleep(1) + r1.vtysh_cmd("conf t\nip route 20.1.1.5/32 null0") + sleep(1) + + step( + "Verify the routes are installed on r1 with delay-reflood in P2MP partial mesh" + ) + verify_p2mp_route(tgen, "r4", "20.1.1.1/32", 32, "10.1.0.3", "r4-eth0") + verify_p2mp_route(tgen, "r4", "20.1.1.2/32", 32, "10.1.0.3", "r4-eth0") + verify_p2mp_route(tgen, "r4", "20.1.1.3/32", 32, "10.1.0.3", "r4-eth0") + verify_p2mp_route(tgen, "r4", "20.1.1.4/32", 32, "10.1.0.3", "r4-eth0") def test_memory_leak(): From e4d843b438ae7cbae89ae47af0754fb1db153c6c Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 18 Jun 2024 17:21:49 -0700 Subject: [PATCH 326/472] zebra: fix evpn mh bond member proto reinstall In case of EVPN MH bond, a member port going in protodown state due to external reason (one case being linkflap), frr updates the state correctly but upon manually clearing external reason trigger FRR to reinstate protodown without any reason code. Fix is to ensure if the protodown reason was external and new state is to have protodown 'off' then do no reinstate protodown. Ticket: #3947432 Testing: switch:#ip link show swp1 4: swp1: mtu 9216 qdisc pfifo_fast master bond1 state DOWN mode DEFAULT group default qlen 1000 link/ether 1c:34:da:2c:aa:68 brd ff:ff:ff:ff:ff:ff protodown on protodown_reason switch:#ip link set swp1 protodown off protodown_reason linkflap off switch:#ip link show swp1 4: swp1: mtu 9216 qdisc pfifo_fast master bond1 state DOWN mode DEFAULT group default qlen 1000 link/ether 1c:34:da:2c:aa:68 brd ff:ff:ff:ff:ff:ff Signed-off-by: Chirag Shah --- zebra/interface.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/zebra/interface.c b/zebra/interface.c index b824977f9e13..f1f24cc29f16 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1656,8 +1656,10 @@ static void interface_if_protodown(struct interface *ifp, bool protodown, uint32_t rc_bitfield) { struct zebra_if *zif = ifp->info; - bool old_protodown; + bool old_protodown, reason_extern; + reason_extern = !!CHECK_FLAG(zif->protodown_rc, + ZEBRA_PROTODOWN_EXTERNAL); /* * Set our reason code to note it wasn't us. * If the reason we got from the kernel is ONLY frr though, don't @@ -1673,8 +1675,8 @@ static void interface_if_protodown(struct interface *ifp, bool protodown, return; if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_DPLANE) - zlog_debug("interface %s dplane change, protodown %s", - ifp->name, protodown ? "on" : "off"); + zlog_debug("interface %s dplane change, protodown %s curr reason_extern %u", + ifp->name, protodown ? "on" : "off", reason_extern); /* Set protodown, respectively */ COND_FLAG(zif->flags, ZIF_FLAG_PROTODOWN, protodown); @@ -1699,6 +1701,13 @@ static void interface_if_protodown(struct interface *ifp, bool protodown, return; } + if (!protodown && reason_extern) { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("bond member %s has protodown reason external and clear the reason, skip reinstall.", + ifp->name); + return; + } + if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "bond mbr %s reinstate protodown %s in the dplane", From d4390fc21795b09b84a6b95b1f8fa1ac2b3dcda9 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 20 Jun 2024 18:02:26 +0200 Subject: [PATCH 327/472] bgpd: fix do not use api.backup_nexthop in ZAPI message The backup_nexthop entry list has been populated by mistake, and should not. Fix this by reverting the introduced behavior. Fixes: 237ebf8d4503 ("bgpd: rework bgp_zebra_announce() function, separate nexthop handling") Signed-off-by: Philippe Guibert --- bgpd/bgp_zebra.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 73543f9fb44c..7f91e3149e0b 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1331,10 +1331,7 @@ static void bgp_zebra_announce_parse_nexthop( &nh_weight)) continue; } - if (CHECK_FLAG(info->flags, BGP_PATH_SELECTED)) - api_nh = &api->nexthops[*valid_nh_count]; - else - api_nh = &api->backup_nexthops[*valid_nh_count]; + api_nh = &api->nexthops[*valid_nh_count]; api_nh->srte_color = bgp_attr_get_color(info->attr); From 56c16ee529b546058c8d1fabbb701d8ed2fded75 Mon Sep 17 00:00:00 2001 From: Sindhu Parvathi Gopinathan Date: Wed, 19 Jun 2024 07:35:31 -0700 Subject: [PATCH 328/472] zebra: clear evpn dup-addr return error-msg when there is no vni clear evpn dup-addr cli returns error-msg for below conditions, - If evpn is not enabled & - If there is no VNI exists. supported command: ``` clear evpn dup-addr vni ``` Ticket: #3495573 Testing: bharat# clear evpn dup-addr vni all Error type: validation Error description: % EVPN not enabled bharat# clear evpn dup-addr vni 20 Error type: validation Error description: % VNI 20 does not exist Signed-off-by: Sindhu Parvathi Gopinathan's Signed-off-by: Chirag Shah --- zebra/zebra_nb_rpcs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/zebra/zebra_nb_rpcs.c b/zebra/zebra_nb_rpcs.c index 938193df2f2a..744ba620f22e 100644 --- a/zebra/zebra_nb_rpcs.c +++ b/zebra/zebra_nb_rpcs.c @@ -12,6 +12,8 @@ #include "zebra/zebra_router.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_vxlan.h" +#include "zebra/zebra_vxlan_if.h" +#include "zebra/zebra_evpn.h" /* * XPath: /frr-zebra:clear-evpn-dup-addr @@ -21,6 +23,11 @@ int clear_evpn_dup_addr_rpc(struct nb_cb_rpc_args *args) struct zebra_vrf *zvrf; int ret = NB_OK; + if (!is_evpn_enabled()) { + snprintf(args->errmsg, args->errmsg_len, + "%% EVPN not enabled\n"); + return NB_ERR_VALIDATION; + } zvrf = zebra_vrf_get_evpn(); if (yang_dnode_exists(args->input, "all-vnis")) { @@ -30,6 +37,12 @@ int clear_evpn_dup_addr_rpc(struct nb_cb_rpc_args *args) struct ipaddr host_ip = {.ipa_type = IPADDR_NONE}; struct ethaddr mac; + if (!zebra_evpn_lookup(vni)) { + snprintf(args->errmsg, args->errmsg_len, + "%% VNI %u does not exist\n", vni); + return NB_ERR_VALIDATION; + } + if (yang_dnode_exists(args->input, "mac-addr")) { yang_dnode_get_mac(&mac, args->input, "mac-addr"); ret = zebra_vxlan_clear_dup_detect_vni_mac(zvrf, vni, From f9d4d1626d47944715eb522af38909cc90a1d53c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 21 Jun 2024 11:32:05 +0200 Subject: [PATCH 329/472] tools/checkpatch: accept pim_* typedefs pimd uses "v4/v6 dispatch" typedefs. Don't complain about those in checkpatch. Signed-off-by: David Lamparter --- tools/checkpatch.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl index f52f1a161649..3e7abeda3962 100755 --- a/tools/checkpatch.pl +++ b/tools/checkpatch.pl @@ -4668,6 +4668,7 @@ sub process { # check for new typedefs, only function parameters and sparse annotations # make sense. if ($line =~ /\btypedef\s/ && + $line !~ /\btypedef.*\s(pim_[^\s]+|[^\s]+_pim)\s*;/ && $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && $line !~ /\b$typeTypedefs\b/ && From df723ccfb70e4c416bb74fc52cfc8b9dd1384314 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 6 Jun 2024 18:03:24 +0200 Subject: [PATCH 330/472] isisd: show isis route uses ttable for paths This is a preliminary commit, so that route paths are visible from json. Before: > IS-IS paths to level-1 routers that speak IPv6 > Vertex Type Metric Next-Hop Interface Parent > rt1 > 2001:db8:1000::1/128 IP6 internal 0 rt1(4) > rt2 TE-IS 10 rt2 eth-rt2 rt1(4) > rt3 TE-IS 10 rt3 eth-rt3 rt1(4) > 2001:db8:1000::2/128 IP6 internal 20 rt2 eth-rt2 rt2(4) > 2001:db8:1000::3/128 IP6 internal 20 rt3 eth-rt3 rt3(4) After: > Vertex Type Metric Next-Hop Interface Parent > ------------------------------------------------------------------------- > rt1 > 2001:db8:1000::1/128 IP6 internal 0 rt1(4) > rt2 TE-IS 10 rt2 eth-rt2 rt1(4) > rt3 TE-IS 10 rt3 eth-rt3 rt1(4) > 2001:db8:1000::2/128 IP6 internal 20 rt2 eth-rt2 rt2(4) > 2001:db8:1000::3/128 IP6 internal 20 rt3 eth-rt3 rt3(4) Signed-off-by: Philippe Guibert --- isisd/isis_spf.c | 79 +- tests/isisd/test_isis_spf.refout | 4266 ++++++++++++++++-------------- 2 files changed, 2303 insertions(+), 2042 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 81201023d657..4892479ac2d0 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2232,16 +2232,30 @@ static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue, struct listnode *node; struct isis_vertex *vertex; char buff[VID2STR_BUFFER]; + char vertex_name[VID2STR_BUFFER]; + char vertex_typestr[VID2STR_BUFFER]; + char vertex_interface[VID2STR_BUFFER]; + char vertex_parent[VID2STR_BUFFER + 11]; + char vertex_nexthop[VID2STR_BUFFER]; + char vertex_metricstr[20]; + struct ttable *tt; + char *table; - vty_out(vty, - "Vertex Type Metric Next-Hop Interface Parent\n"); + /* Prepare table. */ + tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); + ttable_add_row(tt, "Vertex|Type|Metric|Next-Hop|Interface|Parent"); + tt->style.cell.rpad = 2; + tt->style.corner = '+'; + ttable_restyle(tt); + ttable_rowseps(tt, 0, BOTTOM, true, '-'); for (ALL_QUEUE_ELEMENTS_RO(queue, node, vertex)) { if (VTYPE_IS(vertex->type) && memcmp(vertex->N.id, root_sysid, ISIS_SYS_ID_LEN) == 0) { - vty_out(vty, "%-20s %-12s %-6s", - print_sys_hostname(root_sysid), "", ""); - vty_out(vty, "%-30s\n", ""); + /* display here */ + ttable_add_row(tt, "%s|%s|%s|%s|%s|%s", + print_sys_hostname(root_sysid), "", "", + "", "", ""); continue; } @@ -2251,9 +2265,12 @@ static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue, struct isis_vertex_adj *vadj; struct isis_vertex *pvertex; - vty_out(vty, "%-20s %-12s %-6u ", - vid2string(vertex, buff, sizeof(buff)), - vtype2string(vertex->type), vertex->d_N); + snprintf(vertex_name, sizeof(vertex_name), "%s", + vid2string(vertex, buff, sizeof(buff))); + snprintf(vertex_typestr, sizeof(vertex_typestr), "%s", + vtype2string(vertex->type)); + snprintf(vertex_metricstr, sizeof(vertex_metricstr), "%u", + vertex->d_N); for (unsigned int i = 0; i < MAX(vertex->Adj_N ? listcount(vertex->Adj_N) : 0, vertex->parents ? listcount(vertex->parents) : 0); @@ -2273,33 +2290,51 @@ static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue, } if (rows) { - vty_out(vty, "\n"); - vty_out(vty, "%-20s %-12s %-6s ", "", "", ""); + /* display here */ + ttable_add_row(tt, "%s|%s|%s|%s|%s|%s", + vertex_name, vertex_typestr, + vertex_metricstr, vertex_nexthop, + vertex_interface, vertex_parent); + + /* store the first 3 elements */ + vertex_name[0] = '\0'; + vertex_typestr[0] = '\0'; + vertex_metricstr[0] = '\0'; } if (vadj) { struct isis_spf_adj *sadj = vadj->sadj; - vty_out(vty, "%-20s %-9s ", - print_sys_hostname(sadj->id), - sadj->adj ? sadj->adj->circuit - ->interface->name - : "-"); + snprintf(vertex_nexthop, sizeof(vertex_nexthop), + "%s", print_sys_hostname(sadj->id)); + snprintf(vertex_interface, + sizeof(vertex_interface), "%s", + sadj->adj ? sadj->adj->circuit + ->interface->name + : "-"); } if (pvertex) { - if (!vadj) - vty_out(vty, "%-20s %-9s ", "", ""); - - vty_out(vty, "%s(%d)", - vid2string(pvertex, buff, sizeof(buff)), - pvertex->type); + if (!vadj) { + vertex_nexthop[0] = '\0'; + vertex_interface[0] = '\0'; + } + snprintf(vertex_parent, sizeof(vertex_parent), + "%s(%d)", + vid2string(pvertex, buff, sizeof(buff)), + pvertex->type); } ++rows; } - vty_out(vty, "\n"); + ttable_add_row(tt, "%s|%s|%s|%s|%s|%s", vertex_name, + vertex_typestr, vertex_metricstr, vertex_nexthop, + vertex_interface, vertex_parent); } + table = ttable_dump(tt, "\n"); + vty_out(vty, "%s\n", table); + XFREE(MTYPE_TMP, table); + ttable_del(tt); } void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree) diff --git a/tests/isisd/test_isis_spf.refout b/tests/isisd/test_isis_spf.refout index 23d41b9e5dd0..255d920c10cb 100644 --- a/tests/isisd/test_isis_spf.refout +++ b/tests/isisd/test_isis_spf.refout @@ -1,20 +1,22 @@ test# test isis topology 1 root rt1 spf IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + rt3 - rt6(4) + IS-IS L1 IPv4 routing table: @@ -29,21 +31,23 @@ IS-IS L1 IPv4 routing table: - rt3 16060 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) -2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) -2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) + 2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) + 2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) + rt3 - rt6(4) + IS-IS L1 IPv6 routing table: @@ -59,22 +63,24 @@ IS-IS L1 IPv6 routing table: test# test isis topology 2 root rt1 spf IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt5 TE-IS 10 rt5 - rt1(4) -rt2 TE-IS 15 rt2 - rt1(4) -rt1 -rt6 TE-IS 20 rt4 - rt4(4) - rt5 - rt5(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -10.0.255.2/32 IP TE 25 rt2 - rt2(4) -rt3 TE-IS 30 rt3 - rt1(4) -10.0.255.6/32 IP TE 30 rt4 - rt6(4) - rt5 - -10.0.255.3/32 IP TE 40 rt3 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt5 TE-IS 10 rt5 - rt1(4) + rt2 TE-IS 15 rt2 - rt1(4) + rt1 + rt6 TE-IS 20 rt4 - rt4(4) + rt5 - rt5(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + 10.0.255.2/32 IP TE 25 rt2 - rt2(4) + rt3 TE-IS 30 rt3 - rt1(4) + 10.0.255.6/32 IP TE 30 rt4 - rt6(4) + rt5 - rt6(4) + 10.0.255.3/32 IP TE 40 rt3 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -89,22 +95,24 @@ IS-IS L1 IPv4 routing table: - rt5 16060 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt5 TE-IS 10 rt5 - rt1(4) -rt2 TE-IS 15 rt2 - rt1(4) -rt1 -rt6 TE-IS 20 rt4 - rt4(4) - rt5 - rt5(4) -2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) -2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) -2001:db8::2/128 IP6 internal 25 rt2 - rt2(4) -rt3 TE-IS 30 rt3 - rt1(4) -2001:db8::6/128 IP6 internal 30 rt4 - rt6(4) - rt5 - -2001:db8::3/128 IP6 internal 40 rt3 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt5 TE-IS 10 rt5 - rt1(4) + rt2 TE-IS 15 rt2 - rt1(4) + rt1 + rt6 TE-IS 20 rt4 - rt4(4) + rt5 - rt5(4) + 2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) + 2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) + 2001:db8::2/128 IP6 internal 25 rt2 - rt2(4) + rt3 TE-IS 30 rt3 - rt1(4) + 2001:db8::6/128 IP6 internal 30 rt4 - rt6(4) + rt5 - rt6(4) + 2001:db8::3/128 IP6 internal 40 rt3 - rt3(4) + IS-IS L1 IPv6 routing table: @@ -120,19 +128,21 @@ IS-IS L1 IPv6 routing table: test# test isis topology 3 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt5 TE-IS 30 rt2 - rt4(4) -rt6 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 40 rt2 - rt5(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt5 TE-IS 30 rt2 - rt4(4) + rt6 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 40 rt2 - rt5(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + IS-IS L1 IPv4 routing table: @@ -147,23 +157,25 @@ IS-IS L1 IPv4 routing table: test# test isis topology 4 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt8 TE-IS 40 rt2 - rt6(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -10.0.255.8/32 IP TE 50 rt2 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt8 TE-IS 40 rt2 - rt6(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + 10.0.255.8/32 IP TE 50 rt2 - rt8(4) + IS-IS L1 IPv4 routing table: @@ -180,25 +192,27 @@ IS-IS L1 IPv4 routing table: test# test isis topology 5 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt8 TE-IS 40 rt2 - rt6(4) - rt3 - rt7(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -10.0.255.8/32 IP TE 50 rt2 - rt8(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt8 TE-IS 40 rt2 - rt6(4) + rt3 - rt7(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + 10.0.255.8/32 IP TE 50 rt2 - rt8(4) + rt3 - rt8(4) + IS-IS L1 IPv4 routing table: @@ -216,33 +230,35 @@ IS-IS L1 IPv4 routing table: test# test isis topology 6 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) - rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - -10.0.255.4/32 IP TE 30 rt2 - rt4(4) - rt3 - -rt5 TE-IS 40 rt2 - rt6(4) - rt3 - -rt8 TE-IS 40 rt2 - rt6(4) - rt3 - -10.0.255.6/32 IP TE 40 rt2 - rt6(4) - rt3 - -rt7 TE-IS 50 rt2 - rt5(4) - rt3 - rt8(4) -10.0.255.5/32 IP TE 50 rt2 - rt5(4) - rt3 - -10.0.255.8/32 IP TE 50 rt2 - rt8(4) - rt3 - -10.0.255.7/32 IP TE 60 rt2 - rt7(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt3 - rt4(4) + rt5 TE-IS 40 rt2 - rt6(4) + rt3 - rt6(4) + rt8 TE-IS 40 rt2 - rt6(4) + rt3 - rt6(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + rt3 - rt6(4) + rt7 TE-IS 50 rt2 - rt5(4) + rt3 - rt8(4) + 10.0.255.5/32 IP TE 50 rt2 - rt5(4) + rt3 - rt5(4) + 10.0.255.8/32 IP TE 50 rt2 - rt8(4) + rt3 - rt8(4) + 10.0.255.7/32 IP TE 60 rt2 - rt7(4) + rt3 - rt7(4) + IS-IS L1 IPv4 routing table: @@ -264,34 +280,36 @@ IS-IS L1 IPv4 routing table: test# test isis topology 7 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt5 TE-IS 20 rt4 - rt4(4) -rt7 TE-IS 20 rt4 - rt4(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -rt2 TE-IS 30 rt4 - rt5(4) -rt6 TE-IS 30 rt4 - rt5(4) -rt8 TE-IS 30 rt4 - rt5(4) - rt7(4) -10.0.255.5/32 IP TE 30 rt4 - rt5(4) -10.0.255.7/32 IP TE 30 rt4 - rt7(4) -rt10 TE-IS 40 rt4 - rt7(4) -rt3 TE-IS 40 rt4 - rt2(4) - rt6(4) -rt9 TE-IS 40 rt4 - rt8(4) -rt11 TE-IS 40 rt4 - rt8(4) -10.0.255.2/32 IP TE 40 rt4 - rt2(4) -10.0.255.6/32 IP TE 40 rt4 - rt6(4) -10.0.255.8/32 IP TE 40 rt4 - rt8(4) -rt12 TE-IS 50 rt4 - rt9(4) - rt11(4) -10.0.255.10/32 IP TE 50 rt4 - rt10(4) -10.0.255.3/32 IP TE 50 rt4 - rt3(4) -10.0.255.9/32 IP TE 50 rt4 - rt9(4) -10.0.255.11/32 IP TE 50 rt4 - rt11(4) -10.0.255.12/32 IP TE 60 rt4 - rt12(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt5 TE-IS 20 rt4 - rt4(4) + rt7 TE-IS 20 rt4 - rt4(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + rt2 TE-IS 30 rt4 - rt5(4) + rt6 TE-IS 30 rt4 - rt5(4) + rt8 TE-IS 30 rt4 - rt5(4) + rt7(4) + 10.0.255.5/32 IP TE 30 rt4 - rt5(4) + 10.0.255.7/32 IP TE 30 rt4 - rt7(4) + rt10 TE-IS 40 rt4 - rt7(4) + rt3 TE-IS 40 rt4 - rt2(4) + rt6(4) + rt9 TE-IS 40 rt4 - rt8(4) + rt11 TE-IS 40 rt4 - rt8(4) + 10.0.255.2/32 IP TE 40 rt4 - rt2(4) + 10.0.255.6/32 IP TE 40 rt4 - rt6(4) + 10.0.255.8/32 IP TE 40 rt4 - rt8(4) + rt12 TE-IS 50 rt4 - rt9(4) + rt11(4) + 10.0.255.10/32 IP TE 50 rt4 - rt10(4) + 10.0.255.3/32 IP TE 50 rt4 - rt3(4) + 10.0.255.9/32 IP TE 50 rt4 - rt9(4) + 10.0.255.11/32 IP TE 50 rt4 - rt11(4) + 10.0.255.12/32 IP TE 60 rt4 - rt12(4) + IS-IS L1 IPv4 routing table: @@ -312,33 +330,35 @@ IS-IS L1 IPv4 routing table: test# test isis topology 8 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt3 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt2 - rt2(4) -rt7 TE-IS 20 rt4 - rt4(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -rt6 TE-IS 30 rt2 - rt3(4) - rt5(4) -rt8 TE-IS 30 rt2 - rt5(4) -rt10 TE-IS 30 rt4 - rt7(4) -10.0.255.3/32 IP TE 30 rt2 - rt3(4) -10.0.255.5/32 IP TE 30 rt2 - rt5(4) -10.0.255.7/32 IP TE 30 rt4 - rt7(4) -rt9 TE-IS 40 rt2 - rt8(4) -rt11 TE-IS 40 rt2 - rt8(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) -10.0.255.8/32 IP TE 40 rt2 - rt8(4) -10.0.255.10/32 IP TE 40 rt4 - rt10(4) -rt12 TE-IS 50 rt2 - rt9(4) - rt11(4) -10.0.255.9/32 IP TE 50 rt2 - rt9(4) -10.0.255.11/32 IP TE 50 rt2 - rt11(4) -10.0.255.12/32 IP TE 60 rt2 - rt12(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt3 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt2 - rt2(4) + rt7 TE-IS 20 rt4 - rt4(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + rt6 TE-IS 30 rt2 - rt3(4) + rt5(4) + rt8 TE-IS 30 rt2 - rt5(4) + rt10 TE-IS 30 rt4 - rt7(4) + 10.0.255.3/32 IP TE 30 rt2 - rt3(4) + 10.0.255.5/32 IP TE 30 rt2 - rt5(4) + 10.0.255.7/32 IP TE 30 rt4 - rt7(4) + rt9 TE-IS 40 rt2 - rt8(4) + rt11 TE-IS 40 rt2 - rt8(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + 10.0.255.8/32 IP TE 40 rt2 - rt8(4) + 10.0.255.10/32 IP TE 40 rt4 - rt10(4) + rt12 TE-IS 50 rt2 - rt9(4) + rt11(4) + 10.0.255.9/32 IP TE 50 rt2 - rt9(4) + 10.0.255.11/32 IP TE 50 rt2 - rt11(4) + 10.0.255.12/32 IP TE 60 rt2 - rt12(4) + IS-IS L1 IPv4 routing table: @@ -359,28 +379,30 @@ IS-IS L1 IPv4 routing table: test# test isis topology 9 root rt1 spf IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt5 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -rt9 TE-IS 40 rt2 - rt5(4) -10.0.255.5/32 IP TE 40 rt2 - rt5(4) -rt6 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt7 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt8 TE-IS 50 rt2 - rt4(4) - rt9(4) -10.0.255.9/32 IP TE 50 rt2 - rt9(4) -10.0.255.6/32 IP TE 60 rt2 - rt6(4) -10.0.255.7/32 IP TE 60 rt2 - rt7(4) -10.0.255.8/32 IP TE 60 rt2 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt5 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt9 TE-IS 40 rt2 - rt5(4) + 10.0.255.5/32 IP TE 40 rt2 - rt5(4) + rt6 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt7 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt8 TE-IS 50 rt2 - rt4(4) + rt9(4) + 10.0.255.9/32 IP TE 50 rt2 - rt9(4) + 10.0.255.6/32 IP TE 60 rt2 - rt6(4) + 10.0.255.7/32 IP TE 60 rt2 - rt7(4) + 10.0.255.8/32 IP TE 60 rt2 - rt8(4) + IS-IS L1 IPv4 routing table: @@ -397,28 +419,30 @@ IS-IS L1 IPv4 routing table: 10.0.255.9/32 50 - rt2 16090 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt5 TE-IS 30 rt2 - rt4(4) -2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) -rt9 TE-IS 40 rt2 - rt5(4) -2001:db8::5/128 IP6 internal 40 rt2 - rt5(4) -rt6 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt7 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt8 TE-IS 50 rt2 - rt4(4) - rt9(4) -2001:db8::9/128 IP6 internal 50 rt2 - rt9(4) -2001:db8::6/128 IP6 internal 60 rt2 - rt6(4) -2001:db8::7/128 IP6 internal 60 rt2 - rt7(4) -2001:db8::8/128 IP6 internal 60 rt2 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt5 TE-IS 30 rt2 - rt4(4) + 2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) + rt9 TE-IS 40 rt2 - rt5(4) + 2001:db8::5/128 IP6 internal 40 rt2 - rt5(4) + rt6 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt7 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt8 TE-IS 50 rt2 - rt4(4) + rt9(4) + 2001:db8::9/128 IP6 internal 50 rt2 - rt9(4) + 2001:db8::6/128 IP6 internal 60 rt2 - rt6(4) + 2001:db8::7/128 IP6 internal 60 rt2 - rt7(4) + 2001:db8::8/128 IP6 internal 60 rt2 - rt8(4) + IS-IS L1 IPv6 routing table: @@ -436,23 +460,25 @@ IS-IS L1 IPv6 routing table: test# test isis topology 10 root rt1 spf IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 20 rt3 - rt1(4) -rt4 TE-IS 20 rt4 - rt1(4) -rt5 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -rt6 TE-IS 30 rt3 - rt3(4) -rt7 TE-IS 30 rt4 - rt4(4) -rt8 TE-IS 30 rt2 - rt5(4) -10.0.255.3/32 IP TE 30 rt3 - rt3(4) -10.0.255.4/32 IP TE 30 rt4 - rt4(4) -10.0.255.5/32 IP TE 30 rt2 - rt5(4) -10.0.255.6/32 IP TE 40 rt3 - rt6(4) -10.0.255.7/32 IP TE 40 rt4 - rt7(4) -10.0.255.8/32 IP TE 40 rt2 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 20 rt3 - rt1(4) + rt4 TE-IS 20 rt4 - rt1(4) + rt5 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + rt6 TE-IS 30 rt3 - rt3(4) + rt7 TE-IS 30 rt4 - rt4(4) + rt8 TE-IS 30 rt2 - rt5(4) + 10.0.255.3/32 IP TE 30 rt3 - rt3(4) + 10.0.255.4/32 IP TE 30 rt4 - rt4(4) + 10.0.255.5/32 IP TE 30 rt2 - rt5(4) + 10.0.255.6/32 IP TE 40 rt3 - rt6(4) + 10.0.255.7/32 IP TE 40 rt4 - rt7(4) + 10.0.255.8/32 IP TE 40 rt2 - rt8(4) + IS-IS L1 IPv4 routing table: @@ -468,23 +494,25 @@ IS-IS L1 IPv4 routing table: 10.0.255.8/32 40 - rt2 16080 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 20 rt3 - rt1(4) -rt4 TE-IS 20 rt4 - rt1(4) -rt5 TE-IS 20 rt2 - rt2(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -rt6 TE-IS 30 rt3 - rt3(4) -rt7 TE-IS 30 rt4 - rt4(4) -rt8 TE-IS 30 rt2 - rt5(4) -2001:db8::3/128 IP6 internal 30 rt3 - rt3(4) -2001:db8::4/128 IP6 internal 30 rt4 - rt4(4) -2001:db8::5/128 IP6 internal 30 rt2 - rt5(4) -2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) -2001:db8::7/128 IP6 internal 40 rt4 - rt7(4) -2001:db8::8/128 IP6 internal 40 rt2 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 20 rt3 - rt1(4) + rt4 TE-IS 20 rt4 - rt1(4) + rt5 TE-IS 20 rt2 - rt2(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + rt6 TE-IS 30 rt3 - rt3(4) + rt7 TE-IS 30 rt4 - rt4(4) + rt8 TE-IS 30 rt2 - rt5(4) + 2001:db8::3/128 IP6 internal 30 rt3 - rt3(4) + 2001:db8::4/128 IP6 internal 30 rt4 - rt4(4) + 2001:db8::5/128 IP6 internal 30 rt2 - rt5(4) + 2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) + 2001:db8::7/128 IP6 internal 40 rt4 - rt7(4) + 2001:db8::8/128 IP6 internal 40 rt2 - rt8(4) + IS-IS L1 IPv6 routing table: @@ -501,22 +529,24 @@ IS-IS L1 IPv6 routing table: test# test isis topology 11 root rt1 spf IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt2 pseudo_TE-IS 20 rt3 - rt3(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt2 pseudo_TE-IS 20 rt3 - rt3(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + rt3 - rt6(4) + IS-IS L1 IPv4 routing table: @@ -531,22 +561,24 @@ IS-IS L1 IPv4 routing table: - rt3 16060 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt2 pseudo_TE-IS 20 rt3 - rt3(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) -2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) -2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt2 pseudo_TE-IS 20 rt3 - rt3(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) + 2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) + 2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) + rt3 - rt6(4) + IS-IS L1 IPv6 routing table: @@ -562,27 +594,29 @@ IS-IS L1 IPv6 routing table: test# test isis topology 12 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt8 TE-IS 40 rt2 - rt6(4) -rt9 TE-IS 40 rt3 - rt7(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -rt10 TE-IS 50 rt2 - rt8(4) -10.0.255.8/32 IP TE 50 rt2 - rt8(4) -10.0.255.9/32 IP TE 50 rt3 - rt9(4) -10.0.255.10/32 IP TE 60 rt2 - rt10(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt8 TE-IS 40 rt2 - rt6(4) + rt9 TE-IS 40 rt3 - rt7(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + rt10 TE-IS 50 rt2 - rt8(4) + 10.0.255.8/32 IP TE 50 rt2 - rt8(4) + 10.0.255.9/32 IP TE 50 rt3 - rt9(4) + 10.0.255.10/32 IP TE 60 rt2 - rt10(4) + IS-IS L1 IPv4 routing table: @@ -601,24 +635,26 @@ IS-IS L1 IPv4 routing table: test# test isis topology 13 root rt1 spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) - rt3 - rt3(4) -rt5 TE-IS 20 rt3 - rt3(4) -rt6 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt3 - rt5(4) - rt6(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) - rt3 - -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 30 rt3 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt3 - rt3(4) + rt5 TE-IS 20 rt3 - rt3(4) + rt6 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt3 - rt5(4) + rt6(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt3 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 30 rt3 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + IS-IS L1 IPv4 routing table: @@ -636,23 +672,25 @@ IS-IS L1 IPv4 routing table: test# test# test isis topology 4 root rt1 reverse-spf ipv4-only IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt8 TE-IS 40 rt2 - rt6(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -10.0.255.8/32 IP TE 50 rt2 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt8 TE-IS 40 rt2 - rt6(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + 10.0.255.8/32 IP TE 50 rt2 - rt8(4) + IS-IS L1 IPv4 routing table: @@ -669,21 +707,23 @@ IS-IS L1 IPv4 routing table: test# test isis topology 11 root rt1 reverse-spf IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt2 pseudo_TE-IS 20 rt3 - rt3(4) -rt4 TE-IS 20 rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt3 - rt4(4) - rt5(4) -10.0.255.4/32 IP TE 30 rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 40 rt3 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt2 pseudo_TE-IS 20 rt3 - rt3(4) + rt4 TE-IS 20 rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt3 - rt4(4) + rt5(4) + 10.0.255.4/32 IP TE 30 rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 40 rt3 - rt6(4) + IS-IS L1 IPv4 routing table: @@ -695,21 +735,23 @@ IS-IS L1 IPv4 routing table: 10.0.255.6/32 40 - rt3 16060 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt2 pseudo_TE-IS 20 rt3 - rt3(4) -rt4 TE-IS 20 rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -2001:db8::2/128 IP6 internal 20 rt2(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt6 TE-IS 30 rt3 - rt4(4) - rt5(4) -2001:db8::4/128 IP6 internal 30 rt4(4) -2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) -2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt2 pseudo_TE-IS 20 rt3 - rt3(4) + rt4 TE-IS 20 rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 2001:db8::2/128 IP6 internal 20 rt2(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt6 TE-IS 30 rt3 - rt4(4) + rt5(4) + 2001:db8::4/128 IP6 internal 30 rt4(4) + 2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) + 2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) + IS-IS L1 IPv6 routing table: @@ -723,21 +765,23 @@ IS-IS L1 IPv6 routing table: test# test# test isis topology 1 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + rt3 - rt6(4) + Main: IS-IS L1 IPv4 routing table: @@ -756,21 +800,23 @@ Backup: IS-IS L1 IPv4 routing table: IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) -2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) -2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) + 2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) + 2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) + rt3 - rt6(4) + Main: IS-IS L1 IPv6 routing table: @@ -790,21 +836,23 @@ IS-IS L1 IPv6 routing table: test# test isis topology 2 root rt4 lfa system-id rt1 pseudonode-id 1 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt4 -10.0.255.4/32 IP internal 0 rt4(4) -rt1 TE-IS 10 rt1 - rt4(4) -rt5 TE-IS 10 rt5 - rt4(4) -rt6 TE-IS 10 rt6 - rt4(4) -rt1 pseudo_TE-IS 20 rt1 - rt1(4) - rt5 - rt5(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt2 TE-IS 25 rt1 - rt1(4) -10.0.255.2/32 IP TE 35 rt1 - rt2(4) -rt3 TE-IS 40 rt1 - rt1(4) -10.0.255.3/32 IP TE 50 rt1 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt4 + 10.0.255.4/32 IP internal 0 rt4(4) + rt1 TE-IS 10 rt1 - rt4(4) + rt5 TE-IS 10 rt5 - rt4(4) + rt6 TE-IS 10 rt6 - rt4(4) + rt1 pseudo_TE-IS 20 rt1 - rt1(4) + rt5 - rt5(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt2 TE-IS 25 rt1 - rt1(4) + 10.0.255.2/32 IP TE 35 rt1 - rt2(4) + rt3 TE-IS 40 rt1 - rt1(4) + 10.0.255.3/32 IP TE 50 rt1 - rt3(4) + Main: IS-IS L1 IPv4 routing table: @@ -826,21 +874,23 @@ IS-IS L1 IPv4 routing table: 10.0.255.2/32 50 - rt2 implicit-null IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt4 -2001:db8::4/128 IP6 internal 0 rt4(4) -rt1 TE-IS 10 rt1 - rt4(4) -rt5 TE-IS 10 rt5 - rt4(4) -rt6 TE-IS 10 rt6 - rt4(4) -rt1 pseudo_TE-IS 20 rt1 - rt1(4) - rt5 - rt5(4) -2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) -2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) -2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) -rt2 TE-IS 25 rt1 - rt1(4) -2001:db8::2/128 IP6 internal 35 rt1 - rt2(4) -rt3 TE-IS 40 rt1 - rt1(4) -2001:db8::3/128 IP6 internal 50 rt1 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt4 + 2001:db8::4/128 IP6 internal 0 rt4(4) + rt1 TE-IS 10 rt1 - rt4(4) + rt5 TE-IS 10 rt5 - rt4(4) + rt6 TE-IS 10 rt6 - rt4(4) + rt1 pseudo_TE-IS 20 rt1 - rt1(4) + rt5 - rt5(4) + 2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) + 2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) + 2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) + rt2 TE-IS 25 rt1 - rt1(4) + 2001:db8::2/128 IP6 internal 35 rt1 - rt2(4) + rt3 TE-IS 40 rt1 - rt1(4) + 2001:db8::3/128 IP6 internal 50 rt1 - rt3(4) + Main: IS-IS L1 IPv6 routing table: @@ -863,21 +913,23 @@ IS-IS L1 IPv6 routing table: test# test isis topology 2 root rt4 lfa system-id rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt4 -10.0.255.4/32 IP internal 0 rt4(4) -rt1 TE-IS 10 rt1 - rt4(4) -rt5 TE-IS 10 rt5 - rt4(4) -rt6 TE-IS 10 rt6 - rt4(4) -rt1 pseudo_TE-IS 20 rt1 - rt1(4) - rt5 - rt5(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt2 TE-IS 25 rt1 - rt1(4) -10.0.255.2/32 IP TE 35 rt1 - rt2(4) -rt3 TE-IS 40 rt1 - rt1(4) -10.0.255.3/32 IP TE 50 rt1 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt4 + 10.0.255.4/32 IP internal 0 rt4(4) + rt1 TE-IS 10 rt1 - rt4(4) + rt5 TE-IS 10 rt5 - rt4(4) + rt6 TE-IS 10 rt6 - rt4(4) + rt1 pseudo_TE-IS 20 rt1 - rt1(4) + rt5 - rt5(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt2 TE-IS 25 rt1 - rt1(4) + 10.0.255.2/32 IP TE 35 rt1 - rt2(4) + rt3 TE-IS 40 rt1 - rt1(4) + 10.0.255.3/32 IP TE 50 rt1 - rt3(4) + Main: IS-IS L1 IPv4 routing table: @@ -899,21 +951,23 @@ IS-IS L1 IPv4 routing table: 10.0.255.6/32 30 - rt5 16060 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt4 -2001:db8::4/128 IP6 internal 0 rt4(4) -rt1 TE-IS 10 rt1 - rt4(4) -rt5 TE-IS 10 rt5 - rt4(4) -rt6 TE-IS 10 rt6 - rt4(4) -rt1 pseudo_TE-IS 20 rt1 - rt1(4) - rt5 - rt5(4) -2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) -2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) -2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) -rt2 TE-IS 25 rt1 - rt1(4) -2001:db8::2/128 IP6 internal 35 rt1 - rt2(4) -rt3 TE-IS 40 rt1 - rt1(4) -2001:db8::3/128 IP6 internal 50 rt1 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt4 + 2001:db8::4/128 IP6 internal 0 rt4(4) + rt1 TE-IS 10 rt1 - rt4(4) + rt5 TE-IS 10 rt5 - rt4(4) + rt6 TE-IS 10 rt6 - rt4(4) + rt1 pseudo_TE-IS 20 rt1 - rt1(4) + rt5 - rt5(4) + 2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) + 2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) + 2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) + rt2 TE-IS 25 rt1 - rt1(4) + 2001:db8::2/128 IP6 internal 35 rt1 - rt2(4) + rt3 TE-IS 40 rt1 - rt1(4) + 2001:db8::3/128 IP6 internal 50 rt1 - rt3(4) + Main: IS-IS L1 IPv6 routing table: @@ -936,19 +990,21 @@ IS-IS L1 IPv6 routing table: test# test isis topology 3 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt5 TE-IS 30 rt2 - rt4(4) -rt6 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 40 rt2 - rt5(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt5 TE-IS 30 rt2 - rt4(4) + rt6 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 40 rt2 - rt5(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + Main: IS-IS L1 IPv4 routing table: @@ -973,10 +1029,12 @@ IS-IS L1 IPv4 routing table: 10.0.255.6/32 50 - rt3 16060 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ---------------------------------------------------- + rt1 + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + Main: IS-IS L1 IPv6 routing table: @@ -986,19 +1044,21 @@ IS-IS L1 IPv6 routing table: test# test isis topology 3 root rt1 lfa system-id rt3 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt5 TE-IS 30 rt2 - rt4(4) -rt6 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 40 rt2 - rt5(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt5 TE-IS 30 rt2 - rt4(4) + rt6 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 40 rt2 - rt5(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + Main: IS-IS L1 IPv4 routing table: @@ -1020,10 +1080,12 @@ IS-IS L1 IPv4 routing table: 10.0.255.3/32 30 - rt2 16030 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ---------------------------------------------------- + rt1 + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + Main: IS-IS L1 IPv6 routing table: @@ -1033,34 +1095,36 @@ IS-IS L1 IPv6 routing table: test# test isis topology 7 root rt1 lfa system-id rt4 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt5 TE-IS 20 rt4 - rt4(4) -rt7 TE-IS 20 rt4 - rt4(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -rt2 TE-IS 30 rt4 - rt5(4) -rt6 TE-IS 30 rt4 - rt5(4) -rt8 TE-IS 30 rt4 - rt5(4) - rt7(4) -10.0.255.5/32 IP TE 30 rt4 - rt5(4) -10.0.255.7/32 IP TE 30 rt4 - rt7(4) -rt10 TE-IS 40 rt4 - rt7(4) -rt3 TE-IS 40 rt4 - rt2(4) - rt6(4) -rt9 TE-IS 40 rt4 - rt8(4) -rt11 TE-IS 40 rt4 - rt8(4) -10.0.255.2/32 IP TE 40 rt4 - rt2(4) -10.0.255.6/32 IP TE 40 rt4 - rt6(4) -10.0.255.8/32 IP TE 40 rt4 - rt8(4) -rt12 TE-IS 50 rt4 - rt9(4) - rt11(4) -10.0.255.10/32 IP TE 50 rt4 - rt10(4) -10.0.255.3/32 IP TE 50 rt4 - rt3(4) -10.0.255.9/32 IP TE 50 rt4 - rt9(4) -10.0.255.11/32 IP TE 50 rt4 - rt11(4) -10.0.255.12/32 IP TE 60 rt4 - rt12(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt5 TE-IS 20 rt4 - rt4(4) + rt7 TE-IS 20 rt4 - rt4(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + rt2 TE-IS 30 rt4 - rt5(4) + rt6 TE-IS 30 rt4 - rt5(4) + rt8 TE-IS 30 rt4 - rt5(4) + rt7(4) + 10.0.255.5/32 IP TE 30 rt4 - rt5(4) + 10.0.255.7/32 IP TE 30 rt4 - rt7(4) + rt10 TE-IS 40 rt4 - rt7(4) + rt3 TE-IS 40 rt4 - rt2(4) + rt6(4) + rt9 TE-IS 40 rt4 - rt8(4) + rt11 TE-IS 40 rt4 - rt8(4) + 10.0.255.2/32 IP TE 40 rt4 - rt2(4) + 10.0.255.6/32 IP TE 40 rt4 - rt6(4) + 10.0.255.8/32 IP TE 40 rt4 - rt8(4) + rt12 TE-IS 50 rt4 - rt9(4) + rt11(4) + 10.0.255.10/32 IP TE 50 rt4 - rt10(4) + 10.0.255.3/32 IP TE 50 rt4 - rt3(4) + 10.0.255.9/32 IP TE 50 rt4 - rt9(4) + 10.0.255.11/32 IP TE 50 rt4 - rt11(4) + 10.0.255.12/32 IP TE 60 rt4 - rt12(4) + Main: IS-IS L1 IPv4 routing table: @@ -1098,10 +1162,12 @@ IS-IS L1 IPv4 routing table: 10.0.255.12/32 90 - rt2 16120 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -rt4 TE-IS 10 rt4 - rt1(4) -rt2 TE-IS 40 rt2 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ---------------------------------------------------- + rt1 + rt4 TE-IS 10 rt4 - rt1(4) + rt2 TE-IS 40 rt2 - rt1(4) + Main: IS-IS L1 IPv6 routing table: @@ -1111,40 +1177,42 @@ IS-IS L1 IPv6 routing table: test# test isis topology 7 root rt7 lfa system-id rt8 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt7 -10.0.255.7/32 IP internal 0 rt7(4) -rt4 TE-IS 10 rt4 - rt7(4) -rt8 TE-IS 10 rt8 - rt7(4) -rt10 TE-IS 20 rt10 - rt7(4) -rt1 TE-IS 20 rt4 - rt4(4) -rt5 TE-IS 20 rt4 - rt4(4) - rt8 - rt8(4) -rt9 TE-IS 20 rt8 - rt8(4) -rt11 TE-IS 20 rt8 - rt8(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.8/32 IP TE 20 rt8 - rt8(4) -rt2 TE-IS 30 rt4 - rt5(4) - rt8 - -rt6 TE-IS 30 rt4 - rt5(4) - rt8 - -rt12 TE-IS 30 rt8 - rt9(4) - rt11(4) -10.0.255.10/32 IP TE 30 rt10 - rt10(4) -10.0.255.1/32 IP TE 30 rt4 - rt1(4) -10.0.255.5/32 IP TE 30 rt4 - rt5(4) - rt8 - -10.0.255.9/32 IP TE 30 rt8 - rt9(4) -10.0.255.11/32 IP TE 30 rt8 - rt11(4) -rt3 TE-IS 40 rt4 - rt2(4) - rt8 - rt6(4) -10.0.255.2/32 IP TE 40 rt4 - rt2(4) - rt8 - -10.0.255.6/32 IP TE 40 rt4 - rt6(4) - rt8 - -10.0.255.12/32 IP TE 40 rt8 - rt12(4) -10.0.255.3/32 IP TE 50 rt4 - rt3(4) - rt8 - + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt7 + 10.0.255.7/32 IP internal 0 rt7(4) + rt4 TE-IS 10 rt4 - rt7(4) + rt8 TE-IS 10 rt8 - rt7(4) + rt10 TE-IS 20 rt10 - rt7(4) + rt1 TE-IS 20 rt4 - rt4(4) + rt5 TE-IS 20 rt4 - rt4(4) + rt8 - rt8(4) + rt9 TE-IS 20 rt8 - rt8(4) + rt11 TE-IS 20 rt8 - rt8(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.8/32 IP TE 20 rt8 - rt8(4) + rt2 TE-IS 30 rt4 - rt5(4) + rt8 - rt5(4) + rt6 TE-IS 30 rt4 - rt5(4) + rt8 - rt5(4) + rt12 TE-IS 30 rt8 - rt9(4) + rt11(4) + 10.0.255.10/32 IP TE 30 rt10 - rt10(4) + 10.0.255.1/32 IP TE 30 rt4 - rt1(4) + 10.0.255.5/32 IP TE 30 rt4 - rt5(4) + rt8 - rt5(4) + 10.0.255.9/32 IP TE 30 rt8 - rt9(4) + 10.0.255.11/32 IP TE 30 rt8 - rt11(4) + rt3 TE-IS 40 rt4 - rt2(4) + rt8 - rt6(4) + 10.0.255.2/32 IP TE 40 rt4 - rt2(4) + rt8 - rt2(4) + 10.0.255.6/32 IP TE 40 rt4 - rt6(4) + rt8 - rt6(4) + 10.0.255.12/32 IP TE 40 rt8 - rt12(4) + 10.0.255.3/32 IP TE 50 rt4 - rt3(4) + rt8 - rt3(4) + Main: IS-IS L1 IPv4 routing table: @@ -1179,11 +1247,13 @@ IS-IS L1 IPv4 routing table: 10.0.255.12/32 50 - rt10 16120 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt7 -rt4 TE-IS 10 rt4 - rt7(4) -rt8 TE-IS 10 rt8 - rt7(4) -rt10 TE-IS 20 rt10 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ---------------------------------------------------- + rt7 + rt4 TE-IS 10 rt4 - rt7(4) + rt8 TE-IS 10 rt8 - rt7(4) + rt10 TE-IS 20 rt10 - rt7(4) + Main: IS-IS L1 IPv6 routing table: @@ -1193,38 +1263,40 @@ IS-IS L1 IPv6 routing table: test# test isis topology 7 root rt8 lfa system-id rt11 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt8 -10.0.255.8/32 IP internal 0 rt8(4) -rt5 TE-IS 10 rt5 - rt8(4) -rt7 TE-IS 10 rt7 - rt8(4) -rt9 TE-IS 10 rt9 - rt8(4) -rt11 TE-IS 10 rt11 - rt8(4) -rt2 TE-IS 20 rt5 - rt5(4) -rt4 TE-IS 20 rt5 - rt5(4) - rt7 - rt7(4) -rt6 TE-IS 20 rt5 - rt5(4) -rt12 TE-IS 20 rt9 - rt9(4) - rt11 - rt11(4) -rt10 TE-IS 20 rt11 - rt11(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -10.0.255.7/32 IP TE 20 rt7 - rt7(4) -10.0.255.9/32 IP TE 20 rt9 - rt9(4) -10.0.255.11/32 IP TE 20 rt11 - rt11(4) -rt3 TE-IS 30 rt5 - rt2(4) - rt6(4) -rt1 TE-IS 30 rt5 - rt4(4) - rt7 - -10.0.255.2/32 IP TE 30 rt5 - rt2(4) -10.0.255.4/32 IP TE 30 rt5 - rt4(4) - rt7 - -10.0.255.6/32 IP TE 30 rt5 - rt6(4) -10.0.255.12/32 IP TE 30 rt9 - rt12(4) - rt11 - -10.0.255.10/32 IP TE 30 rt11 - rt10(4) -10.0.255.3/32 IP TE 40 rt5 - rt3(4) -10.0.255.1/32 IP TE 40 rt5 - rt1(4) - rt7 - + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt8 + 10.0.255.8/32 IP internal 0 rt8(4) + rt5 TE-IS 10 rt5 - rt8(4) + rt7 TE-IS 10 rt7 - rt8(4) + rt9 TE-IS 10 rt9 - rt8(4) + rt11 TE-IS 10 rt11 - rt8(4) + rt2 TE-IS 20 rt5 - rt5(4) + rt4 TE-IS 20 rt5 - rt5(4) + rt7 - rt7(4) + rt6 TE-IS 20 rt5 - rt5(4) + rt12 TE-IS 20 rt9 - rt9(4) + rt11 - rt11(4) + rt10 TE-IS 20 rt11 - rt11(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + 10.0.255.7/32 IP TE 20 rt7 - rt7(4) + 10.0.255.9/32 IP TE 20 rt9 - rt9(4) + 10.0.255.11/32 IP TE 20 rt11 - rt11(4) + rt3 TE-IS 30 rt5 - rt2(4) + rt6(4) + rt1 TE-IS 30 rt5 - rt4(4) + rt7 - rt4(4) + 10.0.255.2/32 IP TE 30 rt5 - rt2(4) + 10.0.255.4/32 IP TE 30 rt5 - rt4(4) + rt7 - rt4(4) + 10.0.255.6/32 IP TE 30 rt5 - rt6(4) + 10.0.255.12/32 IP TE 30 rt9 - rt12(4) + rt11 - rt12(4) + 10.0.255.10/32 IP TE 30 rt11 - rt10(4) + 10.0.255.3/32 IP TE 40 rt5 - rt3(4) + 10.0.255.1/32 IP TE 40 rt5 - rt1(4) + rt7 - rt1(4) + Main: IS-IS L1 IPv4 routing table: @@ -1255,12 +1327,14 @@ IS-IS L1 IPv4 routing table: 10.0.255.10/32 40 - rt7 16100 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt8 -rt5 TE-IS 10 rt5 - rt8(4) -rt7 TE-IS 10 rt7 - rt8(4) -rt9 TE-IS 10 rt9 - rt8(4) -rt11 TE-IS 10 rt11 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ---------------------------------------------------- + rt8 + rt5 TE-IS 10 rt5 - rt8(4) + rt7 TE-IS 10 rt7 - rt8(4) + rt9 TE-IS 10 rt9 - rt8(4) + rt11 TE-IS 10 rt11 - rt8(4) + Main: IS-IS L1 IPv6 routing table: @@ -1270,28 +1344,30 @@ IS-IS L1 IPv6 routing table: test# test isis topology 9 root rt3 lfa system-id rt1 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt3 -10.0.255.3/32 IP internal 0 rt3(4) -rt1 TE-IS 10 rt1 - rt3(4) -rt2 TE-IS 20 rt1 - rt1(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -rt4 TE-IS 30 rt1 - rt2(4) -10.0.255.2/32 IP TE 30 rt1 - rt2(4) -rt5 TE-IS 40 rt1 - rt4(4) -10.0.255.4/32 IP TE 40 rt1 - rt4(4) -rt9 TE-IS 50 rt1 - rt5(4) -10.0.255.5/32 IP TE 50 rt1 - rt5(4) -rt6 TE-IS 60 rt1 - rt4(4) - rt9(4) -rt7 TE-IS 60 rt1 - rt4(4) - rt9(4) -rt8 TE-IS 60 rt1 - rt4(4) - rt9(4) -10.0.255.9/32 IP TE 60 rt1 - rt9(4) -10.0.255.6/32 IP TE 70 rt1 - rt6(4) -10.0.255.7/32 IP TE 70 rt1 - rt7(4) -10.0.255.8/32 IP TE 70 rt1 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt3 + 10.0.255.3/32 IP internal 0 rt3(4) + rt1 TE-IS 10 rt1 - rt3(4) + rt2 TE-IS 20 rt1 - rt1(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + rt4 TE-IS 30 rt1 - rt2(4) + 10.0.255.2/32 IP TE 30 rt1 - rt2(4) + rt5 TE-IS 40 rt1 - rt4(4) + 10.0.255.4/32 IP TE 40 rt1 - rt4(4) + rt9 TE-IS 50 rt1 - rt5(4) + 10.0.255.5/32 IP TE 50 rt1 - rt5(4) + rt6 TE-IS 60 rt1 - rt4(4) + rt9(4) + rt7 TE-IS 60 rt1 - rt4(4) + rt9(4) + rt8 TE-IS 60 rt1 - rt4(4) + rt9(4) + 10.0.255.9/32 IP TE 60 rt1 - rt9(4) + 10.0.255.6/32 IP TE 70 rt1 - rt6(4) + 10.0.255.7/32 IP TE 70 rt1 - rt7(4) + 10.0.255.8/32 IP TE 70 rt1 - rt8(4) + Main: IS-IS L1 IPv4 routing table: @@ -1323,28 +1399,30 @@ IS-IS L1 IPv4 routing table: 10.0.255.9/32 130 - rt4 16090 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt3 -2001:db8::3/128 IP6 internal 0 rt3(4) -rt1 TE-IS 10 rt1 - rt3(4) -rt2 TE-IS 20 rt1 - rt1(4) -2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) -rt4 TE-IS 30 rt1 - rt2(4) -2001:db8::2/128 IP6 internal 30 rt1 - rt2(4) -rt5 TE-IS 40 rt1 - rt4(4) -2001:db8::4/128 IP6 internal 40 rt1 - rt4(4) -rt9 TE-IS 50 rt1 - rt5(4) -2001:db8::5/128 IP6 internal 50 rt1 - rt5(4) -rt6 TE-IS 60 rt1 - rt4(4) - rt9(4) -rt7 TE-IS 60 rt1 - rt4(4) - rt9(4) -rt8 TE-IS 60 rt1 - rt4(4) - rt9(4) -2001:db8::9/128 IP6 internal 60 rt1 - rt9(4) -2001:db8::6/128 IP6 internal 70 rt1 - rt6(4) -2001:db8::7/128 IP6 internal 70 rt1 - rt7(4) -2001:db8::8/128 IP6 internal 70 rt1 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt3 + 2001:db8::3/128 IP6 internal 0 rt3(4) + rt1 TE-IS 10 rt1 - rt3(4) + rt2 TE-IS 20 rt1 - rt1(4) + 2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) + rt4 TE-IS 30 rt1 - rt2(4) + 2001:db8::2/128 IP6 internal 30 rt1 - rt2(4) + rt5 TE-IS 40 rt1 - rt4(4) + 2001:db8::4/128 IP6 internal 40 rt1 - rt4(4) + rt9 TE-IS 50 rt1 - rt5(4) + 2001:db8::5/128 IP6 internal 50 rt1 - rt5(4) + rt6 TE-IS 60 rt1 - rt4(4) + rt9(4) + rt7 TE-IS 60 rt1 - rt4(4) + rt9(4) + rt8 TE-IS 60 rt1 - rt4(4) + rt9(4) + 2001:db8::9/128 IP6 internal 60 rt1 - rt9(4) + 2001:db8::6/128 IP6 internal 70 rt1 - rt6(4) + 2001:db8::7/128 IP6 internal 70 rt1 - rt7(4) + 2001:db8::8/128 IP6 internal 70 rt1 - rt8(4) + Main: IS-IS L1 IPv6 routing table: @@ -1377,23 +1455,25 @@ IS-IS L1 IPv6 routing table: test# test isis topology 10 root rt8 lfa system-id rt5 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt8 -10.0.255.8/32 IP internal 0 rt8(4) -rt5 TE-IS 10 rt5 - rt8(4) -rt2 TE-IS 20 rt5 - rt5(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -rt1 TE-IS 30 rt5 - rt2(4) -10.0.255.2/32 IP TE 30 rt5 - rt2(4) -10.0.255.1/32 IP TE 40 rt5 - rt1(4) -rt6 TE-IS 50 rt6 - rt8(4) -rt7 TE-IS 50 rt7 - rt8(4) -rt3 TE-IS 50 rt5 - rt1(4) -rt4 TE-IS 50 rt5 - rt1(4) -10.0.255.6/32 IP TE 60 rt6 - rt6(4) -10.0.255.7/32 IP TE 60 rt7 - rt7(4) -10.0.255.3/32 IP TE 60 rt5 - rt3(4) -10.0.255.4/32 IP TE 60 rt5 - rt4(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt8 + 10.0.255.8/32 IP internal 0 rt8(4) + rt5 TE-IS 10 rt5 - rt8(4) + rt2 TE-IS 20 rt5 - rt5(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + rt1 TE-IS 30 rt5 - rt2(4) + 10.0.255.2/32 IP TE 30 rt5 - rt2(4) + 10.0.255.1/32 IP TE 40 rt5 - rt1(4) + rt6 TE-IS 50 rt6 - rt8(4) + rt7 TE-IS 50 rt7 - rt8(4) + rt3 TE-IS 50 rt5 - rt1(4) + rt4 TE-IS 50 rt5 - rt1(4) + 10.0.255.6/32 IP TE 60 rt6 - rt6(4) + 10.0.255.7/32 IP TE 60 rt7 - rt7(4) + 10.0.255.3/32 IP TE 60 rt5 - rt3(4) + 10.0.255.4/32 IP TE 60 rt5 - rt4(4) + Main: IS-IS L1 IPv4 routing table: @@ -1426,23 +1506,25 @@ IS-IS L1 IPv4 routing table: - rt7 16050 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt8 -2001:db8::8/128 IP6 internal 0 rt8(4) -rt5 TE-IS 10 rt5 - rt8(4) -rt2 TE-IS 20 rt5 - rt5(4) -2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) -rt1 TE-IS 30 rt5 - rt2(4) -2001:db8::2/128 IP6 internal 30 rt5 - rt2(4) -2001:db8::1/128 IP6 internal 40 rt5 - rt1(4) -rt6 TE-IS 50 rt6 - rt8(4) -rt7 TE-IS 50 rt7 - rt8(4) -rt3 TE-IS 50 rt5 - rt1(4) -rt4 TE-IS 50 rt5 - rt1(4) -2001:db8::6/128 IP6 internal 60 rt6 - rt6(4) -2001:db8::7/128 IP6 internal 60 rt7 - rt7(4) -2001:db8::3/128 IP6 internal 60 rt5 - rt3(4) -2001:db8::4/128 IP6 internal 60 rt5 - rt4(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt8 + 2001:db8::8/128 IP6 internal 0 rt8(4) + rt5 TE-IS 10 rt5 - rt8(4) + rt2 TE-IS 20 rt5 - rt5(4) + 2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) + rt1 TE-IS 30 rt5 - rt2(4) + 2001:db8::2/128 IP6 internal 30 rt5 - rt2(4) + 2001:db8::1/128 IP6 internal 40 rt5 - rt1(4) + rt6 TE-IS 50 rt6 - rt8(4) + rt7 TE-IS 50 rt7 - rt8(4) + rt3 TE-IS 50 rt5 - rt1(4) + rt4 TE-IS 50 rt5 - rt1(4) + 2001:db8::6/128 IP6 internal 60 rt6 - rt6(4) + 2001:db8::7/128 IP6 internal 60 rt7 - rt7(4) + 2001:db8::3/128 IP6 internal 60 rt5 - rt3(4) + 2001:db8::4/128 IP6 internal 60 rt5 - rt4(4) + Main: IS-IS L1 IPv6 routing table: @@ -1476,22 +1558,24 @@ IS-IS L1 IPv6 routing table: test# test isis topology 11 root rt3 lfa system-id rt5 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt3 -10.0.255.3/32 IP internal 0 rt3(4) -rt1 TE-IS 10 rt1 - rt3(4) -rt2 TE-IS 10 rt2 - rt3(4) -rt5 TE-IS 10 rt5 - rt3(4) -rt2 pseudo_TE-IS 20 rt1 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) - rt5 - rt5(4) -rt6 TE-IS 20 rt5 - rt5(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) - rt5 - -10.0.255.6/32 IP TE 30 rt5 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt3 + 10.0.255.3/32 IP internal 0 rt3(4) + rt1 TE-IS 10 rt1 - rt3(4) + rt2 TE-IS 10 rt2 - rt3(4) + rt5 TE-IS 10 rt5 - rt3(4) + rt2 pseudo_TE-IS 20 rt1 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 - rt5(4) + rt6 TE-IS 20 rt5 - rt5(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt5 - rt4(4) + 10.0.255.6/32 IP TE 30 rt5 - rt6(4) + Main: IS-IS L1 IPv4 routing table: @@ -1515,22 +1599,24 @@ IS-IS L1 IPv4 routing table: 10.0.255.6/32 40 - rt2 16060 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt3 -2001:db8::3/128 IP6 internal 0 rt3(4) -rt1 TE-IS 10 rt1 - rt3(4) -rt2 TE-IS 10 rt2 - rt3(4) -rt5 TE-IS 10 rt5 - rt3(4) -rt2 pseudo_TE-IS 20 rt1 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) - rt5 - rt5(4) -rt6 TE-IS 20 rt5 - rt5(4) -2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) -2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) - rt5 - -2001:db8::6/128 IP6 internal 30 rt5 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt3 + 2001:db8::3/128 IP6 internal 0 rt3(4) + rt1 TE-IS 10 rt1 - rt3(4) + rt2 TE-IS 10 rt2 - rt3(4) + rt5 TE-IS 10 rt5 - rt3(4) + rt2 pseudo_TE-IS 20 rt1 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 - rt5(4) + rt6 TE-IS 20 rt5 - rt5(4) + 2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) + 2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) + rt5 - rt4(4) + 2001:db8::6/128 IP6 internal 30 rt5 - rt6(4) + Main: IS-IS L1 IPv6 routing table: @@ -1555,24 +1641,26 @@ IS-IS L1 IPv6 routing table: test# test isis topology 13 root rt4 lfa system-id rt3 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt4 -10.0.255.4/32 IP internal 0 rt4(4) -rt2 TE-IS 10 rt2 - rt4(4) -rt3 TE-IS 10 rt3 - rt4(4) -rt1 TE-IS 20 rt2 - rt2(4) - rt3 - rt3(4) -rt5 TE-IS 20 rt3 - rt3(4) -rt6 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt3 - rt5(4) - rt6(4) -10.0.255.1/32 IP TE 30 rt2 - rt1(4) - rt3 - -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 30 rt3 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt4 + 10.0.255.4/32 IP internal 0 rt4(4) + rt2 TE-IS 10 rt2 - rt4(4) + rt3 TE-IS 10 rt3 - rt4(4) + rt1 TE-IS 20 rt2 - rt2(4) + rt3 - rt3(4) + rt5 TE-IS 20 rt3 - rt3(4) + rt6 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt3 - rt5(4) + rt6(4) + 10.0.255.1/32 IP TE 30 rt2 - rt1(4) + rt3 - rt1(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 30 rt3 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + Main: IS-IS L1 IPv4 routing table: @@ -1599,11 +1687,13 @@ IS-IS L1 IPv4 routing table: 10.0.255.7/32 120 - rt5 16070 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt4 -rt2 TE-IS 10 rt2 - rt4(4) -rt3 TE-IS 10 rt3 - rt4(4) -rt5 TE-IS 100 rt5 - rt4(4) + Vertex Type Metric Next-Hop Interface Parent + ---------------------------------------------------- + rt4 + rt2 TE-IS 10 rt2 - rt4(4) + rt3 TE-IS 10 rt3 - rt4(4) + rt5 TE-IS 100 rt5 - rt4(4) + Main: IS-IS L1 IPv6 routing table: @@ -1613,18 +1703,20 @@ IS-IS L1 IPv6 routing table: test# test isis topology 14 root rt1 lfa system-id rt1 pseudonode-id 1 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt1 -rt5 TE-IS 20 rt4 - rt4(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.5/32 IP TE 30 rt4 - rt5(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt1 + rt5 TE-IS 20 rt4 - rt4(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.5/32 IP TE 30 rt4 - rt5(4) + Main: IS-IS L1 IPv4 routing table: @@ -1641,18 +1733,20 @@ Backup: IS-IS L1 IPv4 routing table: IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt1 -rt5 TE-IS 20 rt4 - rt4(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::5/128 IP6 internal 30 rt4 - rt5(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt1 + rt5 TE-IS 20 rt4 - rt4(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + 2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::5/128 IP6 internal 30 rt4 - rt5(4) + Main: IS-IS L1 IPv6 routing table: @@ -1670,18 +1764,20 @@ IS-IS L1 IPv6 routing table: test# test isis topology 14 root rt1 lfa system-id rt2 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt1 -rt5 TE-IS 20 rt4 - rt4(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.5/32 IP TE 30 rt4 - rt5(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt1 + rt5 TE-IS 20 rt4 - rt4(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.5/32 IP TE 30 rt4 - rt5(4) + Main: IS-IS L1 IPv4 routing table: @@ -1702,18 +1798,20 @@ IS-IS L1 IPv4 routing table: 10.0.255.2/32 30 - rt3 - IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt1 -rt5 TE-IS 20 rt4 - rt4(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::5/128 IP6 internal 30 rt4 - rt5(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt1 + rt5 TE-IS 20 rt4 - rt4(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + 2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::5/128 IP6 internal 30 rt4 - rt5(4) + Main: IS-IS L1 IPv6 routing table: @@ -1735,19 +1833,21 @@ IS-IS L1 IPv6 routing table: test# test isis topology 14 root rt5 lfa system-id rt4 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt1 pseudo_TE-IS 20 rt4 - rt4(4) -rt1 TE-IS 20 rt4 - rt1(2) -rt3 TE-IS 20 rt4 - rt1(2) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -rt2 TE-IS 30 rt4 - rt1(4) - rt3(4) -10.0.255.1/32 IP TE 30 rt4 - rt1(4) -10.0.255.3/32 IP TE 30 rt4 - rt3(4) -10.0.255.2/32 IP TE 40 rt4 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt1 pseudo_TE-IS 20 rt4 - rt4(4) + rt1 TE-IS 20 rt4 - rt1(2) + rt3 TE-IS 20 rt4 - rt1(2) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + rt2 TE-IS 30 rt4 - rt1(4) + rt3(4) + 10.0.255.1/32 IP TE 30 rt4 - rt1(4) + 10.0.255.3/32 IP TE 30 rt4 - rt3(4) + 10.0.255.2/32 IP TE 40 rt4 - rt2(4) + Main: IS-IS L1 IPv4 routing table: @@ -1771,19 +1871,21 @@ IS-IS L1 IPv4 routing table: 10.0.255.4/32 70 - rt3 - IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt5 -2001:db8::5/128 IP6 internal 0 rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt1 pseudo_TE-IS 20 rt4 - rt4(4) -rt1 TE-IS 20 rt4 - rt1(2) -rt3 TE-IS 20 rt4 - rt1(2) -2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) -rt2 TE-IS 30 rt4 - rt1(4) - rt3(4) -2001:db8::1/128 IP6 internal 30 rt4 - rt1(4) -2001:db8::3/128 IP6 internal 30 rt4 - rt3(4) -2001:db8::2/128 IP6 internal 40 rt4 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt5 + 2001:db8::5/128 IP6 internal 0 rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt1 pseudo_TE-IS 20 rt4 - rt4(4) + rt1 TE-IS 20 rt4 - rt1(2) + rt3 TE-IS 20 rt4 - rt1(2) + 2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) + rt2 TE-IS 30 rt4 - rt1(4) + rt3(4) + 2001:db8::1/128 IP6 internal 30 rt4 - rt1(4) + 2001:db8::3/128 IP6 internal 30 rt4 - rt3(4) + 2001:db8::2/128 IP6 internal 40 rt4 - rt2(4) + Main: IS-IS L1 IPv6 routing table: @@ -1823,36 +1925,40 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt3 - rt5(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt4 TE-IS 40 rt3 - rt6(4) -10.0.255.6/32 IP TE 40 rt3 - rt6(4) -rt2 TE-IS 50 rt3 - rt4(4) -10.0.255.4/32 IP TE 50 rt3 - rt4(4) -10.0.255.2/32 IP TE 60 rt3 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt3 - rt5(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt4 TE-IS 40 rt3 - rt6(4) + 10.0.255.6/32 IP TE 40 rt3 - rt6(4) + rt2 TE-IS 50 rt3 - rt4(4) + 10.0.255.4/32 IP TE 50 rt3 - rt4(4) + 10.0.255.2/32 IP TE 60 rt3 - rt2(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + rt3 - rt6(4) + Main: IS-IS L1 IPv4 routing table: @@ -1890,36 +1996,40 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt5 TE-IS 20 rt3 - rt3(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt6 TE-IS 30 rt3 - rt5(4) -2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) -rt4 TE-IS 40 rt3 - rt6(4) -2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) -rt2 TE-IS 50 rt3 - rt4(4) -2001:db8::4/128 IP6 internal 50 rt3 - rt4(4) -2001:db8::2/128 IP6 internal 60 rt3 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt5 TE-IS 20 rt3 - rt3(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt6 TE-IS 30 rt3 - rt5(4) + 2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) + rt4 TE-IS 40 rt3 - rt6(4) + 2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) + rt2 TE-IS 50 rt3 - rt4(4) + 2001:db8::4/128 IP6 internal 50 rt3 - rt4(4) + 2001:db8::2/128 IP6 internal 60 rt3 - rt2(4) + IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) - rt3 - rt5(4) -2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) -2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) -2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt3 - rt5(4) + 2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) + 2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) + 2001:db8::6/128 IP6 internal 40 rt2 - rt6(4) + rt3 - rt6(4) + Main: IS-IS L1 IPv6 routing table: @@ -1964,39 +2074,43 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt4 TE-IS 20 rt6 - rt6(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt1 pseudo_TE-IS 30 rt6 - rt4(4) -rt1 TE-IS 30 rt6 - rt1(2) -10.0.255.4/32 IP TE 30 rt6 - rt4(4) -rt3 TE-IS 40 rt3 - rt5(4) -10.0.255.1/32 IP TE 40 rt6 - rt1(4) -rt2 TE-IS 45 rt6 - rt1(4) -10.0.255.3/32 IP TE 50 rt3 - rt3(4) -10.0.255.2/32 IP TE 55 rt6 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt4 TE-IS 20 rt6 - rt6(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt1 pseudo_TE-IS 30 rt6 - rt4(4) + rt1 TE-IS 30 rt6 - rt1(2) + 10.0.255.4/32 IP TE 30 rt6 - rt4(4) + rt3 TE-IS 40 rt3 - rt5(4) + 10.0.255.1/32 IP TE 40 rt6 - rt1(4) + rt2 TE-IS 45 rt6 - rt1(4) + 10.0.255.3/32 IP TE 50 rt3 - rt3(4) + 10.0.255.2/32 IP TE 55 rt6 - rt2(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt1 TE-IS 10 rt1 - rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt1 pseudo_TE-IS 20 rt1 - rt1(4) - rt4 - rt4(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt2 TE-IS 25 rt1 - rt1(4) -10.0.255.2/32 IP TE 35 rt1 - rt2(4) -rt3 TE-IS 40 rt3 - rt5(4) - rt1 - rt1(4) -10.0.255.3/32 IP TE 50 rt3 - rt3(4) - rt1 - + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt1 TE-IS 10 rt1 - rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt1 pseudo_TE-IS 20 rt1 - rt1(4) + rt4 - rt4(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt2 TE-IS 25 rt1 - rt1(4) + 10.0.255.2/32 IP TE 35 rt1 - rt2(4) + rt3 TE-IS 40 rt3 - rt5(4) + rt1 - rt1(4) + 10.0.255.3/32 IP TE 50 rt3 - rt3(4) + rt1 - rt3(4) + Main: IS-IS L1 IPv4 routing table: @@ -2041,39 +2155,43 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt5 -2001:db8::5/128 IP6 internal 0 rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt4 TE-IS 20 rt6 - rt6(4) -2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) -rt1 pseudo_TE-IS 30 rt6 - rt4(4) -rt1 TE-IS 30 rt6 - rt1(2) -2001:db8::4/128 IP6 internal 30 rt6 - rt4(4) -rt3 TE-IS 40 rt3 - rt5(4) -2001:db8::1/128 IP6 internal 40 rt6 - rt1(4) -rt2 TE-IS 45 rt6 - rt1(4) -2001:db8::3/128 IP6 internal 50 rt3 - rt3(4) -2001:db8::2/128 IP6 internal 55 rt6 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt5 + 2001:db8::5/128 IP6 internal 0 rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt4 TE-IS 20 rt6 - rt6(4) + 2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) + rt1 pseudo_TE-IS 30 rt6 - rt4(4) + rt1 TE-IS 30 rt6 - rt1(2) + 2001:db8::4/128 IP6 internal 30 rt6 - rt4(4) + rt3 TE-IS 40 rt3 - rt5(4) + 2001:db8::1/128 IP6 internal 40 rt6 - rt1(4) + rt2 TE-IS 45 rt6 - rt1(4) + 2001:db8::3/128 IP6 internal 50 rt3 - rt3(4) + 2001:db8::2/128 IP6 internal 55 rt6 - rt2(4) + IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt5 -2001:db8::5/128 IP6 internal 0 rt5(4) -rt1 TE-IS 10 rt1 - rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt1 pseudo_TE-IS 20 rt1 - rt1(4) - rt4 - rt4(4) -2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) -2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) -2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) -rt2 TE-IS 25 rt1 - rt1(4) -2001:db8::2/128 IP6 internal 35 rt1 - rt2(4) -rt3 TE-IS 40 rt3 - rt5(4) - rt1 - rt1(4) -2001:db8::3/128 IP6 internal 50 rt3 - rt3(4) - rt1 - + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt5 + 2001:db8::5/128 IP6 internal 0 rt5(4) + rt1 TE-IS 10 rt1 - rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt1 pseudo_TE-IS 20 rt1 - rt1(4) + rt4 - rt4(4) + 2001:db8::1/128 IP6 internal 20 rt1 - rt1(4) + 2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) + 2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) + rt2 TE-IS 25 rt1 - rt1(4) + 2001:db8::2/128 IP6 internal 35 rt1 - rt2(4) + rt3 TE-IS 40 rt3 - rt5(4) + rt1 - rt1(4) + 2001:db8::3/128 IP6 internal 50 rt3 - rt3(4) + rt1 - rt3(4) + Main: IS-IS L1 IPv6 routing table: @@ -2123,38 +2241,42 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt4 TE-IS 20 rt6 - rt6(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt3 TE-IS 30 rt3 - rt5(4) -rt2 TE-IS 30 rt6 - rt4(4) -10.0.255.4/32 IP TE 30 rt6 - rt4(4) -rt1 TE-IS 40 rt3 - rt3(4) - rt6 - rt2(4) -10.0.255.3/32 IP TE 40 rt3 - rt3(4) -10.0.255.2/32 IP TE 40 rt6 - rt2(4) -10.0.255.1/32 IP TE 50 rt3 - rt1(4) - rt6 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt4 TE-IS 20 rt6 - rt6(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt3 TE-IS 30 rt3 - rt5(4) + rt2 TE-IS 30 rt6 - rt4(4) + 10.0.255.4/32 IP TE 30 rt6 - rt4(4) + rt1 TE-IS 40 rt3 - rt3(4) + rt6 - rt2(4) + 10.0.255.3/32 IP TE 40 rt3 - rt3(4) + 10.0.255.2/32 IP TE 40 rt6 - rt2(4) + 10.0.255.1/32 IP TE 50 rt3 - rt1(4) + rt6 - rt1(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt2 TE-IS 20 rt4 - rt4(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt3 TE-IS 30 rt3 - rt5(4) - rt4 - rt2(4) -rt1 TE-IS 30 rt4 - rt2(4) -10.0.255.2/32 IP TE 30 rt4 - rt2(4) -10.0.255.3/32 IP TE 40 rt3 - rt3(4) - rt4 - -10.0.255.1/32 IP TE 40 rt4 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt2 TE-IS 20 rt4 - rt4(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt3 TE-IS 30 rt3 - rt5(4) + rt4 - rt2(4) + rt1 TE-IS 30 rt4 - rt2(4) + 10.0.255.2/32 IP TE 30 rt4 - rt2(4) + 10.0.255.3/32 IP TE 40 rt3 - rt3(4) + rt4 - rt3(4) + 10.0.255.1/32 IP TE 40 rt4 - rt1(4) + Main: IS-IS L1 IPv4 routing table: @@ -2210,36 +2332,40 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt2 TE-IS 20 rt4 - rt4(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt1 TE-IS 30 rt4 - rt2(4) -rt3 TE-IS 30 rt4 - rt2(4) -10.0.255.2/32 IP TE 30 rt4 - rt2(4) -10.0.255.1/32 IP TE 40 rt4 - rt1(4) -10.0.255.3/32 IP TE 40 rt4 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt2 TE-IS 20 rt4 - rt4(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt1 TE-IS 30 rt4 - rt2(4) + rt3 TE-IS 30 rt4 - rt2(4) + 10.0.255.2/32 IP TE 30 rt4 - rt2(4) + 10.0.255.1/32 IP TE 40 rt4 - rt1(4) + 10.0.255.3/32 IP TE 40 rt4 - rt3(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt2 TE-IS 20 rt4 - rt4(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt3 TE-IS 30 rt3 - rt5(4) - rt4 - rt2(4) -rt1 TE-IS 30 rt4 - rt2(4) -10.0.255.2/32 IP TE 30 rt4 - rt2(4) -10.0.255.3/32 IP TE 40 rt3 - rt3(4) - rt4 - -10.0.255.1/32 IP TE 40 rt4 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt2 TE-IS 20 rt4 - rt4(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt3 TE-IS 30 rt3 - rt5(4) + rt4 - rt2(4) + rt1 TE-IS 30 rt4 - rt2(4) + 10.0.255.2/32 IP TE 30 rt4 - rt2(4) + 10.0.255.3/32 IP TE 40 rt3 - rt3(4) + rt4 - rt3(4) + 10.0.255.1/32 IP TE 40 rt4 - rt1(4) + Main: IS-IS L1 IPv4 routing table: @@ -2276,44 +2402,48 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt8 TE-IS 40 rt3 - rt7(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -rt6 TE-IS 50 rt3 - rt8(4) -10.0.255.8/32 IP TE 50 rt3 - rt8(4) -rt4 TE-IS 60 rt3 - rt6(4) -10.0.255.6/32 IP TE 60 rt3 - rt6(4) -rt2 TE-IS 70 rt3 - rt4(4) -10.0.255.4/32 IP TE 70 rt3 - rt4(4) -10.0.255.2/32 IP TE 80 rt3 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt8 TE-IS 40 rt3 - rt7(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + rt6 TE-IS 50 rt3 - rt8(4) + 10.0.255.8/32 IP TE 50 rt3 - rt8(4) + rt4 TE-IS 60 rt3 - rt6(4) + 10.0.255.6/32 IP TE 60 rt3 - rt6(4) + rt2 TE-IS 70 rt3 - rt4(4) + 10.0.255.4/32 IP TE 70 rt3 - rt4(4) + 10.0.255.2/32 IP TE 80 rt3 - rt2(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt2 - rt4(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt8 TE-IS 40 rt2 - rt6(4) - rt3 - rt7(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -10.0.255.8/32 IP TE 50 rt2 - rt8(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt2 - rt4(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt8 TE-IS 40 rt2 - rt6(4) + rt3 - rt7(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + 10.0.255.8/32 IP TE 50 rt2 - rt8(4) + rt3 - rt8(4) + Main: IS-IS L1 IPv4 routing table: @@ -2362,46 +2492,50 @@ Q-space: rt3 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt4 -10.0.255.4/32 IP internal 0 rt4(4) -rt2 TE-IS 10 rt2 - rt4(4) -rt6 TE-IS 10 rt6 - rt4(4) -rt1 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt6 - rt6(4) -rt8 TE-IS 20 rt6 - rt6(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt3 TE-IS 30 rt2 - rt1(4) -rt7 TE-IS 30 rt6 - rt5(4) - rt8(4) -10.0.255.1/32 IP TE 30 rt2 - rt1(4) -10.0.255.5/32 IP TE 30 rt6 - rt5(4) -10.0.255.8/32 IP TE 30 rt6 - rt8(4) -10.0.255.3/32 IP TE 40 rt2 - rt3(4) -10.0.255.7/32 IP TE 40 rt6 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt4 + 10.0.255.4/32 IP internal 0 rt4(4) + rt2 TE-IS 10 rt2 - rt4(4) + rt6 TE-IS 10 rt6 - rt4(4) + rt1 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt6 - rt6(4) + rt8 TE-IS 20 rt6 - rt6(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt3 TE-IS 30 rt2 - rt1(4) + rt7 TE-IS 30 rt6 - rt5(4) + rt8(4) + 10.0.255.1/32 IP TE 30 rt2 - rt1(4) + 10.0.255.5/32 IP TE 30 rt6 - rt5(4) + 10.0.255.8/32 IP TE 30 rt6 - rt8(4) + 10.0.255.3/32 IP TE 40 rt2 - rt3(4) + 10.0.255.7/32 IP TE 40 rt6 - rt7(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt4 -10.0.255.4/32 IP internal 0 rt4(4) -rt2 TE-IS 10 rt2 - rt4(4) -rt3 TE-IS 10 rt3 - rt4(4) -rt6 TE-IS 10 rt6 - rt4(4) -rt1 TE-IS 20 rt2 - rt2(4) - rt3 - rt3(4) -rt5 TE-IS 20 rt6 - rt6(4) -rt8 TE-IS 20 rt6 - rt6(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt7 TE-IS 30 rt6 - rt5(4) - rt8(4) -10.0.255.1/32 IP TE 30 rt2 - rt1(4) - rt3 - -10.0.255.5/32 IP TE 30 rt6 - rt5(4) -10.0.255.8/32 IP TE 30 rt6 - rt8(4) -10.0.255.7/32 IP TE 40 rt6 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt4 + 10.0.255.4/32 IP internal 0 rt4(4) + rt2 TE-IS 10 rt2 - rt4(4) + rt3 TE-IS 10 rt3 - rt4(4) + rt6 TE-IS 10 rt6 - rt4(4) + rt1 TE-IS 20 rt2 - rt2(4) + rt3 - rt3(4) + rt5 TE-IS 20 rt6 - rt6(4) + rt8 TE-IS 20 rt6 - rt6(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt7 TE-IS 30 rt6 - rt5(4) + rt8(4) + 10.0.255.1/32 IP TE 30 rt2 - rt1(4) + rt3 - rt1(4) + 10.0.255.5/32 IP TE 30 rt6 - rt5(4) + 10.0.255.8/32 IP TE 30 rt6 - rt8(4) + 10.0.255.7/32 IP TE 40 rt6 - rt7(4) + Main: IS-IS L1 IPv4 routing table: @@ -2452,64 +2586,68 @@ Q-space: rt9 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt11 -10.0.255.11/32 IP internal 0 rt11(4) -rt10 TE-IS 10 rt10 - rt11(4) -rt12 TE-IS 10 rt12 - rt11(4) -rt9 TE-IS 20 rt12 - rt12(4) -10.0.255.10/32 IP TE 20 rt10 - rt10(4) -10.0.255.12/32 IP TE 20 rt12 - rt12(4) -rt7 TE-IS 30 rt10 - rt10(4) -rt8 TE-IS 30 rt12 - rt9(4) -10.0.255.9/32 IP TE 30 rt12 - rt9(4) -rt4 TE-IS 40 rt10 - rt7(4) -rt5 TE-IS 40 rt12 - rt8(4) -10.0.255.7/32 IP TE 40 rt10 - rt7(4) -10.0.255.8/32 IP TE 40 rt12 - rt8(4) -rt6 TE-IS 50 rt12 - rt9(4) - rt5(4) -rt1 TE-IS 50 rt10 - rt4(4) -rt2 TE-IS 50 rt12 - rt5(4) -10.0.255.4/32 IP TE 50 rt10 - rt4(4) -10.0.255.5/32 IP TE 50 rt12 - rt5(4) -rt3 TE-IS 60 rt12 - rt6(4) - rt2(4) -10.0.255.6/32 IP TE 60 rt12 - rt6(4) -10.0.255.1/32 IP TE 60 rt10 - rt1(4) -10.0.255.2/32 IP TE 60 rt12 - rt2(4) -10.0.255.3/32 IP TE 70 rt12 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt11 + 10.0.255.11/32 IP internal 0 rt11(4) + rt10 TE-IS 10 rt10 - rt11(4) + rt12 TE-IS 10 rt12 - rt11(4) + rt9 TE-IS 20 rt12 - rt12(4) + 10.0.255.10/32 IP TE 20 rt10 - rt10(4) + 10.0.255.12/32 IP TE 20 rt12 - rt12(4) + rt7 TE-IS 30 rt10 - rt10(4) + rt8 TE-IS 30 rt12 - rt9(4) + 10.0.255.9/32 IP TE 30 rt12 - rt9(4) + rt4 TE-IS 40 rt10 - rt7(4) + rt5 TE-IS 40 rt12 - rt8(4) + 10.0.255.7/32 IP TE 40 rt10 - rt7(4) + 10.0.255.8/32 IP TE 40 rt12 - rt8(4) + rt6 TE-IS 50 rt12 - rt9(4) + rt5(4) + rt1 TE-IS 50 rt10 - rt4(4) + rt2 TE-IS 50 rt12 - rt5(4) + 10.0.255.4/32 IP TE 50 rt10 - rt4(4) + 10.0.255.5/32 IP TE 50 rt12 - rt5(4) + rt3 TE-IS 60 rt12 - rt6(4) + rt2(4) + 10.0.255.6/32 IP TE 60 rt12 - rt6(4) + 10.0.255.1/32 IP TE 60 rt10 - rt1(4) + 10.0.255.2/32 IP TE 60 rt12 - rt2(4) + 10.0.255.3/32 IP TE 70 rt12 - rt3(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt11 -10.0.255.11/32 IP internal 0 rt11(4) -rt8 TE-IS 10 rt8 - rt11(4) -rt10 TE-IS 10 rt10 - rt11(4) -rt12 TE-IS 10 rt12 - rt11(4) -rt5 TE-IS 20 rt8 - rt8(4) -rt7 TE-IS 20 rt8 - rt8(4) -rt9 TE-IS 20 rt8 - rt8(4) - rt12 - rt12(4) -10.0.255.8/32 IP TE 20 rt8 - rt8(4) -10.0.255.10/32 IP TE 20 rt10 - rt10(4) -10.0.255.12/32 IP TE 20 rt12 - rt12(4) -rt2 TE-IS 30 rt8 - rt5(4) -rt4 TE-IS 30 rt8 - rt5(4) - rt7(4) -rt6 TE-IS 30 rt8 - rt5(4) -10.0.255.5/32 IP TE 30 rt8 - rt5(4) -10.0.255.7/32 IP TE 30 rt8 - rt7(4) -10.0.255.9/32 IP TE 30 rt8 - rt9(4) - rt12 - -rt3 TE-IS 40 rt8 - rt2(4) - rt6(4) -rt1 TE-IS 40 rt8 - rt4(4) -10.0.255.2/32 IP TE 40 rt8 - rt2(4) -10.0.255.4/32 IP TE 40 rt8 - rt4(4) -10.0.255.6/32 IP TE 40 rt8 - rt6(4) -10.0.255.3/32 IP TE 50 rt8 - rt3(4) -10.0.255.1/32 IP TE 50 rt8 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt11 + 10.0.255.11/32 IP internal 0 rt11(4) + rt8 TE-IS 10 rt8 - rt11(4) + rt10 TE-IS 10 rt10 - rt11(4) + rt12 TE-IS 10 rt12 - rt11(4) + rt5 TE-IS 20 rt8 - rt8(4) + rt7 TE-IS 20 rt8 - rt8(4) + rt9 TE-IS 20 rt8 - rt8(4) + rt12 - rt12(4) + 10.0.255.8/32 IP TE 20 rt8 - rt8(4) + 10.0.255.10/32 IP TE 20 rt10 - rt10(4) + 10.0.255.12/32 IP TE 20 rt12 - rt12(4) + rt2 TE-IS 30 rt8 - rt5(4) + rt4 TE-IS 30 rt8 - rt5(4) + rt7(4) + rt6 TE-IS 30 rt8 - rt5(4) + 10.0.255.5/32 IP TE 30 rt8 - rt5(4) + 10.0.255.7/32 IP TE 30 rt8 - rt7(4) + 10.0.255.9/32 IP TE 30 rt8 - rt9(4) + rt12 - rt9(4) + rt3 TE-IS 40 rt8 - rt2(4) + rt6(4) + rt1 TE-IS 40 rt8 - rt4(4) + 10.0.255.2/32 IP TE 40 rt8 - rt2(4) + 10.0.255.4/32 IP TE 40 rt8 - rt4(4) + 10.0.255.6/32 IP TE 40 rt8 - rt6(4) + 10.0.255.3/32 IP TE 50 rt8 - rt3(4) + 10.0.255.1/32 IP TE 50 rt8 - rt1(4) + Main: IS-IS L1 IPv4 routing table: @@ -2577,73 +2715,77 @@ Q-space: rt12 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt6 -10.0.255.6/32 IP internal 0 rt6(4) -rt3 TE-IS 10 rt3 - rt6(4) -rt2 TE-IS 20 rt3 - rt3(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt9 TE-IS 30 rt9 - rt6(4) -rt5 TE-IS 30 rt3 - rt2(4) -10.0.255.2/32 IP TE 30 rt3 - rt2(4) -rt8 TE-IS 40 rt9 - rt9(4) - rt3 - rt5(4) -rt12 TE-IS 40 rt9 - rt9(4) -rt4 TE-IS 40 rt3 - rt5(4) -10.0.255.9/32 IP TE 40 rt9 - rt9(4) -10.0.255.5/32 IP TE 40 rt3 - rt5(4) -rt7 TE-IS 50 rt9 - rt8(4) - rt3 - rt4(4) -rt11 TE-IS 50 rt9 - rt8(4) - rt3 - rt12(4) -rt1 TE-IS 50 rt3 - rt4(4) -10.0.255.8/32 IP TE 50 rt9 - rt8(4) - rt3 - -10.0.255.12/32 IP TE 50 rt9 - rt12(4) -10.0.255.4/32 IP TE 50 rt3 - rt4(4) -rt10 TE-IS 60 rt9 - rt11(4) - rt3 - -10.0.255.7/32 IP TE 60 rt9 - rt7(4) - rt3 - -10.0.255.11/32 IP TE 60 rt9 - rt11(4) - rt3 - -10.0.255.1/32 IP TE 60 rt3 - rt1(4) -10.0.255.10/32 IP TE 70 rt9 - rt10(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt6 + 10.0.255.6/32 IP internal 0 rt6(4) + rt3 TE-IS 10 rt3 - rt6(4) + rt2 TE-IS 20 rt3 - rt3(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt9 TE-IS 30 rt9 - rt6(4) + rt5 TE-IS 30 rt3 - rt2(4) + 10.0.255.2/32 IP TE 30 rt3 - rt2(4) + rt8 TE-IS 40 rt9 - rt9(4) + rt3 - rt5(4) + rt12 TE-IS 40 rt9 - rt9(4) + rt4 TE-IS 40 rt3 - rt5(4) + 10.0.255.9/32 IP TE 40 rt9 - rt9(4) + 10.0.255.5/32 IP TE 40 rt3 - rt5(4) + rt7 TE-IS 50 rt9 - rt8(4) + rt3 - rt4(4) + rt11 TE-IS 50 rt9 - rt8(4) + rt3 - rt12(4) + rt1 TE-IS 50 rt3 - rt4(4) + 10.0.255.8/32 IP TE 50 rt9 - rt8(4) + rt3 - rt8(4) + 10.0.255.12/32 IP TE 50 rt9 - rt12(4) + 10.0.255.4/32 IP TE 50 rt3 - rt4(4) + rt10 TE-IS 60 rt9 - rt11(4) + rt3 - rt11(4) + 10.0.255.7/32 IP TE 60 rt9 - rt7(4) + rt3 - rt7(4) + 10.0.255.11/32 IP TE 60 rt9 - rt11(4) + rt3 - rt11(4) + 10.0.255.1/32 IP TE 60 rt3 - rt1(4) + 10.0.255.10/32 IP TE 70 rt9 - rt10(4) + rt3 - rt10(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt6 -10.0.255.6/32 IP internal 0 rt6(4) -rt3 TE-IS 10 rt3 - rt6(4) -rt5 TE-IS 10 rt5 - rt6(4) -rt2 TE-IS 20 rt3 - rt3(4) - rt5 - rt5(4) -rt4 TE-IS 20 rt5 - rt5(4) -rt8 TE-IS 20 rt5 - rt5(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -rt9 TE-IS 30 rt9 - rt6(4) - rt5 - rt8(4) -rt1 TE-IS 30 rt5 - rt4(4) -rt7 TE-IS 30 rt5 - rt4(4) - rt8(4) -rt11 TE-IS 30 rt5 - rt8(4) -10.0.255.2/32 IP TE 30 rt3 - rt2(4) - rt5 - -10.0.255.4/32 IP TE 30 rt5 - rt4(4) -10.0.255.8/32 IP TE 30 rt5 - rt8(4) -rt12 TE-IS 40 rt9 - rt9(4) - rt5 - rt11(4) -rt10 TE-IS 40 rt5 - rt11(4) -10.0.255.9/32 IP TE 40 rt9 - rt9(4) - rt5 - -10.0.255.1/32 IP TE 40 rt5 - rt1(4) -10.0.255.7/32 IP TE 40 rt5 - rt7(4) -10.0.255.11/32 IP TE 40 rt5 - rt11(4) -10.0.255.12/32 IP TE 50 rt9 - rt12(4) - rt5 - -10.0.255.10/32 IP TE 50 rt5 - rt10(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt6 + 10.0.255.6/32 IP internal 0 rt6(4) + rt3 TE-IS 10 rt3 - rt6(4) + rt5 TE-IS 10 rt5 - rt6(4) + rt2 TE-IS 20 rt3 - rt3(4) + rt5 - rt5(4) + rt4 TE-IS 20 rt5 - rt5(4) + rt8 TE-IS 20 rt5 - rt5(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + rt9 TE-IS 30 rt9 - rt6(4) + rt5 - rt8(4) + rt1 TE-IS 30 rt5 - rt4(4) + rt7 TE-IS 30 rt5 - rt4(4) + rt8(4) + rt11 TE-IS 30 rt5 - rt8(4) + 10.0.255.2/32 IP TE 30 rt3 - rt2(4) + rt5 - rt2(4) + 10.0.255.4/32 IP TE 30 rt5 - rt4(4) + 10.0.255.8/32 IP TE 30 rt5 - rt8(4) + rt12 TE-IS 40 rt9 - rt9(4) + rt5 - rt11(4) + rt10 TE-IS 40 rt5 - rt11(4) + 10.0.255.9/32 IP TE 40 rt9 - rt9(4) + rt5 - rt9(4) + 10.0.255.1/32 IP TE 40 rt5 - rt1(4) + 10.0.255.7/32 IP TE 40 rt5 - rt7(4) + 10.0.255.11/32 IP TE 40 rt5 - rt11(4) + 10.0.255.12/32 IP TE 50 rt9 - rt12(4) + rt5 - rt12(4) + 10.0.255.10/32 IP TE 50 rt5 - rt10(4) + Main: IS-IS L1 IPv4 routing table: @@ -2706,62 +2848,66 @@ Q-space: rt12 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt2 -10.0.255.2/32 IP internal 0 rt2(4) -rt1 TE-IS 10 rt1 - rt2(4) -rt3 TE-IS 10 rt3 - rt2(4) -rt4 TE-IS 20 rt1 - rt1(4) -rt6 TE-IS 20 rt3 - rt3(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt1 - rt4(4) -rt5 TE-IS 30 rt3 - rt6(4) -10.0.255.4/32 IP TE 30 rt1 - rt4(4) -10.0.255.6/32 IP TE 30 rt3 - rt6(4) -rt10 TE-IS 40 rt1 - rt7(4) -rt8 TE-IS 40 rt3 - rt5(4) -10.0.255.7/32 IP TE 40 rt1 - rt7(4) -10.0.255.5/32 IP TE 40 rt3 - rt5(4) -rt9 TE-IS 50 rt3 - rt8(4) -rt11 TE-IS 50 rt3 - rt8(4) -10.0.255.10/32 IP TE 50 rt1 - rt10(4) -10.0.255.8/32 IP TE 50 rt3 - rt8(4) -rt12 TE-IS 60 rt3 - rt9(4) - rt11(4) -10.0.255.9/32 IP TE 60 rt3 - rt9(4) -10.0.255.11/32 IP TE 60 rt3 - rt11(4) -10.0.255.12/32 IP TE 70 rt3 - rt12(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt2 + 10.0.255.2/32 IP internal 0 rt2(4) + rt1 TE-IS 10 rt1 - rt2(4) + rt3 TE-IS 10 rt3 - rt2(4) + rt4 TE-IS 20 rt1 - rt1(4) + rt6 TE-IS 20 rt3 - rt3(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt1 - rt4(4) + rt5 TE-IS 30 rt3 - rt6(4) + 10.0.255.4/32 IP TE 30 rt1 - rt4(4) + 10.0.255.6/32 IP TE 30 rt3 - rt6(4) + rt10 TE-IS 40 rt1 - rt7(4) + rt8 TE-IS 40 rt3 - rt5(4) + 10.0.255.7/32 IP TE 40 rt1 - rt7(4) + 10.0.255.5/32 IP TE 40 rt3 - rt5(4) + rt9 TE-IS 50 rt3 - rt8(4) + rt11 TE-IS 50 rt3 - rt8(4) + 10.0.255.10/32 IP TE 50 rt1 - rt10(4) + 10.0.255.8/32 IP TE 50 rt3 - rt8(4) + rt12 TE-IS 60 rt3 - rt9(4) + rt11(4) + 10.0.255.9/32 IP TE 60 rt3 - rt9(4) + 10.0.255.11/32 IP TE 60 rt3 - rt11(4) + 10.0.255.12/32 IP TE 70 rt3 - rt12(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt2 -10.0.255.2/32 IP internal 0 rt2(4) -rt1 TE-IS 10 rt1 - rt2(4) -rt3 TE-IS 10 rt3 - rt2(4) -rt5 TE-IS 10 rt5 - rt2(4) -rt4 TE-IS 20 rt1 - rt1(4) -rt6 TE-IS 20 rt3 - rt3(4) - rt5 - rt5(4) -rt8 TE-IS 20 rt5 - rt5(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -rt7 TE-IS 30 rt1 - rt4(4) -rt9 TE-IS 30 rt5 - rt8(4) -rt11 TE-IS 30 rt5 - rt8(4) -10.0.255.4/32 IP TE 30 rt1 - rt4(4) -10.0.255.6/32 IP TE 30 rt3 - rt6(4) - rt5 - -10.0.255.8/32 IP TE 30 rt5 - rt8(4) -rt10 TE-IS 40 rt1 - rt7(4) -rt12 TE-IS 40 rt5 - rt9(4) - rt11(4) -10.0.255.7/32 IP TE 40 rt1 - rt7(4) -10.0.255.9/32 IP TE 40 rt5 - rt9(4) -10.0.255.11/32 IP TE 40 rt5 - rt11(4) -10.0.255.10/32 IP TE 50 rt1 - rt10(4) -10.0.255.12/32 IP TE 50 rt5 - rt12(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt2 + 10.0.255.2/32 IP internal 0 rt2(4) + rt1 TE-IS 10 rt1 - rt2(4) + rt3 TE-IS 10 rt3 - rt2(4) + rt5 TE-IS 10 rt5 - rt2(4) + rt4 TE-IS 20 rt1 - rt1(4) + rt6 TE-IS 20 rt3 - rt3(4) + rt5 - rt5(4) + rt8 TE-IS 20 rt5 - rt5(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + rt7 TE-IS 30 rt1 - rt4(4) + rt9 TE-IS 30 rt5 - rt8(4) + rt11 TE-IS 30 rt5 - rt8(4) + 10.0.255.4/32 IP TE 30 rt1 - rt4(4) + 10.0.255.6/32 IP TE 30 rt3 - rt6(4) + rt5 - rt6(4) + 10.0.255.8/32 IP TE 30 rt5 - rt8(4) + rt10 TE-IS 40 rt1 - rt7(4) + rt12 TE-IS 40 rt5 - rt9(4) + rt11(4) + 10.0.255.7/32 IP TE 40 rt1 - rt7(4) + 10.0.255.9/32 IP TE 40 rt5 - rt9(4) + 10.0.255.11/32 IP TE 40 rt5 - rt11(4) + 10.0.255.10/32 IP TE 50 rt1 - rt10(4) + 10.0.255.12/32 IP TE 50 rt5 - rt12(4) + Main: IS-IS L1 IPv4 routing table: @@ -2815,36 +2961,40 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt2 -10.0.255.2/32 IP internal 0 rt2(4) -rt1 TE-IS 50 rt1 - rt2(4) -rt3 TE-IS 50 rt3 - rt2(4) -rt2 -rt5 TE-IS 60 rt3 - rt3(4) -10.0.255.1/32 IP TE 60 rt1 - rt1(4) -10.0.255.3/32 IP TE 60 rt3 - rt3(4) -rt4 TE-IS 70 rt3 - rt5(4) -rt6 TE-IS 70 rt3 - rt5(4) -10.0.255.5/32 IP TE 70 rt3 - rt5(4) -10.0.255.4/32 IP TE 80 rt3 - rt4(4) -10.0.255.6/32 IP TE 80 rt3 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt2 + 10.0.255.2/32 IP internal 0 rt2(4) + rt1 TE-IS 50 rt1 - rt2(4) + rt3 TE-IS 50 rt3 - rt2(4) + rt2 + rt5 TE-IS 60 rt3 - rt3(4) + 10.0.255.1/32 IP TE 60 rt1 - rt1(4) + 10.0.255.3/32 IP TE 60 rt3 - rt3(4) + rt4 TE-IS 70 rt3 - rt5(4) + rt6 TE-IS 70 rt3 - rt5(4) + 10.0.255.5/32 IP TE 70 rt3 - rt5(4) + 10.0.255.4/32 IP TE 80 rt3 - rt4(4) + 10.0.255.6/32 IP TE 80 rt3 - rt6(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt2 -10.0.255.2/32 IP internal 0 rt2(4) -rt4 TE-IS 10 rt4 - rt2(4) -rt5 TE-IS 20 rt4 - rt4(4) -rt6 TE-IS 20 rt4 - rt4(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -rt3 TE-IS 30 rt4 - rt5(4) -10.0.255.5/32 IP TE 30 rt4 - rt5(4) -10.0.255.6/32 IP TE 30 rt4 - rt6(4) -rt2 -rt1 TE-IS 40 rt4 - rt2(2) -10.0.255.3/32 IP TE 40 rt4 - rt3(4) -10.0.255.1/32 IP TE 50 rt4 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt2 + 10.0.255.2/32 IP internal 0 rt2(4) + rt4 TE-IS 10 rt4 - rt2(4) + rt5 TE-IS 20 rt4 - rt4(4) + rt6 TE-IS 20 rt4 - rt4(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + rt3 TE-IS 30 rt4 - rt5(4) + 10.0.255.5/32 IP TE 30 rt4 - rt5(4) + 10.0.255.6/32 IP TE 30 rt4 - rt6(4) + rt2 + rt1 TE-IS 40 rt4 - rt2(2) + 10.0.255.3/32 IP TE 40 rt4 - rt3(4) + 10.0.255.1/32 IP TE 50 rt4 - rt1(4) + Main: IS-IS L1 IPv4 routing table: @@ -2893,36 +3043,40 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt2 -2001:db8::2/128 IP6 internal 0 rt2(4) -rt1 TE-IS 50 rt1 - rt2(4) -rt3 TE-IS 50 rt3 - rt2(4) -rt2 -rt5 TE-IS 60 rt3 - rt3(4) -2001:db8::1/128 IP6 internal 60 rt1 - rt1(4) -2001:db8::3/128 IP6 internal 60 rt3 - rt3(4) -rt4 TE-IS 70 rt3 - rt5(4) -rt6 TE-IS 70 rt3 - rt5(4) -2001:db8::5/128 IP6 internal 70 rt3 - rt5(4) -2001:db8::4/128 IP6 internal 80 rt3 - rt4(4) -2001:db8::6/128 IP6 internal 80 rt3 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt2 + 2001:db8::2/128 IP6 internal 0 rt2(4) + rt1 TE-IS 50 rt1 - rt2(4) + rt3 TE-IS 50 rt3 - rt2(4) + rt2 + rt5 TE-IS 60 rt3 - rt3(4) + 2001:db8::1/128 IP6 internal 60 rt1 - rt1(4) + 2001:db8::3/128 IP6 internal 60 rt3 - rt3(4) + rt4 TE-IS 70 rt3 - rt5(4) + rt6 TE-IS 70 rt3 - rt5(4) + 2001:db8::5/128 IP6 internal 70 rt3 - rt5(4) + 2001:db8::4/128 IP6 internal 80 rt3 - rt4(4) + 2001:db8::6/128 IP6 internal 80 rt3 - rt6(4) + IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt2 -2001:db8::2/128 IP6 internal 0 rt2(4) -rt4 TE-IS 10 rt4 - rt2(4) -rt5 TE-IS 20 rt4 - rt4(4) -rt6 TE-IS 20 rt4 - rt4(4) -2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) -rt3 TE-IS 30 rt4 - rt5(4) -2001:db8::5/128 IP6 internal 30 rt4 - rt5(4) -2001:db8::6/128 IP6 internal 30 rt4 - rt6(4) -rt2 -rt1 TE-IS 40 rt4 - rt2(2) -2001:db8::3/128 IP6 internal 40 rt4 - rt3(4) -2001:db8::1/128 IP6 internal 50 rt4 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt2 + 2001:db8::2/128 IP6 internal 0 rt2(4) + rt4 TE-IS 10 rt4 - rt2(4) + rt5 TE-IS 20 rt4 - rt4(4) + rt6 TE-IS 20 rt4 - rt4(4) + 2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) + rt3 TE-IS 30 rt4 - rt5(4) + 2001:db8::5/128 IP6 internal 30 rt4 - rt5(4) + 2001:db8::6/128 IP6 internal 30 rt4 - rt6(4) + rt2 + rt1 TE-IS 40 rt4 - rt2(2) + 2001:db8::3/128 IP6 internal 40 rt4 - rt3(4) + 2001:db8::1/128 IP6 internal 50 rt4 - rt1(4) + Main: IS-IS L1 IPv6 routing table: @@ -2966,42 +3120,46 @@ Q-space: rt7 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -rt3 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -rt5 TE-IS 40 rt2 - rt3(4) -rt6 TE-IS 40 rt2 - rt3(4) -10.0.255.3/32 IP TE 40 rt2 - rt3(4) -rt7 TE-IS 50 rt2 - rt5(4) - rt6(4) -10.0.255.5/32 IP TE 50 rt2 - rt5(4) -10.0.255.6/32 IP TE 50 rt2 - rt6(4) -10.0.255.7/32 IP TE 60 rt2 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + rt3 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt5 TE-IS 40 rt2 - rt3(4) + rt6 TE-IS 40 rt2 - rt3(4) + 10.0.255.3/32 IP TE 40 rt2 - rt3(4) + rt7 TE-IS 50 rt2 - rt5(4) + rt6(4) + 10.0.255.5/32 IP TE 50 rt2 - rt5(4) + 10.0.255.6/32 IP TE 50 rt2 - rt6(4) + 10.0.255.7/32 IP TE 60 rt2 - rt7(4) + IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) - rt3 - rt3(4) -rt5 TE-IS 20 rt3 - rt3(4) -rt6 TE-IS 20 rt3 - rt3(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt3 - rt5(4) - rt6(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) - rt3 - -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.6/32 IP TE 30 rt3 - rt6(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + rt3 - rt3(4) + rt5 TE-IS 20 rt3 - rt3(4) + rt6 TE-IS 20 rt3 - rt3(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt3 - rt5(4) + rt6(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt3 - rt4(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.6/32 IP TE 30 rt3 - rt6(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + Main: IS-IS L1 IPv4 routing table: @@ -3044,19 +3202,21 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt6 TE-IS 30 rt3 - rt5(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt4 TE-IS 40 rt3 - rt6(4) -10.0.255.6/32 IP TE 40 rt3 - rt6(4) -rt2 TE-IS 50 rt3 - rt4(4) -10.0.255.4/32 IP TE 50 rt3 - rt4(4) -10.0.255.2/32 IP TE 60 rt3 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt6 TE-IS 30 rt3 - rt5(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt4 TE-IS 40 rt3 - rt6(4) + 10.0.255.6/32 IP TE 40 rt3 - rt6(4) + rt2 TE-IS 50 rt3 - rt4(4) + 10.0.255.4/32 IP TE 50 rt3 - rt4(4) + 10.0.255.2/32 IP TE 60 rt3 - rt2(4) + IS-IS L1 IPv4 routing table: @@ -3080,19 +3240,21 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt5 TE-IS 20 rt3 - rt3(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt6 TE-IS 30 rt3 - rt5(4) -2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) -rt4 TE-IS 40 rt3 - rt6(4) -2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) -rt2 TE-IS 50 rt3 - rt4(4) -2001:db8::4/128 IP6 internal 50 rt3 - rt4(4) -2001:db8::2/128 IP6 internal 60 rt3 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt5 TE-IS 20 rt3 - rt3(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt6 TE-IS 30 rt3 - rt5(4) + 2001:db8::5/128 IP6 internal 30 rt3 - rt5(4) + rt4 TE-IS 40 rt3 - rt6(4) + 2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) + rt2 TE-IS 50 rt3 - rt4(4) + 2001:db8::4/128 IP6 internal 50 rt3 - rt4(4) + 2001:db8::2/128 IP6 internal 60 rt3 - rt2(4) + IS-IS L1 IPv6 routing table: @@ -3127,22 +3289,24 @@ Q-space: rt3 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt5 TE-IS 10 rt5 - rt1(4) -rt2 TE-IS 15 rt2 - rt1(4) -rt1 -rt6 TE-IS 20 rt4 - rt4(4) - rt5 - rt5(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -10.0.255.2/32 IP TE 25 rt2 - rt2(4) -10.0.255.6/32 IP TE 30 rt4 - rt6(4) - rt5 - -rt3 TE-IS 50 rt5 - rt5(4) -10.0.255.3/32 IP TE 60 rt5 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt5 TE-IS 10 rt5 - rt1(4) + rt2 TE-IS 15 rt2 - rt1(4) + rt1 + rt6 TE-IS 20 rt4 - rt4(4) + rt5 - rt5(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + 10.0.255.2/32 IP TE 25 rt2 - rt2(4) + 10.0.255.6/32 IP TE 30 rt4 - rt6(4) + rt5 - rt6(4) + rt3 TE-IS 50 rt5 - rt5(4) + 10.0.255.3/32 IP TE 60 rt5 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -3175,22 +3339,24 @@ Q-space: rt3 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt4 TE-IS 10 rt4 - rt1(4) -rt5 TE-IS 10 rt5 - rt1(4) -rt2 TE-IS 15 rt2 - rt1(4) -rt1 -rt6 TE-IS 20 rt4 - rt4(4) - rt5 - rt5(4) -2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) -2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) -2001:db8::2/128 IP6 internal 25 rt2 - rt2(4) -2001:db8::6/128 IP6 internal 30 rt4 - rt6(4) - rt5 - -rt3 TE-IS 50 rt5 - rt5(4) -2001:db8::3/128 IP6 internal 60 rt5 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt4 TE-IS 10 rt4 - rt1(4) + rt5 TE-IS 10 rt5 - rt1(4) + rt2 TE-IS 15 rt2 - rt1(4) + rt1 + rt6 TE-IS 20 rt4 - rt4(4) + rt5 - rt5(4) + 2001:db8::4/128 IP6 internal 20 rt4 - rt4(4) + 2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) + 2001:db8::2/128 IP6 internal 25 rt2 - rt2(4) + 2001:db8::6/128 IP6 internal 30 rt4 - rt6(4) + rt5 - rt6(4) + rt3 TE-IS 50 rt5 - rt5(4) + 2001:db8::3/128 IP6 internal 60 rt5 - rt3(4) + IS-IS L1 IPv6 routing table: @@ -3217,20 +3383,22 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 15 rt2 - rt1(4) -10.0.255.2/32 IP TE 25 rt2 - rt2(4) -rt3 TE-IS 30 rt3 - rt1(4) -10.0.255.3/32 IP TE 40 rt3 - rt3(4) -rt4 TE-IS 55 rt2 - rt2(4) -rt1 -rt6 TE-IS 65 rt2 - rt4(4) -rt5 TE-IS 65 rt2 - rt1(2) -10.0.255.4/32 IP TE 65 rt2 - rt4(4) -10.0.255.6/32 IP TE 75 rt2 - rt6(4) -10.0.255.5/32 IP TE 75 rt2 - rt5(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 15 rt2 - rt1(4) + 10.0.255.2/32 IP TE 25 rt2 - rt2(4) + rt3 TE-IS 30 rt3 - rt1(4) + 10.0.255.3/32 IP TE 40 rt3 - rt3(4) + rt4 TE-IS 55 rt2 - rt2(4) + rt1 + rt6 TE-IS 65 rt2 - rt4(4) + rt5 TE-IS 65 rt2 - rt1(2) + 10.0.255.4/32 IP TE 65 rt2 - rt4(4) + 10.0.255.6/32 IP TE 75 rt2 - rt6(4) + 10.0.255.5/32 IP TE 75 rt2 - rt5(4) + IS-IS L1 IPv4 routing table: @@ -3258,20 +3426,22 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 15 rt2 - rt1(4) -2001:db8::2/128 IP6 internal 25 rt2 - rt2(4) -rt3 TE-IS 30 rt3 - rt1(4) -2001:db8::3/128 IP6 internal 40 rt3 - rt3(4) -rt4 TE-IS 55 rt2 - rt2(4) -rt1 -rt6 TE-IS 65 rt2 - rt4(4) -rt5 TE-IS 65 rt2 - rt1(2) -2001:db8::4/128 IP6 internal 65 rt2 - rt4(4) -2001:db8::6/128 IP6 internal 75 rt2 - rt6(4) -2001:db8::5/128 IP6 internal 75 rt2 - rt5(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 15 rt2 - rt1(4) + 2001:db8::2/128 IP6 internal 25 rt2 - rt2(4) + rt3 TE-IS 30 rt3 - rt1(4) + 2001:db8::3/128 IP6 internal 40 rt3 - rt3(4) + rt4 TE-IS 55 rt2 - rt2(4) + rt1 + rt6 TE-IS 65 rt2 - rt4(4) + rt5 TE-IS 65 rt2 - rt1(2) + 2001:db8::4/128 IP6 internal 65 rt2 - rt4(4) + 2001:db8::6/128 IP6 internal 75 rt2 - rt6(4) + 2001:db8::5/128 IP6 internal 75 rt2 - rt5(4) + IS-IS L1 IPv6 routing table: @@ -3303,20 +3473,22 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt4 TE-IS 20 rt6 - rt6(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt1 pseudo_TE-IS 30 rt6 - rt4(4) -rt1 TE-IS 30 rt6 - rt1(2) -10.0.255.4/32 IP TE 30 rt6 - rt4(4) -rt3 TE-IS 40 rt3 - rt5(4) -10.0.255.1/32 IP TE 40 rt6 - rt1(4) -rt2 TE-IS 45 rt6 - rt1(4) -10.0.255.3/32 IP TE 50 rt3 - rt3(4) -10.0.255.2/32 IP TE 55 rt6 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------ + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt4 TE-IS 20 rt6 - rt6(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt1 pseudo_TE-IS 30 rt6 - rt4(4) + rt1 TE-IS 30 rt6 - rt1(2) + 10.0.255.4/32 IP TE 30 rt6 - rt4(4) + rt3 TE-IS 40 rt3 - rt5(4) + 10.0.255.1/32 IP TE 40 rt6 - rt1(4) + rt2 TE-IS 45 rt6 - rt1(4) + 10.0.255.3/32 IP TE 50 rt3 - rt3(4) + 10.0.255.2/32 IP TE 55 rt6 - rt2(4) + IS-IS L1 IPv4 routing table: @@ -3347,20 +3519,22 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt5 -2001:db8::5/128 IP6 internal 0 rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt4 TE-IS 20 rt6 - rt6(4) -2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) -rt1 pseudo_TE-IS 30 rt6 - rt4(4) -rt1 TE-IS 30 rt6 - rt1(2) -2001:db8::4/128 IP6 internal 30 rt6 - rt4(4) -rt3 TE-IS 40 rt3 - rt5(4) -2001:db8::1/128 IP6 internal 40 rt6 - rt1(4) -rt2 TE-IS 45 rt6 - rt1(4) -2001:db8::3/128 IP6 internal 50 rt3 - rt3(4) -2001:db8::2/128 IP6 internal 55 rt6 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt5 + 2001:db8::5/128 IP6 internal 0 rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt4 TE-IS 20 rt6 - rt6(4) + 2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) + rt1 pseudo_TE-IS 30 rt6 - rt4(4) + rt1 TE-IS 30 rt6 - rt1(2) + 2001:db8::4/128 IP6 internal 30 rt6 - rt4(4) + rt3 TE-IS 40 rt3 - rt5(4) + 2001:db8::1/128 IP6 internal 40 rt6 - rt1(4) + rt2 TE-IS 45 rt6 - rt1(4) + 2001:db8::3/128 IP6 internal 50 rt3 - rt3(4) + 2001:db8::2/128 IP6 internal 55 rt6 - rt2(4) + IS-IS L1 IPv6 routing table: @@ -3396,21 +3570,23 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt4 TE-IS 20 rt6 - rt6(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt3 TE-IS 30 rt3 - rt5(4) -rt2 TE-IS 30 rt6 - rt4(4) -10.0.255.4/32 IP TE 30 rt6 - rt4(4) -rt1 TE-IS 40 rt3 - rt3(4) - rt6 - rt2(4) -10.0.255.3/32 IP TE 40 rt3 - rt3(4) -10.0.255.2/32 IP TE 40 rt6 - rt2(4) -10.0.255.1/32 IP TE 50 rt3 - rt1(4) - rt6 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt4 TE-IS 20 rt6 - rt6(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt3 TE-IS 30 rt3 - rt5(4) + rt2 TE-IS 30 rt6 - rt4(4) + 10.0.255.4/32 IP TE 30 rt6 - rt4(4) + rt1 TE-IS 40 rt3 - rt3(4) + rt6 - rt2(4) + 10.0.255.3/32 IP TE 40 rt3 - rt3(4) + 10.0.255.2/32 IP TE 40 rt6 - rt2(4) + 10.0.255.1/32 IP TE 50 rt3 - rt1(4) + rt6 - rt1(4) + IS-IS L1 IPv4 routing table: @@ -3450,19 +3626,21 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt5 -10.0.255.5/32 IP internal 0 rt5(4) -rt4 TE-IS 10 rt4 - rt5(4) -rt6 TE-IS 10 rt6 - rt5(4) -rt2 TE-IS 20 rt4 - rt4(4) -10.0.255.4/32 IP TE 20 rt4 - rt4(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt1 TE-IS 30 rt4 - rt2(4) -rt3 TE-IS 30 rt4 - rt2(4) -10.0.255.2/32 IP TE 30 rt4 - rt2(4) -10.0.255.1/32 IP TE 40 rt4 - rt1(4) -10.0.255.3/32 IP TE 40 rt4 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt5 + 10.0.255.5/32 IP internal 0 rt5(4) + rt4 TE-IS 10 rt4 - rt5(4) + rt6 TE-IS 10 rt6 - rt5(4) + rt2 TE-IS 20 rt4 - rt4(4) + 10.0.255.4/32 IP TE 20 rt4 - rt4(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt1 TE-IS 30 rt4 - rt2(4) + rt3 TE-IS 30 rt4 - rt2(4) + 10.0.255.2/32 IP TE 30 rt4 - rt2(4) + 10.0.255.1/32 IP TE 40 rt4 - rt1(4) + 10.0.255.3/32 IP TE 40 rt4 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -3484,23 +3662,25 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -rt6 TE-IS 70 rt3 - rt5(4) -rt4 TE-IS 80 rt3 - rt6(4) -rt8 TE-IS 80 rt3 - rt6(4) -10.0.255.6/32 IP TE 80 rt3 - rt6(4) -rt2 TE-IS 90 rt3 - rt4(4) -10.0.255.4/32 IP TE 90 rt3 - rt4(4) -10.0.255.8/32 IP TE 90 rt3 - rt8(4) -10.0.255.2/32 IP TE 100 rt3 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + rt6 TE-IS 70 rt3 - rt5(4) + rt4 TE-IS 80 rt3 - rt6(4) + rt8 TE-IS 80 rt3 - rt6(4) + 10.0.255.6/32 IP TE 80 rt3 - rt6(4) + rt2 TE-IS 90 rt3 - rt4(4) + 10.0.255.4/32 IP TE 90 rt3 - rt4(4) + 10.0.255.8/32 IP TE 90 rt3 - rt8(4) + 10.0.255.2/32 IP TE 100 rt3 - rt2(4) + IS-IS L1 IPv4 routing table: @@ -3531,23 +3711,25 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt4 -10.0.255.4/32 IP internal 0 rt4(4) -rt2 TE-IS 10 rt2 - rt4(4) -rt1 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -rt3 TE-IS 30 rt2 - rt1(4) -10.0.255.1/32 IP TE 30 rt2 - rt1(4) -rt5 TE-IS 40 rt2 - rt3(4) -10.0.255.3/32 IP TE 40 rt2 - rt3(4) -rt7 TE-IS 50 rt2 - rt5(4) -10.0.255.5/32 IP TE 50 rt2 - rt5(4) -10.0.255.7/32 IP TE 60 rt2 - rt7(4) -rt6 TE-IS 90 rt2 - rt5(4) -rt8 TE-IS 100 rt2 - rt6(4) -10.0.255.6/32 IP TE 100 rt2 - rt6(4) -10.0.255.8/32 IP TE 110 rt2 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt4 + 10.0.255.4/32 IP internal 0 rt4(4) + rt2 TE-IS 10 rt2 - rt4(4) + rt1 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + rt3 TE-IS 30 rt2 - rt1(4) + 10.0.255.1/32 IP TE 30 rt2 - rt1(4) + rt5 TE-IS 40 rt2 - rt3(4) + 10.0.255.3/32 IP TE 40 rt2 - rt3(4) + rt7 TE-IS 50 rt2 - rt5(4) + 10.0.255.5/32 IP TE 50 rt2 - rt5(4) + 10.0.255.7/32 IP TE 60 rt2 - rt7(4) + rt6 TE-IS 90 rt2 - rt5(4) + rt8 TE-IS 100 rt2 - rt6(4) + 10.0.255.6/32 IP TE 100 rt2 - rt6(4) + 10.0.255.8/32 IP TE 110 rt2 - rt8(4) + IS-IS L1 IPv4 routing table: @@ -3575,23 +3757,25 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -rt5 TE-IS 20 rt3 - rt3(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt3 - rt5(4) -10.0.255.5/32 IP TE 30 rt3 - rt5(4) -rt8 TE-IS 40 rt3 - rt7(4) -10.0.255.7/32 IP TE 40 rt3 - rt7(4) -rt6 TE-IS 50 rt3 - rt8(4) -10.0.255.8/32 IP TE 50 rt3 - rt8(4) -rt4 TE-IS 60 rt3 - rt6(4) -10.0.255.6/32 IP TE 60 rt3 - rt6(4) -rt2 TE-IS 70 rt3 - rt4(4) -10.0.255.4/32 IP TE 70 rt3 - rt4(4) -10.0.255.2/32 IP TE 80 rt3 - rt2(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + rt5 TE-IS 20 rt3 - rt3(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt3 - rt5(4) + 10.0.255.5/32 IP TE 30 rt3 - rt5(4) + rt8 TE-IS 40 rt3 - rt7(4) + 10.0.255.7/32 IP TE 40 rt3 - rt7(4) + rt6 TE-IS 50 rt3 - rt8(4) + 10.0.255.8/32 IP TE 50 rt3 - rt8(4) + rt4 TE-IS 60 rt3 - rt6(4) + 10.0.255.6/32 IP TE 60 rt3 - rt6(4) + rt2 TE-IS 70 rt3 - rt4(4) + 10.0.255.4/32 IP TE 70 rt3 - rt4(4) + 10.0.255.2/32 IP TE 80 rt3 - rt2(4) + IS-IS L1 IPv4 routing table: @@ -3624,24 +3808,26 @@ Q-space: rt3 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt4 -10.0.255.4/32 IP internal 0 rt4(4) -rt2 TE-IS 10 rt2 - rt4(4) -rt6 TE-IS 10 rt6 - rt4(4) -rt1 TE-IS 20 rt2 - rt2(4) -rt5 TE-IS 20 rt6 - rt6(4) -rt8 TE-IS 20 rt6 - rt6(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -rt3 TE-IS 30 rt2 - rt1(4) -rt7 TE-IS 30 rt6 - rt5(4) - rt8(4) -10.0.255.1/32 IP TE 30 rt2 - rt1(4) -10.0.255.5/32 IP TE 30 rt6 - rt5(4) -10.0.255.8/32 IP TE 30 rt6 - rt8(4) -10.0.255.3/32 IP TE 40 rt2 - rt3(4) -10.0.255.7/32 IP TE 40 rt6 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt4 + 10.0.255.4/32 IP internal 0 rt4(4) + rt2 TE-IS 10 rt2 - rt4(4) + rt6 TE-IS 10 rt6 - rt4(4) + rt1 TE-IS 20 rt2 - rt2(4) + rt5 TE-IS 20 rt6 - rt6(4) + rt8 TE-IS 20 rt6 - rt6(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + rt3 TE-IS 30 rt2 - rt1(4) + rt7 TE-IS 30 rt6 - rt5(4) + rt8(4) + 10.0.255.1/32 IP TE 30 rt2 - rt1(4) + 10.0.255.5/32 IP TE 30 rt6 - rt5(4) + 10.0.255.8/32 IP TE 30 rt6 - rt8(4) + 10.0.255.3/32 IP TE 40 rt2 - rt3(4) + 10.0.255.7/32 IP TE 40 rt6 - rt7(4) + IS-IS L1 IPv4 routing table: @@ -3676,33 +3862,35 @@ Q-space: rt9 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt11 -10.0.255.11/32 IP internal 0 rt11(4) -rt10 TE-IS 10 rt10 - rt11(4) -rt12 TE-IS 10 rt12 - rt11(4) -rt9 TE-IS 20 rt12 - rt12(4) -10.0.255.10/32 IP TE 20 rt10 - rt10(4) -10.0.255.12/32 IP TE 20 rt12 - rt12(4) -rt7 TE-IS 30 rt10 - rt10(4) -rt8 TE-IS 30 rt12 - rt9(4) -10.0.255.9/32 IP TE 30 rt12 - rt9(4) -rt4 TE-IS 40 rt10 - rt7(4) -rt5 TE-IS 40 rt12 - rt8(4) -10.0.255.7/32 IP TE 40 rt10 - rt7(4) -10.0.255.8/32 IP TE 40 rt12 - rt8(4) -rt6 TE-IS 50 rt12 - rt9(4) - rt5(4) -rt1 TE-IS 50 rt10 - rt4(4) -rt2 TE-IS 50 rt12 - rt5(4) -10.0.255.4/32 IP TE 50 rt10 - rt4(4) -10.0.255.5/32 IP TE 50 rt12 - rt5(4) -rt3 TE-IS 60 rt12 - rt6(4) - rt2(4) -10.0.255.6/32 IP TE 60 rt12 - rt6(4) -10.0.255.1/32 IP TE 60 rt10 - rt1(4) -10.0.255.2/32 IP TE 60 rt12 - rt2(4) -10.0.255.3/32 IP TE 70 rt12 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt11 + 10.0.255.11/32 IP internal 0 rt11(4) + rt10 TE-IS 10 rt10 - rt11(4) + rt12 TE-IS 10 rt12 - rt11(4) + rt9 TE-IS 20 rt12 - rt12(4) + 10.0.255.10/32 IP TE 20 rt10 - rt10(4) + 10.0.255.12/32 IP TE 20 rt12 - rt12(4) + rt7 TE-IS 30 rt10 - rt10(4) + rt8 TE-IS 30 rt12 - rt9(4) + 10.0.255.9/32 IP TE 30 rt12 - rt9(4) + rt4 TE-IS 40 rt10 - rt7(4) + rt5 TE-IS 40 rt12 - rt8(4) + 10.0.255.7/32 IP TE 40 rt10 - rt7(4) + 10.0.255.8/32 IP TE 40 rt12 - rt8(4) + rt6 TE-IS 50 rt12 - rt9(4) + rt5(4) + rt1 TE-IS 50 rt10 - rt4(4) + rt2 TE-IS 50 rt12 - rt5(4) + 10.0.255.4/32 IP TE 50 rt10 - rt4(4) + 10.0.255.5/32 IP TE 50 rt12 - rt5(4) + rt3 TE-IS 60 rt12 - rt6(4) + rt2(4) + 10.0.255.6/32 IP TE 60 rt12 - rt6(4) + 10.0.255.1/32 IP TE 60 rt10 - rt1(4) + 10.0.255.2/32 IP TE 60 rt12 - rt2(4) + 10.0.255.3/32 IP TE 70 rt12 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -3750,39 +3938,41 @@ Q-space: rt12 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt6 -10.0.255.6/32 IP internal 0 rt6(4) -rt3 TE-IS 10 rt3 - rt6(4) -rt2 TE-IS 20 rt3 - rt3(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt9 TE-IS 30 rt9 - rt6(4) -rt5 TE-IS 30 rt3 - rt2(4) -10.0.255.2/32 IP TE 30 rt3 - rt2(4) -rt8 TE-IS 40 rt9 - rt9(4) - rt3 - rt5(4) -rt12 TE-IS 40 rt9 - rt9(4) -rt4 TE-IS 40 rt3 - rt5(4) -10.0.255.9/32 IP TE 40 rt9 - rt9(4) -10.0.255.5/32 IP TE 40 rt3 - rt5(4) -rt7 TE-IS 50 rt9 - rt8(4) - rt3 - rt4(4) -rt11 TE-IS 50 rt9 - rt8(4) - rt3 - rt12(4) -rt1 TE-IS 50 rt3 - rt4(4) -10.0.255.8/32 IP TE 50 rt9 - rt8(4) - rt3 - -10.0.255.12/32 IP TE 50 rt9 - rt12(4) -10.0.255.4/32 IP TE 50 rt3 - rt4(4) -rt10 TE-IS 60 rt9 - rt11(4) - rt3 - -10.0.255.7/32 IP TE 60 rt9 - rt7(4) - rt3 - -10.0.255.11/32 IP TE 60 rt9 - rt11(4) - rt3 - -10.0.255.1/32 IP TE 60 rt3 - rt1(4) -10.0.255.10/32 IP TE 70 rt9 - rt10(4) - rt3 - + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt6 + 10.0.255.6/32 IP internal 0 rt6(4) + rt3 TE-IS 10 rt3 - rt6(4) + rt2 TE-IS 20 rt3 - rt3(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt9 TE-IS 30 rt9 - rt6(4) + rt5 TE-IS 30 rt3 - rt2(4) + 10.0.255.2/32 IP TE 30 rt3 - rt2(4) + rt8 TE-IS 40 rt9 - rt9(4) + rt3 - rt5(4) + rt12 TE-IS 40 rt9 - rt9(4) + rt4 TE-IS 40 rt3 - rt5(4) + 10.0.255.9/32 IP TE 40 rt9 - rt9(4) + 10.0.255.5/32 IP TE 40 rt3 - rt5(4) + rt7 TE-IS 50 rt9 - rt8(4) + rt3 - rt4(4) + rt11 TE-IS 50 rt9 - rt8(4) + rt3 - rt12(4) + rt1 TE-IS 50 rt3 - rt4(4) + 10.0.255.8/32 IP TE 50 rt9 - rt8(4) + rt3 - rt8(4) + 10.0.255.12/32 IP TE 50 rt9 - rt12(4) + 10.0.255.4/32 IP TE 50 rt3 - rt4(4) + rt10 TE-IS 60 rt9 - rt11(4) + rt3 - rt11(4) + 10.0.255.7/32 IP TE 60 rt9 - rt7(4) + rt3 - rt7(4) + 10.0.255.11/32 IP TE 60 rt9 - rt11(4) + rt3 - rt11(4) + 10.0.255.1/32 IP TE 60 rt3 - rt1(4) + 10.0.255.10/32 IP TE 70 rt9 - rt10(4) + rt3 - rt10(4) + IS-IS L1 IPv4 routing table: @@ -3829,34 +4019,36 @@ Q-space: rt10 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt2 -10.0.255.2/32 IP internal 0 rt2(4) -rt3 TE-IS 10 rt3 - rt2(4) -rt5 TE-IS 10 rt5 - rt2(4) -rt6 TE-IS 20 rt3 - rt3(4) - rt5 - rt5(4) -rt8 TE-IS 20 rt5 - rt5(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -rt9 TE-IS 30 rt5 - rt8(4) -rt11 TE-IS 30 rt5 - rt8(4) -10.0.255.6/32 IP TE 30 rt3 - rt6(4) - rt5 - -10.0.255.8/32 IP TE 30 rt5 - rt8(4) -rt12 TE-IS 40 rt5 - rt9(4) - rt11(4) -10.0.255.9/32 IP TE 40 rt5 - rt9(4) -10.0.255.11/32 IP TE 40 rt5 - rt11(4) -10.0.255.12/32 IP TE 50 rt5 - rt12(4) -rt10 TE-IS 60 rt5 - rt11(4) -rt7 TE-IS 70 rt5 - rt10(4) -10.0.255.10/32 IP TE 70 rt5 - rt10(4) -rt4 TE-IS 80 rt5 - rt7(4) -10.0.255.7/32 IP TE 80 rt5 - rt7(4) -rt1 TE-IS 90 rt5 - rt4(4) -10.0.255.4/32 IP TE 90 rt5 - rt4(4) -10.0.255.1/32 IP TE 100 rt5 - rt1(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt2 + 10.0.255.2/32 IP internal 0 rt2(4) + rt3 TE-IS 10 rt3 - rt2(4) + rt5 TE-IS 10 rt5 - rt2(4) + rt6 TE-IS 20 rt3 - rt3(4) + rt5 - rt5(4) + rt8 TE-IS 20 rt5 - rt5(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + rt9 TE-IS 30 rt5 - rt8(4) + rt11 TE-IS 30 rt5 - rt8(4) + 10.0.255.6/32 IP TE 30 rt3 - rt6(4) + rt5 - rt6(4) + 10.0.255.8/32 IP TE 30 rt5 - rt8(4) + rt12 TE-IS 40 rt5 - rt9(4) + rt11(4) + 10.0.255.9/32 IP TE 40 rt5 - rt9(4) + 10.0.255.11/32 IP TE 40 rt5 - rt11(4) + 10.0.255.12/32 IP TE 50 rt5 - rt12(4) + rt10 TE-IS 60 rt5 - rt11(4) + rt7 TE-IS 70 rt5 - rt10(4) + 10.0.255.10/32 IP TE 70 rt5 - rt10(4) + rt4 TE-IS 80 rt5 - rt7(4) + 10.0.255.7/32 IP TE 80 rt5 - rt7(4) + rt1 TE-IS 90 rt5 - rt4(4) + 10.0.255.4/32 IP TE 90 rt5 - rt4(4) + 10.0.255.1/32 IP TE 100 rt5 - rt1(4) + IS-IS L1 IPv4 routing table: @@ -3894,32 +4086,34 @@ Q-space: rt12 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt2 -10.0.255.2/32 IP internal 0 rt2(4) -rt1 TE-IS 10 rt1 - rt2(4) -rt3 TE-IS 10 rt3 - rt2(4) -rt4 TE-IS 20 rt1 - rt1(4) -rt6 TE-IS 20 rt3 - rt3(4) -10.0.255.1/32 IP TE 20 rt1 - rt1(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt7 TE-IS 30 rt1 - rt4(4) -rt5 TE-IS 30 rt3 - rt6(4) -10.0.255.4/32 IP TE 30 rt1 - rt4(4) -10.0.255.6/32 IP TE 30 rt3 - rt6(4) -rt10 TE-IS 40 rt1 - rt7(4) -rt8 TE-IS 40 rt3 - rt5(4) -10.0.255.7/32 IP TE 40 rt1 - rt7(4) -10.0.255.5/32 IP TE 40 rt3 - rt5(4) -rt9 TE-IS 50 rt3 - rt8(4) -rt11 TE-IS 50 rt3 - rt8(4) -10.0.255.10/32 IP TE 50 rt1 - rt10(4) -10.0.255.8/32 IP TE 50 rt3 - rt8(4) -rt12 TE-IS 60 rt3 - rt9(4) - rt11(4) -10.0.255.9/32 IP TE 60 rt3 - rt9(4) -10.0.255.11/32 IP TE 60 rt3 - rt11(4) -10.0.255.12/32 IP TE 70 rt3 - rt12(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt2 + 10.0.255.2/32 IP internal 0 rt2(4) + rt1 TE-IS 10 rt1 - rt2(4) + rt3 TE-IS 10 rt3 - rt2(4) + rt4 TE-IS 20 rt1 - rt1(4) + rt6 TE-IS 20 rt3 - rt3(4) + 10.0.255.1/32 IP TE 20 rt1 - rt1(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt7 TE-IS 30 rt1 - rt4(4) + rt5 TE-IS 30 rt3 - rt6(4) + 10.0.255.4/32 IP TE 30 rt1 - rt4(4) + 10.0.255.6/32 IP TE 30 rt3 - rt6(4) + rt10 TE-IS 40 rt1 - rt7(4) + rt8 TE-IS 40 rt3 - rt5(4) + 10.0.255.7/32 IP TE 40 rt1 - rt7(4) + 10.0.255.5/32 IP TE 40 rt3 - rt5(4) + rt9 TE-IS 50 rt3 - rt8(4) + rt11 TE-IS 50 rt3 - rt8(4) + 10.0.255.10/32 IP TE 50 rt1 - rt10(4) + 10.0.255.8/32 IP TE 50 rt3 - rt8(4) + rt12 TE-IS 60 rt3 - rt9(4) + rt11(4) + 10.0.255.9/32 IP TE 60 rt3 - rt9(4) + 10.0.255.11/32 IP TE 60 rt3 - rt11(4) + 10.0.255.12/32 IP TE 70 rt3 - rt12(4) + IS-IS L1 IPv4 routing table: @@ -3954,28 +4148,30 @@ Q-space: rt3 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -rt5 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -rt9 TE-IS 40 rt2 - rt5(4) -10.0.255.5/32 IP TE 40 rt2 - rt5(4) -rt6 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt7 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt8 TE-IS 50 rt2 - rt4(4) - rt9(4) -10.0.255.9/32 IP TE 50 rt2 - rt9(4) -10.0.255.6/32 IP TE 60 rt2 - rt6(4) -10.0.255.7/32 IP TE 60 rt2 - rt7(4) -10.0.255.8/32 IP TE 60 rt2 - rt8(4) -rt3 TE-IS 120 rt2 - rt4(4) -10.0.255.3/32 IP TE 130 rt2 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + rt5 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt9 TE-IS 40 rt2 - rt5(4) + 10.0.255.5/32 IP TE 40 rt2 - rt5(4) + rt6 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt7 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt8 TE-IS 50 rt2 - rt4(4) + rt9(4) + 10.0.255.9/32 IP TE 50 rt2 - rt9(4) + 10.0.255.6/32 IP TE 60 rt2 - rt6(4) + 10.0.255.7/32 IP TE 60 rt2 - rt7(4) + 10.0.255.8/32 IP TE 60 rt2 - rt8(4) + rt3 TE-IS 120 rt2 - rt4(4) + 10.0.255.3/32 IP TE 130 rt2 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -4005,28 +4201,30 @@ Q-space: rt3 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -rt5 TE-IS 30 rt2 - rt4(4) -2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) -rt9 TE-IS 40 rt2 - rt5(4) -2001:db8::5/128 IP6 internal 40 rt2 - rt5(4) -rt6 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt7 TE-IS 50 rt2 - rt4(4) - rt9(4) -rt8 TE-IS 50 rt2 - rt4(4) - rt9(4) -2001:db8::9/128 IP6 internal 50 rt2 - rt9(4) -2001:db8::6/128 IP6 internal 60 rt2 - rt6(4) -2001:db8::7/128 IP6 internal 60 rt2 - rt7(4) -2001:db8::8/128 IP6 internal 60 rt2 - rt8(4) -rt3 TE-IS 120 rt2 - rt4(4) -2001:db8::3/128 IP6 internal 130 rt2 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + rt5 TE-IS 30 rt2 - rt4(4) + 2001:db8::4/128 IP6 internal 30 rt2 - rt4(4) + rt9 TE-IS 40 rt2 - rt5(4) + 2001:db8::5/128 IP6 internal 40 rt2 - rt5(4) + rt6 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt7 TE-IS 50 rt2 - rt4(4) + rt9(4) + rt8 TE-IS 50 rt2 - rt4(4) + rt9(4) + 2001:db8::9/128 IP6 internal 50 rt2 - rt9(4) + 2001:db8::6/128 IP6 internal 60 rt2 - rt6(4) + 2001:db8::7/128 IP6 internal 60 rt2 - rt7(4) + 2001:db8::8/128 IP6 internal 60 rt2 - rt8(4) + rt3 TE-IS 120 rt2 - rt4(4) + 2001:db8::3/128 IP6 internal 130 rt2 - rt3(4) + IS-IS L1 IPv6 routing table: @@ -4051,28 +4249,30 @@ Q-space: rt9 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -10.0.255.3/32 IP TE 20 rt3 - rt3(4) -rt4 TE-IS 110 rt3 - rt3(4) -rt2 TE-IS 120 rt3 - rt4(4) -rt5 TE-IS 120 rt3 - rt4(4) -10.0.255.4/32 IP TE 120 rt3 - rt4(4) -rt9 TE-IS 130 rt3 - rt5(4) -10.0.255.2/32 IP TE 130 rt3 - rt2(4) -10.0.255.5/32 IP TE 130 rt3 - rt5(4) -rt6 TE-IS 140 rt3 - rt4(4) - rt9(4) -rt7 TE-IS 140 rt3 - rt4(4) - rt9(4) -rt8 TE-IS 140 rt3 - rt4(4) - rt9(4) -10.0.255.9/32 IP TE 140 rt3 - rt9(4) -10.0.255.6/32 IP TE 150 rt3 - rt6(4) -10.0.255.7/32 IP TE 150 rt3 - rt7(4) -10.0.255.8/32 IP TE 150 rt3 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + 10.0.255.3/32 IP TE 20 rt3 - rt3(4) + rt4 TE-IS 110 rt3 - rt3(4) + rt2 TE-IS 120 rt3 - rt4(4) + rt5 TE-IS 120 rt3 - rt4(4) + 10.0.255.4/32 IP TE 120 rt3 - rt4(4) + rt9 TE-IS 130 rt3 - rt5(4) + 10.0.255.2/32 IP TE 130 rt3 - rt2(4) + 10.0.255.5/32 IP TE 130 rt3 - rt5(4) + rt6 TE-IS 140 rt3 - rt4(4) + rt9(4) + rt7 TE-IS 140 rt3 - rt4(4) + rt9(4) + rt8 TE-IS 140 rt3 - rt4(4) + rt9(4) + 10.0.255.9/32 IP TE 140 rt3 - rt9(4) + 10.0.255.6/32 IP TE 150 rt3 - rt6(4) + 10.0.255.7/32 IP TE 150 rt3 - rt7(4) + 10.0.255.8/32 IP TE 150 rt3 - rt8(4) + IS-IS L1 IPv4 routing table: @@ -4102,28 +4302,30 @@ Q-space: rt9 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt3 TE-IS 10 rt3 - rt1(4) -2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) -rt4 TE-IS 110 rt3 - rt3(4) -rt2 TE-IS 120 rt3 - rt4(4) -rt5 TE-IS 120 rt3 - rt4(4) -2001:db8::4/128 IP6 internal 120 rt3 - rt4(4) -rt9 TE-IS 130 rt3 - rt5(4) -2001:db8::2/128 IP6 internal 130 rt3 - rt2(4) -2001:db8::5/128 IP6 internal 130 rt3 - rt5(4) -rt6 TE-IS 140 rt3 - rt4(4) - rt9(4) -rt7 TE-IS 140 rt3 - rt4(4) - rt9(4) -rt8 TE-IS 140 rt3 - rt4(4) - rt9(4) -2001:db8::9/128 IP6 internal 140 rt3 - rt9(4) -2001:db8::6/128 IP6 internal 150 rt3 - rt6(4) -2001:db8::7/128 IP6 internal 150 rt3 - rt7(4) -2001:db8::8/128 IP6 internal 150 rt3 - rt8(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt3 TE-IS 10 rt3 - rt1(4) + 2001:db8::3/128 IP6 internal 20 rt3 - rt3(4) + rt4 TE-IS 110 rt3 - rt3(4) + rt2 TE-IS 120 rt3 - rt4(4) + rt5 TE-IS 120 rt3 - rt4(4) + 2001:db8::4/128 IP6 internal 120 rt3 - rt4(4) + rt9 TE-IS 130 rt3 - rt5(4) + 2001:db8::2/128 IP6 internal 130 rt3 - rt2(4) + 2001:db8::5/128 IP6 internal 130 rt3 - rt5(4) + rt6 TE-IS 140 rt3 - rt4(4) + rt9(4) + rt7 TE-IS 140 rt3 - rt4(4) + rt9(4) + rt8 TE-IS 140 rt3 - rt4(4) + rt9(4) + 2001:db8::9/128 IP6 internal 140 rt3 - rt9(4) + 2001:db8::6/128 IP6 internal 150 rt3 - rt6(4) + 2001:db8::7/128 IP6 internal 150 rt3 - rt7(4) + 2001:db8::8/128 IP6 internal 150 rt3 - rt8(4) + IS-IS L1 IPv6 routing table: @@ -4160,45 +4362,47 @@ Q-space: rt5 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt9 -10.0.255.9/32 IP internal 0 rt9(4) -rt6 TE-IS 10 rt6 - rt9(4) -rt7 TE-IS 10 rt7 - rt9(4) -rt8 TE-IS 10 rt8 - rt9(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -10.0.255.7/32 IP TE 20 rt7 - rt7(4) -10.0.255.8/32 IP TE 20 rt8 - rt8(4) -rt4 TE-IS 40 rt6 - rt6(4) - rt7 - rt7(4) - rt8 - rt8(4) -rt2 TE-IS 50 rt6 - rt4(4) - rt7 - - rt8 - -rt5 TE-IS 50 rt6 - rt4(4) - rt7 - - rt8 - -10.0.255.4/32 IP TE 50 rt6 - rt4(4) - rt7 - - rt8 - -rt1 TE-IS 60 rt6 - rt2(4) - rt7 - - rt8 - -10.0.255.2/32 IP TE 60 rt6 - rt2(4) - rt7 - - rt8 - -10.0.255.5/32 IP TE 60 rt6 - rt5(4) - rt7 - - rt8 - -rt3 TE-IS 70 rt6 - rt1(4) - rt7 - - rt8 - -10.0.255.1/32 IP TE 70 rt6 - rt1(4) - rt7 - - rt8 - -10.0.255.3/32 IP TE 80 rt6 - rt3(4) - rt7 - - rt8 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt9 + 10.0.255.9/32 IP internal 0 rt9(4) + rt6 TE-IS 10 rt6 - rt9(4) + rt7 TE-IS 10 rt7 - rt9(4) + rt8 TE-IS 10 rt8 - rt9(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + 10.0.255.7/32 IP TE 20 rt7 - rt7(4) + 10.0.255.8/32 IP TE 20 rt8 - rt8(4) + rt4 TE-IS 40 rt6 - rt6(4) + rt7 - rt7(4) + rt8 - rt8(4) + rt2 TE-IS 50 rt6 - rt4(4) + rt7 - rt4(4) + rt8 - rt4(4) + rt5 TE-IS 50 rt6 - rt4(4) + rt7 - rt4(4) + rt8 - rt4(4) + 10.0.255.4/32 IP TE 50 rt6 - rt4(4) + rt7 - rt4(4) + rt8 - rt4(4) + rt1 TE-IS 60 rt6 - rt2(4) + rt7 - rt2(4) + rt8 - rt2(4) + 10.0.255.2/32 IP TE 60 rt6 - rt2(4) + rt7 - rt2(4) + rt8 - rt2(4) + 10.0.255.5/32 IP TE 60 rt6 - rt5(4) + rt7 - rt5(4) + rt8 - rt5(4) + rt3 TE-IS 70 rt6 - rt1(4) + rt7 - rt1(4) + rt8 - rt1(4) + 10.0.255.1/32 IP TE 70 rt6 - rt1(4) + rt7 - rt1(4) + rt8 - rt1(4) + 10.0.255.3/32 IP TE 80 rt6 - rt3(4) + rt7 - rt3(4) + rt8 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -4242,45 +4446,47 @@ Q-space: rt5 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt9 -2001:db8::9/128 IP6 internal 0 rt9(4) -rt6 TE-IS 10 rt6 - rt9(4) -rt7 TE-IS 10 rt7 - rt9(4) -rt8 TE-IS 10 rt8 - rt9(4) -2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) -2001:db8::7/128 IP6 internal 20 rt7 - rt7(4) -2001:db8::8/128 IP6 internal 20 rt8 - rt8(4) -rt4 TE-IS 40 rt6 - rt6(4) - rt7 - rt7(4) - rt8 - rt8(4) -rt2 TE-IS 50 rt6 - rt4(4) - rt7 - - rt8 - -rt5 TE-IS 50 rt6 - rt4(4) - rt7 - - rt8 - -2001:db8::4/128 IP6 internal 50 rt6 - rt4(4) - rt7 - - rt8 - -rt1 TE-IS 60 rt6 - rt2(4) - rt7 - - rt8 - -2001:db8::2/128 IP6 internal 60 rt6 - rt2(4) - rt7 - - rt8 - -2001:db8::5/128 IP6 internal 60 rt6 - rt5(4) - rt7 - - rt8 - -rt3 TE-IS 70 rt6 - rt1(4) - rt7 - - rt8 - -2001:db8::1/128 IP6 internal 70 rt6 - rt1(4) - rt7 - - rt8 - -2001:db8::3/128 IP6 internal 80 rt6 - rt3(4) - rt7 - - rt8 - + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt9 + 2001:db8::9/128 IP6 internal 0 rt9(4) + rt6 TE-IS 10 rt6 - rt9(4) + rt7 TE-IS 10 rt7 - rt9(4) + rt8 TE-IS 10 rt8 - rt9(4) + 2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) + 2001:db8::7/128 IP6 internal 20 rt7 - rt7(4) + 2001:db8::8/128 IP6 internal 20 rt8 - rt8(4) + rt4 TE-IS 40 rt6 - rt6(4) + rt7 - rt7(4) + rt8 - rt8(4) + rt2 TE-IS 50 rt6 - rt4(4) + rt7 - rt4(4) + rt8 - rt4(4) + rt5 TE-IS 50 rt6 - rt4(4) + rt7 - rt4(4) + rt8 - rt4(4) + 2001:db8::4/128 IP6 internal 50 rt6 - rt4(4) + rt7 - rt4(4) + rt8 - rt4(4) + rt1 TE-IS 60 rt6 - rt2(4) + rt7 - rt2(4) + rt8 - rt2(4) + 2001:db8::2/128 IP6 internal 60 rt6 - rt2(4) + rt7 - rt2(4) + rt8 - rt2(4) + 2001:db8::5/128 IP6 internal 60 rt6 - rt5(4) + rt7 - rt5(4) + rt8 - rt5(4) + rt3 TE-IS 70 rt6 - rt1(4) + rt7 - rt1(4) + rt8 - rt1(4) + 2001:db8::1/128 IP6 internal 70 rt6 - rt1(4) + rt7 - rt1(4) + rt8 - rt1(4) + 2001:db8::3/128 IP6 internal 80 rt6 - rt3(4) + rt7 - rt3(4) + rt8 - rt3(4) + IS-IS L1 IPv6 routing table: @@ -4329,25 +4535,27 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt9 -10.0.255.9/32 IP internal 0 rt9(4) -rt5 TE-IS 10 rt5 - rt9(4) -rt6 TE-IS 10 rt6 - rt9(4) -rt7 TE-IS 10 rt7 - rt9(4) -rt4 TE-IS 20 rt5 - rt5(4) -10.0.255.5/32 IP TE 20 rt5 - rt5(4) -10.0.255.6/32 IP TE 20 rt6 - rt6(4) -10.0.255.7/32 IP TE 20 rt7 - rt7(4) -rt2 TE-IS 30 rt5 - rt4(4) -10.0.255.4/32 IP TE 30 rt5 - rt4(4) -rt1 TE-IS 40 rt5 - rt2(4) -10.0.255.2/32 IP TE 40 rt5 - rt2(4) -rt8 TE-IS 50 rt5 - rt4(4) -rt3 TE-IS 50 rt5 - rt1(4) -10.0.255.1/32 IP TE 50 rt5 - rt1(4) -10.0.255.8/32 IP TE 60 rt5 - rt8(4) -10.0.255.3/32 IP TE 60 rt5 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt9 + 10.0.255.9/32 IP internal 0 rt9(4) + rt5 TE-IS 10 rt5 - rt9(4) + rt6 TE-IS 10 rt6 - rt9(4) + rt7 TE-IS 10 rt7 - rt9(4) + rt4 TE-IS 20 rt5 - rt5(4) + 10.0.255.5/32 IP TE 20 rt5 - rt5(4) + 10.0.255.6/32 IP TE 20 rt6 - rt6(4) + 10.0.255.7/32 IP TE 20 rt7 - rt7(4) + rt2 TE-IS 30 rt5 - rt4(4) + 10.0.255.4/32 IP TE 30 rt5 - rt4(4) + rt1 TE-IS 40 rt5 - rt2(4) + 10.0.255.2/32 IP TE 40 rt5 - rt2(4) + rt8 TE-IS 50 rt5 - rt4(4) + rt3 TE-IS 50 rt5 - rt1(4) + 10.0.255.1/32 IP TE 50 rt5 - rt1(4) + 10.0.255.8/32 IP TE 60 rt5 - rt8(4) + 10.0.255.3/32 IP TE 60 rt5 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -4381,25 +4589,27 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt9 -2001:db8::9/128 IP6 internal 0 rt9(4) -rt5 TE-IS 10 rt5 - rt9(4) -rt6 TE-IS 10 rt6 - rt9(4) -rt7 TE-IS 10 rt7 - rt9(4) -rt4 TE-IS 20 rt5 - rt5(4) -2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) -2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) -2001:db8::7/128 IP6 internal 20 rt7 - rt7(4) -rt2 TE-IS 30 rt5 - rt4(4) -2001:db8::4/128 IP6 internal 30 rt5 - rt4(4) -rt1 TE-IS 40 rt5 - rt2(4) -2001:db8::2/128 IP6 internal 40 rt5 - rt2(4) -rt8 TE-IS 50 rt5 - rt4(4) -rt3 TE-IS 50 rt5 - rt1(4) -2001:db8::1/128 IP6 internal 50 rt5 - rt1(4) -2001:db8::8/128 IP6 internal 60 rt5 - rt8(4) -2001:db8::3/128 IP6 internal 60 rt5 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt9 + 2001:db8::9/128 IP6 internal 0 rt9(4) + rt5 TE-IS 10 rt5 - rt9(4) + rt6 TE-IS 10 rt6 - rt9(4) + rt7 TE-IS 10 rt7 - rt9(4) + rt4 TE-IS 20 rt5 - rt5(4) + 2001:db8::5/128 IP6 internal 20 rt5 - rt5(4) + 2001:db8::6/128 IP6 internal 20 rt6 - rt6(4) + 2001:db8::7/128 IP6 internal 20 rt7 - rt7(4) + rt2 TE-IS 30 rt5 - rt4(4) + 2001:db8::4/128 IP6 internal 30 rt5 - rt4(4) + rt1 TE-IS 40 rt5 - rt2(4) + 2001:db8::2/128 IP6 internal 40 rt5 - rt2(4) + rt8 TE-IS 50 rt5 - rt4(4) + rt3 TE-IS 50 rt5 - rt1(4) + 2001:db8::1/128 IP6 internal 50 rt5 - rt1(4) + 2001:db8::8/128 IP6 internal 60 rt5 - rt8(4) + 2001:db8::3/128 IP6 internal 60 rt5 - rt3(4) + IS-IS L1 IPv6 routing table: @@ -4428,29 +4638,31 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt3 TE-IS 20 rt3 - rt1(4) -rt4 TE-IS 20 rt4 - rt1(4) -rt6 TE-IS 30 rt3 - rt3(4) -rt7 TE-IS 30 rt4 - rt4(4) -10.0.255.3/32 IP TE 30 rt3 - rt3(4) -10.0.255.4/32 IP TE 30 rt4 - rt4(4) -10.0.255.6/32 IP TE 40 rt3 - rt6(4) -10.0.255.7/32 IP TE 40 rt4 - rt7(4) -rt8 TE-IS 80 rt3 - rt6(4) - rt4 - rt7(4) -rt5 TE-IS 90 rt3 - rt8(4) - rt4 - -10.0.255.8/32 IP TE 90 rt3 - rt8(4) - rt4 - -rt2 TE-IS 100 rt3 - rt5(4) - rt4 - -10.0.255.5/32 IP TE 100 rt3 - rt5(4) - rt4 - -10.0.255.2/32 IP TE 110 rt3 - rt2(4) - rt4 - + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt3 TE-IS 20 rt3 - rt1(4) + rt4 TE-IS 20 rt4 - rt1(4) + rt6 TE-IS 30 rt3 - rt3(4) + rt7 TE-IS 30 rt4 - rt4(4) + 10.0.255.3/32 IP TE 30 rt3 - rt3(4) + 10.0.255.4/32 IP TE 30 rt4 - rt4(4) + 10.0.255.6/32 IP TE 40 rt3 - rt6(4) + 10.0.255.7/32 IP TE 40 rt4 - rt7(4) + rt8 TE-IS 80 rt3 - rt6(4) + rt4 - rt7(4) + rt5 TE-IS 90 rt3 - rt8(4) + rt4 - rt8(4) + 10.0.255.8/32 IP TE 90 rt3 - rt8(4) + rt4 - rt8(4) + rt2 TE-IS 100 rt3 - rt5(4) + rt4 - rt5(4) + 10.0.255.5/32 IP TE 100 rt3 - rt5(4) + rt4 - rt5(4) + 10.0.255.2/32 IP TE 110 rt3 - rt2(4) + rt4 - rt2(4) + IS-IS L1 IPv4 routing table: @@ -4483,29 +4695,31 @@ Q-space: rt8 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt3 TE-IS 20 rt3 - rt1(4) -rt4 TE-IS 20 rt4 - rt1(4) -rt6 TE-IS 30 rt3 - rt3(4) -rt7 TE-IS 30 rt4 - rt4(4) -2001:db8::3/128 IP6 internal 30 rt3 - rt3(4) -2001:db8::4/128 IP6 internal 30 rt4 - rt4(4) -2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) -2001:db8::7/128 IP6 internal 40 rt4 - rt7(4) -rt8 TE-IS 80 rt3 - rt6(4) - rt4 - rt7(4) -rt5 TE-IS 90 rt3 - rt8(4) - rt4 - -2001:db8::8/128 IP6 internal 90 rt3 - rt8(4) - rt4 - -rt2 TE-IS 100 rt3 - rt5(4) - rt4 - -2001:db8::5/128 IP6 internal 100 rt3 - rt5(4) - rt4 - -2001:db8::2/128 IP6 internal 110 rt3 - rt2(4) - rt4 - + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt3 TE-IS 20 rt3 - rt1(4) + rt4 TE-IS 20 rt4 - rt1(4) + rt6 TE-IS 30 rt3 - rt3(4) + rt7 TE-IS 30 rt4 - rt4(4) + 2001:db8::3/128 IP6 internal 30 rt3 - rt3(4) + 2001:db8::4/128 IP6 internal 30 rt4 - rt4(4) + 2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) + 2001:db8::7/128 IP6 internal 40 rt4 - rt7(4) + rt8 TE-IS 80 rt3 - rt6(4) + rt4 - rt7(4) + rt5 TE-IS 90 rt3 - rt8(4) + rt4 - rt8(4) + 2001:db8::8/128 IP6 internal 90 rt3 - rt8(4) + rt4 - rt8(4) + rt2 TE-IS 100 rt3 - rt5(4) + rt4 - rt5(4) + 2001:db8::5/128 IP6 internal 100 rt3 - rt5(4) + rt4 - rt5(4) + 2001:db8::2/128 IP6 internal 110 rt3 - rt2(4) + rt4 - rt2(4) + IS-IS L1 IPv6 routing table: @@ -4540,23 +4754,25 @@ Q-space: rt7 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 20 rt3 - rt1(4) -rt5 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -rt6 TE-IS 30 rt3 - rt3(4) -rt8 TE-IS 30 rt2 - rt5(4) -10.0.255.3/32 IP TE 30 rt3 - rt3(4) -10.0.255.5/32 IP TE 30 rt2 - rt5(4) -10.0.255.6/32 IP TE 40 rt3 - rt6(4) -10.0.255.8/32 IP TE 40 rt2 - rt8(4) -rt7 TE-IS 80 rt2 - rt8(4) -rt4 TE-IS 90 rt2 - rt7(4) -10.0.255.7/32 IP TE 90 rt2 - rt7(4) -10.0.255.4/32 IP TE 100 rt2 - rt4(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 20 rt3 - rt1(4) + rt5 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + rt6 TE-IS 30 rt3 - rt3(4) + rt8 TE-IS 30 rt2 - rt5(4) + 10.0.255.3/32 IP TE 30 rt3 - rt3(4) + 10.0.255.5/32 IP TE 30 rt2 - rt5(4) + 10.0.255.6/32 IP TE 40 rt3 - rt6(4) + 10.0.255.8/32 IP TE 40 rt2 - rt8(4) + rt7 TE-IS 80 rt2 - rt8(4) + rt4 TE-IS 90 rt2 - rt7(4) + 10.0.255.7/32 IP TE 90 rt2 - rt7(4) + 10.0.255.4/32 IP TE 100 rt2 - rt4(4) + IS-IS L1 IPv4 routing table: @@ -4586,23 +4802,25 @@ Q-space: rt7 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt1 -2001:db8::1/128 IP6 internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt3 TE-IS 20 rt3 - rt1(4) -rt5 TE-IS 20 rt2 - rt2(4) -2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) -rt6 TE-IS 30 rt3 - rt3(4) -rt8 TE-IS 30 rt2 - rt5(4) -2001:db8::3/128 IP6 internal 30 rt3 - rt3(4) -2001:db8::5/128 IP6 internal 30 rt2 - rt5(4) -2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) -2001:db8::8/128 IP6 internal 40 rt2 - rt8(4) -rt7 TE-IS 80 rt2 - rt8(4) -rt4 TE-IS 90 rt2 - rt7(4) -2001:db8::7/128 IP6 internal 90 rt2 - rt7(4) -2001:db8::4/128 IP6 internal 100 rt2 - rt4(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt1 + 2001:db8::1/128 IP6 internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt3 TE-IS 20 rt3 - rt1(4) + rt5 TE-IS 20 rt2 - rt2(4) + 2001:db8::2/128 IP6 internal 20 rt2 - rt2(4) + rt6 TE-IS 30 rt3 - rt3(4) + rt8 TE-IS 30 rt2 - rt5(4) + 2001:db8::3/128 IP6 internal 30 rt3 - rt3(4) + 2001:db8::5/128 IP6 internal 30 rt2 - rt5(4) + 2001:db8::6/128 IP6 internal 40 rt3 - rt6(4) + 2001:db8::8/128 IP6 internal 40 rt2 - rt8(4) + rt7 TE-IS 80 rt2 - rt8(4) + rt4 TE-IS 90 rt2 - rt7(4) + 2001:db8::7/128 IP6 internal 90 rt2 - rt7(4) + 2001:db8::4/128 IP6 internal 100 rt2 - rt4(4) + IS-IS L1 IPv6 routing table: @@ -4633,20 +4851,22 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt2 -10.0.255.2/32 IP internal 0 rt2(4) -rt1 TE-IS 50 rt1 - rt2(4) -rt3 TE-IS 50 rt3 - rt2(4) -rt2 -rt5 TE-IS 60 rt3 - rt3(4) -10.0.255.1/32 IP TE 60 rt1 - rt1(4) -10.0.255.3/32 IP TE 60 rt3 - rt3(4) -rt4 TE-IS 70 rt3 - rt5(4) -rt6 TE-IS 70 rt3 - rt5(4) -10.0.255.5/32 IP TE 70 rt3 - rt5(4) -10.0.255.4/32 IP TE 80 rt3 - rt4(4) -10.0.255.6/32 IP TE 80 rt3 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt2 + 10.0.255.2/32 IP internal 0 rt2(4) + rt1 TE-IS 50 rt1 - rt2(4) + rt3 TE-IS 50 rt3 - rt2(4) + rt2 + rt5 TE-IS 60 rt3 - rt3(4) + 10.0.255.1/32 IP TE 60 rt1 - rt1(4) + 10.0.255.3/32 IP TE 60 rt3 - rt3(4) + rt4 TE-IS 70 rt3 - rt5(4) + rt6 TE-IS 70 rt3 - rt5(4) + 10.0.255.5/32 IP TE 70 rt3 - rt5(4) + 10.0.255.4/32 IP TE 80 rt3 - rt4(4) + 10.0.255.6/32 IP TE 80 rt3 - rt6(4) + IS-IS L1 IPv4 routing table: @@ -4679,20 +4899,22 @@ Q-space: rt6 IS-IS paths to level-1 routers that speak IPv6 -Vertex Type Metric Next-Hop Interface Parent -rt2 -2001:db8::2/128 IP6 internal 0 rt2(4) -rt1 TE-IS 50 rt1 - rt2(4) -rt3 TE-IS 50 rt3 - rt2(4) -rt2 -rt5 TE-IS 60 rt3 - rt3(4) -2001:db8::1/128 IP6 internal 60 rt1 - rt1(4) -2001:db8::3/128 IP6 internal 60 rt3 - rt3(4) -rt4 TE-IS 70 rt3 - rt5(4) -rt6 TE-IS 70 rt3 - rt5(4) -2001:db8::5/128 IP6 internal 70 rt3 - rt5(4) -2001:db8::4/128 IP6 internal 80 rt3 - rt4(4) -2001:db8::6/128 IP6 internal 80 rt3 - rt6(4) + Vertex Type Metric Next-Hop Interface Parent + -------------------------------------------------------------------- + rt2 + 2001:db8::2/128 IP6 internal 0 rt2(4) + rt1 TE-IS 50 rt1 - rt2(4) + rt3 TE-IS 50 rt3 - rt2(4) + rt2 + rt5 TE-IS 60 rt3 - rt3(4) + 2001:db8::1/128 IP6 internal 60 rt1 - rt1(4) + 2001:db8::3/128 IP6 internal 60 rt3 - rt3(4) + rt4 TE-IS 70 rt3 - rt5(4) + rt6 TE-IS 70 rt3 - rt5(4) + 2001:db8::5/128 IP6 internal 70 rt3 - rt5(4) + 2001:db8::4/128 IP6 internal 80 rt3 - rt4(4) + 2001:db8::6/128 IP6 internal 80 rt3 - rt6(4) + IS-IS L1 IPv6 routing table: @@ -4723,27 +4945,29 @@ Q-space: rt3 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -rt6 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -rt8 TE-IS 40 rt2 - rt6(4) -10.0.255.6/32 IP TE 40 rt2 - rt6(4) -rt10 TE-IS 50 rt2 - rt8(4) -10.0.255.8/32 IP TE 50 rt2 - rt8(4) -10.0.255.10/32 IP TE 60 rt2 - rt10(4) -rt7 TE-IS 140 rt2 - rt8(4) -rt9 TE-IS 150 rt2 - rt7(4) -10.0.255.7/32 IP TE 150 rt2 - rt7(4) -10.0.255.9/32 IP TE 160 rt2 - rt9(4) -rt5 TE-IS 340 rt2 - rt7(4) -10.0.255.5/32 IP TE 350 rt2 - rt5(4) -rt3 TE-IS 740 rt2 - rt5(4) -10.0.255.3/32 IP TE 750 rt2 - rt3(4) + Vertex Type Metric Next-Hop Interface Parent + ------------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + rt6 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt8 TE-IS 40 rt2 - rt6(4) + 10.0.255.6/32 IP TE 40 rt2 - rt6(4) + rt10 TE-IS 50 rt2 - rt8(4) + 10.0.255.8/32 IP TE 50 rt2 - rt8(4) + 10.0.255.10/32 IP TE 60 rt2 - rt10(4) + rt7 TE-IS 140 rt2 - rt8(4) + rt9 TE-IS 150 rt2 - rt7(4) + 10.0.255.7/32 IP TE 150 rt2 - rt7(4) + 10.0.255.9/32 IP TE 160 rt2 - rt9(4) + rt5 TE-IS 340 rt2 - rt7(4) + 10.0.255.5/32 IP TE 350 rt2 - rt5(4) + rt3 TE-IS 740 rt2 - rt5(4) + 10.0.255.3/32 IP TE 750 rt2 - rt3(4) + IS-IS L1 IPv4 routing table: @@ -4770,22 +4994,24 @@ Q-space: rt7 IS-IS paths to level-1 routers that speak IP -Vertex Type Metric Next-Hop Interface Parent -rt1 -10.0.255.1/32 IP internal 0 rt1(4) -rt2 TE-IS 10 rt2 - rt1(4) -rt4 TE-IS 20 rt2 - rt2(4) -10.0.255.2/32 IP TE 20 rt2 - rt2(4) -rt3 TE-IS 30 rt2 - rt4(4) -10.0.255.4/32 IP TE 30 rt2 - rt4(4) -rt5 TE-IS 40 rt2 - rt3(4) -rt6 TE-IS 40 rt2 - rt3(4) -10.0.255.3/32 IP TE 40 rt2 - rt3(4) -rt7 TE-IS 50 rt2 - rt5(4) - rt6(4) -10.0.255.5/32 IP TE 50 rt2 - rt5(4) -10.0.255.6/32 IP TE 50 rt2 - rt6(4) -10.0.255.7/32 IP TE 60 rt2 - rt7(4) + Vertex Type Metric Next-Hop Interface Parent + ----------------------------------------------------------------- + rt1 + 10.0.255.1/32 IP internal 0 rt1(4) + rt2 TE-IS 10 rt2 - rt1(4) + rt4 TE-IS 20 rt2 - rt2(4) + 10.0.255.2/32 IP TE 20 rt2 - rt2(4) + rt3 TE-IS 30 rt2 - rt4(4) + 10.0.255.4/32 IP TE 30 rt2 - rt4(4) + rt5 TE-IS 40 rt2 - rt3(4) + rt6 TE-IS 40 rt2 - rt3(4) + 10.0.255.3/32 IP TE 40 rt2 - rt3(4) + rt7 TE-IS 50 rt2 - rt5(4) + rt6(4) + 10.0.255.5/32 IP TE 50 rt2 - rt5(4) + 10.0.255.6/32 IP TE 50 rt2 - rt6(4) + 10.0.255.7/32 IP TE 60 rt2 - rt7(4) + IS-IS L1 IPv4 routing table: @@ -4796,5 +5022,5 @@ IS-IS L1 IPv4 routing table: 10.0.255.6/32 50 - rt2 16040/16060 10.0.255.7/32 60 - rt2 16040/16070 -test# -end. +test# +end. From 3a2554e4a23a69c6030253f78644f4f03b3bdcab Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Thu, 6 Jun 2024 17:08:56 +0200 Subject: [PATCH 331/472] isisd: add json support to display spf paths in 'show isis route' The 'show isis route json' command never displays the list of paths. Add the json support for this sub-part. > # show isis route json > [..] > "ipv6-paths":[ > { > "Vertex":"rt1", > "Type":"", > "Metric":0, > "Next-Hop":"", > "Interface":"", > "Parent":"" > }, > { > "Vertex":"2001:db8:1000::1\/128", > "Type":"IP6 internal", > "Metric":0, > "Next-Hop":"", > "Interface":"", > "Parent":"rt1(4)" > }, Signed-off-by: Philippe Guibert --- isisd/isis_spf.c | 64 ++++++++++++++++++++++++++----------- isisd/isis_spf.h | 3 +- tests/isisd/test_isis_spf.c | 10 +++--- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 4892479ac2d0..c64bf67df561 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2227,7 +2227,7 @@ int _isis_spf_schedule(struct isis_area *area, int level, } static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue, - uint8_t *root_sysid) + uint8_t *root_sysid, struct json_object **json) { struct listnode *node; struct isis_vertex *vertex; @@ -2331,13 +2331,17 @@ static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue, vertex_typestr, vertex_metricstr, vertex_nexthop, vertex_interface, vertex_parent); } - table = ttable_dump(tt, "\n"); - vty_out(vty, "%s\n", table); - XFREE(MTYPE_TMP, table); + if (json == NULL) { + table = ttable_dump(tt, "\n"); + vty_out(vty, "%s\n", table); + XFREE(MTYPE_TMP, table); + } else + *json = ttable_json(tt, "ssdsss"); ttable_del(tt); } -void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree) +void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree, + struct json_object **json) { const char *tree_id_text = NULL; @@ -2359,10 +2363,13 @@ void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree) return; } - vty_out(vty, "IS-IS paths to level-%d routers %s\n", spftree->level, - tree_id_text); - isis_print_paths(vty, &spftree->paths, spftree->sysid); - vty_out(vty, "\n"); + if (!json) + vty_out(vty, "IS-IS paths to level-%d routers %s\n", + spftree->level, tree_id_text); + + isis_print_paths(vty, &spftree->paths, spftree->sysid, json); + if (!json) + vty_out(vty, "\n"); } static void show_isis_topology_common(struct vty *vty, int levels, @@ -2420,7 +2427,7 @@ static void show_isis_topology_common(struct vty *vty, int levels, spftree = area->spftree[SPFTREE_IPV4] [level - 1]; - isis_print_spftree(vty, spftree); + isis_print_spftree(vty, spftree, NULL); } if (area->ipv6_circuits > 0) { #ifndef FABRICD @@ -2431,7 +2438,7 @@ static void show_isis_topology_common(struct vty *vty, int levels, #endif /* ifndef FABRICD */ spftree = area->spftree[SPFTREE_IPV6] [level - 1]; - isis_print_spftree(vty, spftree); + isis_print_spftree(vty, spftree, NULL); } if (isis_area_ipv6_dstsrc_enabled(area)) { #ifndef FABRICD @@ -2443,14 +2450,15 @@ static void show_isis_topology_common(struct vty *vty, int levels, #endif /* ifndef FABRICD */ spftree = area->spftree[SPFTREE_DSTSRC] [level - 1]; - isis_print_spftree(vty, spftree); + isis_print_spftree(vty, spftree, NULL); } } if (fabricd_spftree(area)) { vty_out(vty, "IS-IS paths to level-2 routers with hop-by-hop metric\n"); - isis_print_paths(vty, &fabricd_spftree(area)->paths, isis->sysid); + isis_print_paths(vty, &fabricd_spftree(area)->paths, + isis->sysid, NULL); vty_out(vty, "\n"); } @@ -3006,8 +3014,14 @@ static void show_isis_route_common(struct vty *vty, int levels, spftree = area->spftree[SPFTREE_IPV4] [level - 1]; - if (!json) - isis_print_spftree(vty, spftree); + isis_print_spftree(vty, spftree, + json ? &json_val : NULL); + if (json && json_val) { + json_object_object_add(json_level, + "ipv4-paths", + json_val); + json_val = NULL; + } isis_print_routes(vty, spftree, json ? &json_val : NULL, @@ -3028,8 +3042,14 @@ static void show_isis_route_common(struct vty *vty, int levels, spftree = area->spftree[SPFTREE_IPV6] [level - 1]; - if (!json) - isis_print_spftree(vty, spftree); + isis_print_spftree(vty, spftree, + json ? &json_val : NULL); + if (json && json_val) { + json_object_object_add(json_level, + "ipv6-paths", + json_val); + json_val = NULL; + } isis_print_routes(vty, spftree, json ? &json_val : NULL, @@ -3051,8 +3071,14 @@ static void show_isis_route_common(struct vty *vty, int levels, spftree = area->spftree[SPFTREE_DSTSRC] [level - 1]; - if (!json) - isis_print_spftree(vty, spftree); + isis_print_spftree(vty, spftree, + json ? &json_val : NULL); + if (json && json_val) { + json_object_object_add(json_level, + "ipv6-dstsrc-paths", + json_val); + json_val = NULL; + } isis_print_routes(vty, spftree, json ? &json_val : NULL, prefix_sid, backup); diff --git a/isisd/isis_spf.h b/isisd/isis_spf.h index 7e9754d9bfa5..ee2d29abe3ba 100644 --- a/isisd/isis_spf.h +++ b/isisd/isis_spf.h @@ -61,7 +61,8 @@ struct isis_lsp *isis_root_system_lsp(struct lspdb_head *lspdb, __FILE__, __LINE__) int _isis_spf_schedule(struct isis_area *area, int level, const char *func, const char *file, int line); -void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree); +void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree, + struct json_object **json); void isis_print_routes(struct vty *vty, struct isis_spftree *spftree, json_object **json, bool prefix_sid, bool backup); void isis_spf_init(void); diff --git a/tests/isisd/test_isis_spf.c b/tests/isisd/test_isis_spf.c index 4ea28cda2ff8..6fe6993fdfd8 100644 --- a/tests/isisd/test_isis_spf.c +++ b/tests/isisd/test_isis_spf.c @@ -55,7 +55,7 @@ static void test_run_spf(struct vty *vty, const struct isis_topology *topology, isis_run_spf(spftree); /* Print the SPT and the corresponding routing table. */ - isis_print_spftree(vty, spftree); + isis_print_spftree(vty, spftree, NULL); isis_print_routes(vty, spftree, NULL, false, false); /* Cleanup SPF tree. */ @@ -85,7 +85,7 @@ static void test_run_lfa(struct vty *vty, const struct isis_topology *topology, isis_lfa_compute(area, NULL, spftree_self, protected_resource); /* Print the SPT and the corresponding main/backup routing tables. */ - isis_print_spftree(vty, spftree_self); + isis_print_spftree(vty, spftree_self, NULL); vty_out(vty, "Main:\n"); isis_print_routes(vty, spftree_self, NULL, false, false); vty_out(vty, "Backup:\n"); @@ -148,7 +148,7 @@ static void test_run_rlfa(struct vty *vty, const struct isis_topology *topology, vty_out(vty, "\n"); /* Print the post-convergence SPT. */ - isis_print_spftree(vty, spftree_pc); + isis_print_spftree(vty, spftree_pc, NULL); /* * Activate the computed RLFAs (if any) using artificial LDP labels for @@ -164,7 +164,7 @@ static void test_run_rlfa(struct vty *vty, const struct isis_topology *topology, } /* Print the SPT and the corresponding main/backup routing tables. */ - isis_print_spftree(vty, spftree_self); + isis_print_spftree(vty, spftree_self, NULL); vty_out(vty, "Main:\n"); isis_print_routes(vty, spftree_self, NULL, false, false); vty_out(vty, "Backup:\n"); @@ -228,7 +228,7 @@ static void test_run_ti_lfa(struct vty *vty, /* * Print the post-convergence SPT and the corresponding routing table. */ - isis_print_spftree(vty, spftree_pc); + isis_print_spftree(vty, spftree_pc, NULL); isis_print_routes(vty, spftree_self, NULL, false, true); /* Cleanup everything. */ From f72a8eb4b5840e8fb73138df0768c23f4ebcfc86 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 14 Jun 2024 08:57:16 +0200 Subject: [PATCH 332/472] isisd: add json support for 'show isis topology' command Add the json keyword for dumping isis topology. Signed-off-by: Philippe Guibert --- isisd/isis_spf.c | 125 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 21 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index c64bf67df561..86d998c41958 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2373,7 +2373,8 @@ void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree, } static void show_isis_topology_common(struct vty *vty, int levels, - struct isis *isis, uint8_t algo) + struct isis *isis, uint8_t algo, + json_object **json) { #ifndef FABRICD struct isis_flex_algo_data *fa_data; @@ -2382,10 +2383,15 @@ static void show_isis_topology_common(struct vty *vty, int levels, struct isis_spftree *spftree; struct listnode *node; struct isis_area *area; + json_object *json_level = NULL, *jstr = NULL, *json_val; + char key[18]; if (!isis->area_list || isis->area_list->count == 0) return; + if (json) + *json = json_object_new_object(); + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { #ifndef FABRICD /* @@ -2403,21 +2409,37 @@ static void show_isis_topology_common(struct vty *vty, int levels, fa_data = NULL; #endif /* ifndef FABRICD */ - vty_out(vty, - "Area %s:", area->area_tag ? area->area_tag : "null"); + if (json) { + jstr = json_object_new_string( + area->area_tag ? area->area_tag : "null"); + json_object_object_add(*json, "area", jstr); + json_object_int_add(*json, "algorithm", algo); + } else { + vty_out(vty, "Area %s:", + area->area_tag ? area->area_tag : "null"); #ifndef FABRICD - if (algo != SR_ALGORITHM_SPF) - vty_out(vty, " Algorithm %hhu\n", algo); - else + if (algo != SR_ALGORITHM_SPF) + vty_out(vty, " Algorithm %hhu\n", algo); + else #endif /* ifndef FABRICD */ - vty_out(vty, "\n"); + vty_out(vty, "\n"); + } for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) { if ((level & levels) == 0) continue; + if (json) { + json_level = json_object_new_object(); + jstr = json_object_new_string( + area->area_tag ? area->area_tag + : "null"); + json_object_object_add(json_level, "area", jstr); + } + if (area->ip_circuits > 0) { + json_val = NULL; #ifndef FABRICD if (fa_data) spftree = fa_data->spftree[SPFTREE_IPV4] @@ -2427,9 +2449,16 @@ static void show_isis_topology_common(struct vty *vty, int levels, spftree = area->spftree[SPFTREE_IPV4] [level - 1]; - isis_print_spftree(vty, spftree, NULL); + isis_print_spftree(vty, spftree, + json ? &json_val : NULL); + if (json && json_val) { + json_object_object_add(json_level, + "ipv4-paths", + json_val); + } } if (area->ipv6_circuits > 0) { + json_val = NULL; #ifndef FABRICD if (fa_data) spftree = fa_data->spftree[SPFTREE_IPV6] @@ -2438,9 +2467,16 @@ static void show_isis_topology_common(struct vty *vty, int levels, #endif /* ifndef FABRICD */ spftree = area->spftree[SPFTREE_IPV6] [level - 1]; - isis_print_spftree(vty, spftree, NULL); + isis_print_spftree(vty, spftree, + json ? &json_val : NULL); + if (json && json_val) { + json_object_object_add(json_level, + "ipv6-paths", + json_val); + } } if (isis_area_ipv6_dstsrc_enabled(area)) { + json_val = NULL; #ifndef FABRICD if (fa_data) spftree = @@ -2450,19 +2486,36 @@ static void show_isis_topology_common(struct vty *vty, int levels, #endif /* ifndef FABRICD */ spftree = area->spftree[SPFTREE_DSTSRC] [level - 1]; - isis_print_spftree(vty, spftree, NULL); + isis_print_spftree(vty, spftree, + json ? &json_val : NULL); + if (json && json_val) { + json_object_object_add(json_level, + "ipv6-dstsrc-paths", + json_val); + } + } + if (json) { + snprintf(key, sizeof(key), "level-%d", level); + json_object_object_add(*json, key, json_level); } } if (fabricd_spftree(area)) { + json_val = NULL; + vty_out(vty, "IS-IS paths to level-2 routers with hop-by-hop metric\n"); isis_print_paths(vty, &fabricd_spftree(area)->paths, - isis->sysid, NULL); - vty_out(vty, "\n"); + isis->sysid, json ? &json_val : NULL); + if (json && json_val) + json_object_object_add(json_level, + "fabricd-paths", + json_val); + else + vty_out(vty, "\n"); } - - vty_out(vty, "\n"); + if (!json) + vty_out(vty, "\n"); } } @@ -2473,6 +2526,7 @@ DEFUN(show_isis_topology, show_isis_topology_cmd, " []" " [algorithm [(128-255)]]" #endif /* ifndef FABRICD */ + " [json$uj]" , SHOW_STR PROTO_HELP VRF_CMD_HELP_STR "All VRFs\n" @@ -2483,6 +2537,7 @@ DEFUN(show_isis_topology, show_isis_topology_cmd, "Show Flex-algo routes\n" "Algorithm number\n" #endif /* ifndef FABRICD */ + JSON_STR ) { int levels = ISIS_LEVELS; @@ -2493,6 +2548,8 @@ DEFUN(show_isis_topology, show_isis_topology_cmd, bool all_algorithm = false; int idx_vrf = 0; uint16_t algorithm = SR_ALGORITHM_SPF; + bool uj = use_json(argc, argv); + json_object *json = NULL, *json_vrf = NULL; #ifndef FABRICD int idx = 0; @@ -2516,21 +2573,33 @@ DEFUN(show_isis_topology, show_isis_topology_cmd, } ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + if (uj) + json = json_object_new_array(); + if (all_vrf) { for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { if (all_algorithm) { for (algorithm = SR_ALGORITHM_FLEX_MIN; algorithm <= SR_ALGORITHM_FLEX_MAX; algorithm++) - show_isis_topology_common( - vty, levels, isis, - (uint8_t)algorithm); + show_isis_topology_common(vty, levels, + isis, + (uint8_t)algorithm, + uj ? &json_vrf + : NULL); } else { show_isis_topology_common(vty, levels, isis, - (uint8_t)algorithm); + (uint8_t)algorithm, + uj ? &json_vrf : NULL); + } + if (uj) { + json_object_object_add(json_vrf, "vrf_id", + json_object_new_int( + isis->vrf_id)); + json_object_array_add(json, json_vrf); } } - return CMD_SUCCESS; + goto out; } isis = isis_lookup_by_vrfname(vrf_name); if (isis == NULL) @@ -2539,10 +2608,24 @@ DEFUN(show_isis_topology, show_isis_topology_cmd, for (algorithm = SR_ALGORITHM_FLEX_MIN; algorithm <= SR_ALGORITHM_FLEX_MAX; algorithm++) { show_isis_topology_common(vty, levels, isis, - (uint8_t)algorithm); + (uint8_t)algorithm, + uj ? &json_vrf : NULL); } } else - show_isis_topology_common(vty, levels, isis, (uint8_t)algorithm); + show_isis_topology_common(vty, levels, isis, (uint8_t)algorithm, + uj ? &json_vrf : NULL); + if (uj) { + json_object_object_add(json_vrf, "vrf_id", + json_object_new_int(isis->vrf_id)); + json_object_array_add(json, json_vrf); + } +out: + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } return CMD_SUCCESS; } From cd68ea344792aa730cb89ae52b388360e3235f07 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 14 Jun 2024 10:18:15 +0200 Subject: [PATCH 333/472] topotests: isis_topo1, use 'show isis topology json' command Add the json support from ISIS vty command. Signed-off-by: Philippe Guibert --- .../topotests/isis_topo1/r1/r1_topology.json | 188 ++++----- .../topotests/isis_topo1/r2/r2_topology.json | 188 ++++----- .../topotests/isis_topo1/r3/r3_topology.json | 386 +++++++++--------- .../topotests/isis_topo1/r4/r4_topology.json | 386 +++++++++--------- .../topotests/isis_topo1/r5/r5_topology.json | 306 +++++++------- tests/topotests/isis_topo1/test_isis_topo1.py | 57 +-- 6 files changed, 731 insertions(+), 780 deletions(-) diff --git a/tests/topotests/isis_topo1/r1/r1_topology.json b/tests/topotests/isis_topo1/r1/r1_topology.json index 337d6bf5ef08..d52346df6f7a 100644 --- a/tests/topotests/isis_topo1/r1/r1_topology.json +++ b/tests/topotests/isis_topo1/r1/r1_topology.json @@ -1,96 +1,98 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r1" - } - ], - "ipv6": [ - { - "vertex": "r1" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r1" - }, - { - "metric": "0", - "parent": "r1(4)", - "type": "IP internal", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r1(4)", - "type": "TE-IS", - "vertex": "r3" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.254.0.3/32" - } - ], - "ipv6": [ - { - "vertex": "r1" - }, - { - "metric": "0", - "parent": "r1(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r1(4)", - "type": "TE-IS", - "vertex": "r3" - }, - { - "metric": "10", - "interface": "r1-eth0", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r1" + } + ], + "ipv6-paths": [ + { + "Vertex": "r1" + } + ] }, - { - "metric": "10", - "interface": "r1-eth0", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::3/128" + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r1" + }, + { + "Metric": 0, + "Parent": "r1(4)", + "Type": "IP internal", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r1(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.254.0.3/32" + } + ], + "ipv6-paths": [ + { + "Vertex": "r1" + }, + { + "Metric": 0, + "Parent": "r1(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r1(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Metric": 10, + "Interface": "r1-eth0", + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + }, + { + "Metric": 10, + "Interface": "r1-eth0", + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::3/128" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1/r2/r2_topology.json b/tests/topotests/isis_topo1/r2/r2_topology.json index de90fb5a32d0..d0a1f90fd081 100644 --- a/tests/topotests/isis_topo1/r2/r2_topology.json +++ b/tests/topotests/isis_topo1/r2/r2_topology.json @@ -1,96 +1,98 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r2" - } - ], - "ipv6": [ - { - "vertex": "r2" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r2" - }, - { - "metric": "0", - "parent": "r2(4)", - "type": "IP internal", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r2(4)", - "type": "TE-IS", - "vertex": "r4" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.254.0.4/32" - } - ], - "ipv6": [ - { - "vertex": "r2" - }, - { - "metric": "0", - "parent": "r2(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r2(4)", - "type": "TE-IS", - "vertex": "r4" - }, - { - "metric": "10", - "interface": "r2-eth0", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r2" + } + ], + "ipv6-paths": [ + { + "Vertex": "r2" + } + ] }, - { - "metric": "10", - "interface": "r2-eth0", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::4/128" + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r2" + }, + { + "Metric": 0, + "Parent": "r2(4)", + "Type": "IP internal", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r2(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.254.0.4/32" + } + ], + "ipv6-paths": [ + { + "Vertex": "r2" + }, + { + "Metric": 0, + "Parent": "r2(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r2(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Metric": 10, + "Interface": "r2-eth0", + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + }, + { + "Metric": 10, + "Interface": "r2-eth0", + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::4/128" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1/r3/r3_topology.json b/tests/topotests/isis_topo1/r3/r3_topology.json index 2d36f9b427aa..9265e62786cf 100644 --- a/tests/topotests/isis_topo1/r3/r3_topology.json +++ b/tests/topotests/isis_topo1/r3/r3_topology.json @@ -1,194 +1,196 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r3" - }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP internal", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.254.0.5/32" - }, - { - "interface": "r3-eth1", - "metric": "20", - "next-hop": "r5", - "type": "TE-IS", - "vertex": "r4" - }, - { - "interface": "r3-eth1", - "metric": "20", - "next-hop": "r5", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r3-eth1", - "metric": "20", - "next-hop": "r5", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.254.0.4/32" - } - ], - "ipv6": [ - { - "vertex": "r3" - }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "metric": "10", - "interface": "r3-eth1", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" - }, - { - "metric": "10", - "interface": "r3-eth1", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::5/128" - }, - { - "interface": "r3-eth1", - "metric": "20", - "next-hop": "r5", - "type": "TE-IS", - "vertex": "r4" - }, - { - "metric": "20", - "interface": "r3-eth1", - "next-hop": "r5", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - }, - { - "metric": "20", - "interface": "r3-eth1", - "next-hop": "r5", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::4/128" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r3" - }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP internal", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r1", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r1" - }, - { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r1", - "parent": "r1(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r1", - "parent": "r1(4)", - "type": "IP TE", - "vertex": "10.254.0.1/32" - } - ], - "ipv6": [ - { - "vertex": "r3" - }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - }, - { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r1", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r1" - }, - { - "metric": "10", - "interface": "r3-eth0", - "next-hop": "r1", - "parent": "r1(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::1/128" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP internal", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.254.0.5/32" + }, + { + "Interface": "r3-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Interface": "r3-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r3-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.254.0.4/32" + } + ], + "ipv6-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Metric": 10, + "Interface": "r3-eth1", + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + }, + { + "Metric": 10, + "Interface": "r3-eth1", + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::5/128" + }, + { + "Interface": "r3-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Metric": 20, + "Interface": "r3-eth1", + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + }, + { + "Metric": 20, + "Interface": "r3-eth1", + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::4/128" + } + ] + }, + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP internal", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r3-eth0", + "Metric": 10, + "Next-Hop": "r1", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r1" + }, + { + "Interface": "r3-eth0", + "Metric": 10, + "Next-Hop": "r1", + "Parent": "r1(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r3-eth0", + "Metric": 10, + "Next-Hop": "r1", + "Parent": "r1(4)", + "Type": "IP TE", + "Vertex": "10.254.0.1/32" + } + ], + "ipv6-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + }, + { + "Interface": "r3-eth0", + "Metric": 10, + "Next-Hop": "r1", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r1" + }, + { + "Metric": 10, + "Interface": "r3-eth0", + "Next-Hop": "r1", + "Parent": "r1(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::1/128" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1/r4/r4_topology.json b/tests/topotests/isis_topo1/r4/r4_topology.json index e7d78419127b..240c7588fc19 100644 --- a/tests/topotests/isis_topo1/r4/r4_topology.json +++ b/tests/topotests/isis_topo1/r4/r4_topology.json @@ -1,194 +1,196 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r4" - }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP internal", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.254.0.5/32" - }, - { - "interface": "r4-eth1", - "metric": "20", - "next-hop": "r5", - "type": "TE-IS", - "vertex": "r3" - }, - { - "interface": "r4-eth1", - "metric": "20", - "next-hop": "r5", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r4-eth1", - "metric": "20", - "next-hop": "r5", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.254.0.3/32" - } - ], - "ipv6": [ - { - "vertex": "r4" - }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "metric": "10", - "interface": "r4-eth1", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" - }, - { - "metric": "10", - "interface": "r4-eth1", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::5/128" - }, - { - "interface": "r4-eth1", - "metric": "20", - "next-hop": "r5", - "type": "TE-IS", - "vertex": "r3" - }, - { - "metric": "20", - "interface": "r4-eth1", - "next-hop": "r5", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - }, - { - "metric": "20", - "interface": "r4-eth1", - "next-hop": "r5", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::3/128" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r4" - }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP internal", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r2" - }, - { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r2(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r2(4)", - "type": "IP TE", - "vertex": "10.254.0.2/32" - } - ], - "ipv6": [ - { - "vertex": "r4" - }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - }, - { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r2" - }, - { - "metric": "10", - "interface": "r4-eth0", - "next-hop": "r2", - "parent": "r2(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::2/128" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP internal", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.254.0.5/32" + }, + { + "Interface": "r4-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r4-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r4-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.254.0.3/32" + } + ], + "ipv6-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Metric": 10, + "Interface": "r4-eth1", + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + }, + { + "Metric": 10, + "Interface": "r4-eth1", + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::5/128" + }, + { + "Interface": "r4-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Metric": 20, + "Interface": "r4-eth1", + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + }, + { + "Metric": 20, + "Interface": "r4-eth1", + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::3/128" + } + ] + }, + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP internal", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r4-eth0", + "Metric": 10, + "Next-Hop": "r2", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r2" + }, + { + "Interface": "r4-eth0", + "Metric": 10, + "Next-Hop": "r2", + "Parent": "r2(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r4-eth0", + "Metric": 10, + "Next-Hop": "r2", + "Parent": "r2(4)", + "Type": "IP TE", + "Vertex": "10.254.0.2/32" + } + ], + "ipv6-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + }, + { + "Interface": "r4-eth0", + "Metric": 10, + "Next-Hop": "r2", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r2" + }, + { + "Metric": 10, + "Interface": "r4-eth0", + "Next-Hop": "r2", + "Parent": "r2(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::2/128" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1/r5/r5_topology.json b/tests/topotests/isis_topo1/r5/r5_topology.json index 3d887b7cea69..37da1a08e383 100644 --- a/tests/topotests/isis_topo1/r5/r5_topology.json +++ b/tests/topotests/isis_topo1/r5/r5_topology.json @@ -1,156 +1,154 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r5" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP internal", - "vertex": "10.0.10.0/24" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP internal", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r3" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r4" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.254.0.3/32" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.254.0.4/32" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r5" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP internal", + "Vertex": "10.0.10.0/24" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP internal", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.254.0.3/32" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.254.0.4/32" + } + ], + "ipv6-paths": [ + { + "Vertex": "r5" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Metric": 10, + "Interface": "r5-eth0", + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + }, + { + "Metric": 10, + "Interface": "r5-eth0", + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::3/128" + }, + { + "Metric": 10, + "Interface": "r5-eth1", + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + }, + { + "Metric": 10, + "Interface": "r5-eth1", + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:f::4/128" + } + ] } - ], - "ipv6": [ - { - "vertex": "r5" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r3" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r4" - }, - { - "metric": "10", - "interface": "r5-eth0", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - }, - { - "metric": "10", - "interface": "r5-eth0", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::3/128" - }, - { - "metric": "10", - "interface": "r5-eth1", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - }, - { - "metric": "10", - "interface": "r5-eth1", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:f::4/128" - } - ] - }, - "level-2": { - "ipv4": [], - "ipv6": [] } - } -} +] diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py index cea284963d1e..8b6fb98612a1 100644 --- a/tests/topotests/isis_topo1/test_isis_topo1.py +++ b/tests/topotests/isis_topo1/test_isis_topo1.py @@ -120,19 +120,13 @@ def test_isis_convergence(): pytest.skip(tgen.errors) logger.info("waiting for ISIS protocol to converge") - # Code to generate the json files. - # for rname, router in tgen.routers().items(): - # open('/tmp/{}_topology.json'.format(rname), 'w').write( - # json.dumps(show_isis_topology(router), indent=2, sort_keys=True) - # ) - for rname, router in tgen.routers().items(): filename = "{0}/{1}/{1}_topology.json".format(CWD, rname) expected = json.loads(open(filename).read()) def compare_isis_topology(router, expected): "Helper function to test ISIS topology convergence." - actual = show_isis_topology(router) + actual = json.loads(router.vtysh_cmd("show isis topology json")) return topotest.json_cmp(actual, expected) test_func = functools.partial(compare_isis_topology, router, expected) @@ -845,52 +839,3 @@ def parse_topology(lines, level): continue return areas - - -def show_isis_topology(router): - """ - Get the ISIS topology in a dictionary format. - - Sample: - { - 'area-name': { - 'level-1': [ - { - 'vertex': 'r1' - } - ], - 'level-2': [ - { - 'vertex': '10.0.0.1/24', - 'type': 'IP', - 'parent': '0', - 'metric': 'internal' - } - ] - }, - 'area-name-2': { - 'level-2': [ - { - "interface": "rX-ethY", - "metric": "Z", - "next-hop": "rA", - "parent": "rC(B)", - "type": "TE-IS", - "vertex": "rD" - } - ] - } - } - """ - l1out = topotest.normalize_text( - router.vtysh_cmd("show isis topology level-1") - ).splitlines() - l2out = topotest.normalize_text( - router.vtysh_cmd("show isis topology level-2") - ).splitlines() - - l1 = parse_topology(l1out, "level-1") - l2 = parse_topology(l2out, "level-2") - - dict_merge(l1, l2) - return l1 From ea6ad95ab578dbbb90c263ea4ed65b3ab392f709 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 14 Jun 2024 16:22:56 +0200 Subject: [PATCH 334/472] topotests: isis_topo1_vrf, align json support on 'show isis topology' command Add the json support from ISIS vty command. > show isis vrf vrf1 topology json Signed-off-by: Philippe Guibert --- .../isis_topo1_vrf/r1/r1_topology.json | 156 +++++----- .../isis_topo1_vrf/r2/r2_topology.json | 156 +++++----- .../isis_topo1_vrf/r3/r3_topology.json | 274 +++++++++--------- .../isis_topo1_vrf/r4/r4_topology.json | 274 +++++++++--------- .../isis_topo1_vrf/r5/r5_topology.json | 242 ++++++++-------- .../isis_topo1_vrf/test_isis_topo1_vrf.py | 54 +--- 6 files changed, 571 insertions(+), 585 deletions(-) diff --git a/tests/topotests/isis_topo1_vrf/r1/r1_topology.json b/tests/topotests/isis_topo1_vrf/r1/r1_topology.json index 666fa52b19a2..8d4ccc84cc9e 100644 --- a/tests/topotests/isis_topo1_vrf/r1/r1_topology.json +++ b/tests/topotests/isis_topo1_vrf/r1/r1_topology.json @@ -1,80 +1,82 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r1" - } - ], - "ipv6": [ - { - "vertex": "r1" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r1" - }, - { - "metric": "0", - "parent": "r1(4)", - "type": "IP internal", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r1(4)", - "type": "TE-IS", - "vertex": "r3" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - } - ], - "ipv6": [ - { - "vertex": "r1" - }, - { - "metric": "0", - "parent": "r1(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - }, - { - "interface": "r1-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r1(4)", - "type": "TE-IS", - "vertex": "r3" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r1" + } + ], + "ipv6-paths": [ + { + "Vertex": "r1" + } + ] }, - { - "metric": "10", - "interface": "r1-eth0", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r1" + }, + { + "Metric": 0, + "Parent": "r1(4)", + "Type": "IP internal", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r1(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + } + ], + "ipv6-paths": [ + { + "Vertex": "r1" + }, + { + "Metric": 0, + "Parent": "r1(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + }, + { + "Interface": "r1-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r1(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Metric": 10, + "Interface": "r1-eth0", + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1_vrf/r2/r2_topology.json b/tests/topotests/isis_topo1_vrf/r2/r2_topology.json index c26ad1ee37e4..dc87c4282298 100644 --- a/tests/topotests/isis_topo1_vrf/r2/r2_topology.json +++ b/tests/topotests/isis_topo1_vrf/r2/r2_topology.json @@ -1,80 +1,82 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r2" - } - ], - "ipv6": [ - { - "vertex": "r2" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r2" - }, - { - "metric": "0", - "parent": "r2(4)", - "type": "IP internal", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r2(4)", - "type": "TE-IS", - "vertex": "r4" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" - } - ], - "ipv6": [ - { - "vertex": "r2" - }, - { - "metric": "0", - "parent": "r2(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - }, - { - "interface": "r2-eth0", - "metric": "10", - "next-hop": "r4", - "parent": "r2(4)", - "type": "TE-IS", - "vertex": "r4" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r2" + } + ], + "ipv6-paths": [ + { + "Vertex": "r2" + } + ] }, - { - "metric": "10", - "interface": "r2-eth0", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r2" + }, + { + "Metric": 0, + "Parent": "r2(4)", + "Type": "IP internal", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r2(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + } + ], + "ipv6-paths": [ + { + "Vertex": "r2" + }, + { + "Metric": 0, + "Parent": "r2(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + }, + { + "Interface": "r2-eth0", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r2(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Metric": 10, + "Interface": "r2-eth0", + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json index 044a6c0438aa..602dc7df55f1 100644 --- a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json +++ b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json @@ -1,132 +1,148 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r3" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP internal", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r3-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Interface": "r3-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + } + ], + "ipv6-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + }, + { + "Interface": "r3-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Metric": 10, + "Interface": "r3-eth1", + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + }, + { + "Interface": "r3-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Metric": 20, + "Interface": "r3-eth1", + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + } + ] }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP internal", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r3-eth1", - "metric": "20", - "next-hop": "r5", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - } - ], - "ipv6": [ - { - "vertex": "r3" - }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" - }, - { - "interface": "r3-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "metric": "10", - "interface": "r3-eth1", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" - }, - { - "metric": "20", - "interface": "r3-eth1", - "next-hop": "r5", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r3" - }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP internal", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r1", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r1" - }, - { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r1", - "parent": "r1(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - } - ], - "ipv6": [ - { - "vertex": "r3" - }, - { - "metric": "0", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - }, - { - "interface": "r3-eth0", - "metric": "10", - "next-hop": "r1", - "parent": "r3(4)", - "type": "TE-IS", - "vertex": "r1" + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP internal", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r3-eth0", + "Metric": 10, + "Next-Hop": "r1", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r1" + }, + { + "Interface": "r3-eth0", + "Metric": 10, + "Next-Hop": "r1", + "Parent": "r1(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + } + ], + "ipv6-paths": [ + { + "Vertex": "r3" + }, + { + "Metric": 0, + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + }, + { + "Interface": "r3-eth0", + "Metric": 10, + "Next-Hop": "r1", + "Parent": "r3(4)", + "Type": "TE-IS", + "Vertex": "r1" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1_vrf/r4/r4_topology.json b/tests/topotests/isis_topo1_vrf/r4/r4_topology.json index d40008aa3013..f4c1bb376838 100644 --- a/tests/topotests/isis_topo1_vrf/r4/r4_topology.json +++ b/tests/topotests/isis_topo1_vrf/r4/r4_topology.json @@ -1,132 +1,148 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r4" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP internal", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r4-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r4-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + } + ], + "ipv6-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + }, + { + "Interface": "r4-eth1", + "Metric": 10, + "Next-Hop": "r5", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r5" + }, + { + "Metric": 10, + "Interface": "r4-eth1", + "Next-Hop": "r5", + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + }, + { + "Interface": "r4-eth1", + "Metric": 20, + "Next-Hop": "r5", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Metric": 20, + "Interface": "r4-eth1", + "Next-Hop": "r5", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + } + ] }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP internal", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r4-eth1", - "metric": "20", - "next-hop": "r5", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - } - ], - "ipv6": [ - { - "vertex": "r4" - }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" - }, - { - "interface": "r4-eth1", - "metric": "10", - "next-hop": "r5", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r5" - }, - { - "metric": "10", - "interface": "r4-eth1", - "next-hop": "r5", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" - }, - { - "metric": "20", - "interface": "r4-eth1", - "next-hop": "r5", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - } - ] - }, - "level-2": { - "ipv4": [ - { - "vertex": "r4" - }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP internal", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r2" - }, - { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r2(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - } - ], - "ipv6": [ - { - "vertex": "r4" - }, - { - "metric": "0", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - }, - { - "interface": "r4-eth0", - "metric": "10", - "next-hop": "r2", - "parent": "r4(4)", - "type": "TE-IS", - "vertex": "r2" + "level-2": { + "ipv4-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP internal", + "Vertex": "10.0.21.0/24" + }, + { + "Interface": "r4-eth0", + "Metric": 10, + "Next-Hop": "r2", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r2" + }, + { + "Interface": "r4-eth0", + "Metric": 10, + "Next-Hop": "r2", + "Parent": "r2(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + } + ], + "ipv6-paths": [ + { + "Vertex": "r4" + }, + { + "Metric": 0, + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + }, + { + "Interface": "r4-eth0", + "Metric": 10, + "Next-Hop": "r2", + "Parent": "r4(4)", + "Type": "TE-IS", + "Vertex": "r2" + } + ] } - ] } - } -} +] diff --git a/tests/topotests/isis_topo1_vrf/r5/r5_topology.json b/tests/topotests/isis_topo1_vrf/r5/r5_topology.json index 2a088cae3061..669f31c474d3 100644 --- a/tests/topotests/isis_topo1_vrf/r5/r5_topology.json +++ b/tests/topotests/isis_topo1_vrf/r5/r5_topology.json @@ -1,124 +1,122 @@ -{ - "1": { - "level-1": { - "ipv4": [ - { - "vertex": "r5" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP internal", - "vertex": "10.0.10.0/24" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP internal", - "vertex": "10.0.11.0/24" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r3" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r4" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.20.0/24" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP TE", - "vertex": "10.0.10.0/24" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.21.0/24" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP TE", - "vertex": "10.0.11.0/24" +[ + { + "area": "1", + "algorithm": 0, + "level-1": { + "ipv4-paths": [ + { + "Vertex": "r5" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP internal", + "Vertex": "10.0.10.0/24" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP internal", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.10.0/24" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP TE", + "Vertex": "10.0.20.0/24" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.11.0/24" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP TE", + "Vertex": "10.0.21.0/24" + } + ], + "ipv6-paths": [ + { + "Vertex": "r5" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:1::/64" + }, + { + "Metric": 0, + "Parent": "r5(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:2:2::/64" + }, + { + "Interface": "r5-eth0", + "Metric": 10, + "Next-Hop": "r3", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r3" + }, + { + "Interface": "r5-eth1", + "Metric": 10, + "Next-Hop": "r4", + "Parent": "r5(4)", + "Type": "TE-IS", + "Vertex": "r4" + }, + { + "Metric": 10, + "Interface": "r5-eth0", + "Next-Hop": "r3", + "Parent": "r3(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:1::/64" + }, + { + "Metric": 10, + "Interface": "r5-eth1", + "Next-Hop": "r4", + "Parent": "r4(4)", + "Type": "IP6 internal", + "Vertex": "2001:db8:1:2::/64" + } + ] } - ], - "ipv6": [ - { - "vertex": "r5" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:1::/64" - }, - { - "metric": "0", - "parent": "r5(4)", - "type": "IP6 internal", - "vertex": "2001:db8:2:2::/64" - }, - { - "interface": "r5-eth0", - "metric": "10", - "next-hop": "r3", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r3" - }, - { - "interface": "r5-eth1", - "metric": "10", - "next-hop": "r4", - "parent": "r5(4)", - "type": "TE-IS", - "vertex": "r4" - }, - { - "metric": "10", - "interface": "r5-eth0", - "next-hop": "r3", - "parent": "r3(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:1::/64" - }, - { - "metric": "10", - "interface": "r5-eth1", - "next-hop": "r4", - "parent": "r4(4)", - "type": "IP6 internal", - "vertex": "2001:db8:1:2::/64" - } - ] - }, - "level-2": { - "ipv4": [], - "ipv6": [] } - } -} +] diff --git a/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py b/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py index 7aac7c704da9..afc6864b98c9 100644 --- a/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py +++ b/tests/topotests/isis_topo1_vrf/test_isis_topo1_vrf.py @@ -141,8 +141,9 @@ def test_isis_convergence(): def compare_isis_topology(router, expected): "Helper function to test ISIS vrf topology convergence." - actual = show_isis_topology(router) - + actual = json.loads( + router.vtysh_cmd(f"show isis vrf {router.name}-cust1 topology json") + ) return topotest.json_cmp(actual, expected) test_func = functools.partial(compare_isis_topology, router, expected) @@ -377,52 +378,3 @@ def parse_topology(lines, level): continue return areas - - -def show_isis_topology(router): - """ - Get the ISIS vrf topology in a dictionary format. - - Sample: - { - 'area-name': { - 'level-1': [ - { - 'vertex': 'r1' - } - ], - 'level-2': [ - { - 'vertex': '10.0.0.1/24', - 'type': 'IP', - 'parent': '0', - 'metric': 'internal' - } - ] - }, - 'area-name-2': { - 'level-2': [ - { - "interface": "rX-ethY", - "metric": "Z", - "next-hop": "rA", - "parent": "rC(B)", - "type": "TE-IS", - "vertex": "rD" - } - ] - } - } - """ - l1out = topotest.normalize_text( - router.vtysh_cmd("show isis vrf {}-cust1 topology level-1".format(router.name)) - ).splitlines() - l2out = topotest.normalize_text( - router.vtysh_cmd("show isis vrf {}-cust1 topology level-2".format(router.name)) - ).splitlines() - - l1 = parse_topology(l1out, "level-1") - l2 = parse_topology(l2out, "level-2") - - dict_merge(l1, l2) - return l1 From d0a142aae46789fd9a7e541e61b9b7b52ea742cd Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 19 Jun 2024 16:05:33 +0200 Subject: [PATCH 335/472] isisd: override json fields for monitored paths The json output for isis route paths should use caml format. Signed-off-by: Philippe Guibert --- isisd/isis_spf.c | 4 +- .../topotests/isis_topo1/r1/r1_topology.json | 108 ++++---- .../topotests/isis_topo1/r2/r2_topology.json | 108 ++++---- .../topotests/isis_topo1/r3/r3_topology.json | 252 +++++++++--------- .../topotests/isis_topo1/r4/r4_topology.json | 252 +++++++++--------- .../topotests/isis_topo1/r5/r5_topology.json | 204 +++++++------- .../isis_topo1_vrf/r1/r1_topology.json | 84 +++--- .../isis_topo1_vrf/r2/r2_topology.json | 84 +++--- .../isis_topo1_vrf/r3/r3_topology.json | 180 ++++++------- .../isis_topo1_vrf/r4/r4_topology.json | 180 ++++++------- .../isis_topo1_vrf/r5/r5_topology.json | 156 +++++------ 11 files changed, 807 insertions(+), 805 deletions(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 86d998c41958..d6ce76960be6 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2336,7 +2336,9 @@ static void isis_print_paths(struct vty *vty, struct isis_vertex_queue *queue, vty_out(vty, "%s\n", table); XFREE(MTYPE_TMP, table); } else - *json = ttable_json(tt, "ssdsss"); + *json = ttable_json_with_json_text( + tt, "ssdsss", + "vertex|type|metric|nextHop|interface|parent"); ttable_del(tt); } diff --git a/tests/topotests/isis_topo1/r1/r1_topology.json b/tests/topotests/isis_topo1/r1/r1_topology.json index d52346df6f7a..6b3374cc4d6f 100644 --- a/tests/topotests/isis_topo1/r1/r1_topology.json +++ b/tests/topotests/isis_topo1/r1/r1_topology.json @@ -5,92 +5,92 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r1" + "vertex": "r1" } ], "ipv6-paths": [ { - "Vertex": "r1" + "vertex": "r1" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r1" + "vertex": "r1" }, { - "Metric": 0, - "Parent": "r1(4)", - "Type": "IP internal", - "Vertex": "10.0.20.0/24" + "metric": 0, + "parent": "r1(4)", + "type": "IP internal", + "vertex": "10.0.20.0/24" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r1(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r1(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.254.0.3/32" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.254.0.3/32" } ], "ipv6-paths": [ { - "Vertex": "r1" + "vertex": "r1" }, { - "Metric": 0, - "Parent": "r1(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 0, + "parent": "r1(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r1(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r1(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Metric": 10, - "Interface": "r1-eth0", - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 10, + "interface": "r1-eth0", + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" }, { - "Metric": 10, - "Interface": "r1-eth0", - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::3/128" + "metric": 10, + "interface": "r1-eth0", + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::3/128" } ] } diff --git a/tests/topotests/isis_topo1/r2/r2_topology.json b/tests/topotests/isis_topo1/r2/r2_topology.json index d0a1f90fd081..8720bc1cac2c 100644 --- a/tests/topotests/isis_topo1/r2/r2_topology.json +++ b/tests/topotests/isis_topo1/r2/r2_topology.json @@ -5,92 +5,92 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r2" + "vertex": "r2" } ], "ipv6-paths": [ { - "Vertex": "r2" + "vertex": "r2" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r2" + "vertex": "r2" }, { - "Metric": 0, - "Parent": "r2(4)", - "Type": "IP internal", - "Vertex": "10.0.21.0/24" + "metric": 0, + "parent": "r2(4)", + "type": "IP internal", + "vertex": "10.0.21.0/24" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r2(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r2(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.254.0.4/32" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.254.0.4/32" } ], "ipv6-paths": [ { - "Vertex": "r2" + "vertex": "r2" }, { - "Metric": 0, - "Parent": "r2(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 0, + "parent": "r2(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r2(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r2(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Metric": 10, - "Interface": "r2-eth0", - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 10, + "interface": "r2-eth0", + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" }, { - "Metric": 10, - "Interface": "r2-eth0", - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::4/128" + "metric": 10, + "interface": "r2-eth0", + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::4/128" } ] } diff --git a/tests/topotests/isis_topo1/r3/r3_topology.json b/tests/topotests/isis_topo1/r3/r3_topology.json index 9265e62786cf..568b6dfeede8 100644 --- a/tests/topotests/isis_topo1/r3/r3_topology.json +++ b/tests/topotests/isis_topo1/r3/r3_topology.json @@ -5,190 +5,190 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP internal", - "Vertex": "10.0.10.0/24" + "metric": 0, + "parent": "r3(4)", + "type": "IP internal", + "vertex": "10.0.10.0/24" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.254.0.5/32" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.254.0.5/32" }, { - "Interface": "r3-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r3-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r4" }, { - "Interface": "r3-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r3-eth1", + "metric": 20, + "nextHop": "r5", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" }, { - "Interface": "r3-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.254.0.4/32" + "interface": "r3-eth1", + "metric": 20, + "nextHop": "r5", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.254.0.4/32" } ], "ipv6-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 0, + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Metric": 10, - "Interface": "r3-eth1", - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 10, + "interface": "r3-eth1", + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" }, { - "Metric": 10, - "Interface": "r3-eth1", - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::5/128" + "metric": 10, + "interface": "r3-eth1", + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::5/128" }, { - "Interface": "r3-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r3-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r4" }, { - "Metric": 20, - "Interface": "r3-eth1", - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 20, + "interface": "r3-eth1", + "nextHop": "r5", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" }, { - "Metric": 20, - "Interface": "r3-eth1", - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::4/128" + "metric": 20, + "interface": "r3-eth1", + "nextHop": "r5", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::4/128" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP internal", - "Vertex": "10.0.20.0/24" + "metric": 0, + "parent": "r3(4)", + "type": "IP internal", + "vertex": "10.0.20.0/24" }, { - "Interface": "r3-eth0", - "Metric": 10, - "Next-Hop": "r1", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r1" + "interface": "r3-eth0", + "metric": 10, + "nextHop": "r1", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r1" }, { - "Interface": "r3-eth0", - "Metric": 10, - "Next-Hop": "r1", - "Parent": "r1(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r3-eth0", + "metric": 10, + "nextHop": "r1", + "parent": "r1(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" }, { - "Interface": "r3-eth0", - "Metric": 10, - "Next-Hop": "r1", - "Parent": "r1(4)", - "Type": "IP TE", - "Vertex": "10.254.0.1/32" + "interface": "r3-eth0", + "metric": 10, + "nextHop": "r1", + "parent": "r1(4)", + "type": "IP TE", + "vertex": "10.254.0.1/32" } ], "ipv6-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 0, + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" }, { - "Interface": "r3-eth0", - "Metric": 10, - "Next-Hop": "r1", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r1" + "interface": "r3-eth0", + "metric": 10, + "nextHop": "r1", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r1" }, { - "Metric": 10, - "Interface": "r3-eth0", - "Next-Hop": "r1", - "Parent": "r1(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::1/128" + "metric": 10, + "interface": "r3-eth0", + "nextHop": "r1", + "parent": "r1(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::1/128" } ] } diff --git a/tests/topotests/isis_topo1/r4/r4_topology.json b/tests/topotests/isis_topo1/r4/r4_topology.json index 240c7588fc19..9a53955cc969 100644 --- a/tests/topotests/isis_topo1/r4/r4_topology.json +++ b/tests/topotests/isis_topo1/r4/r4_topology.json @@ -5,190 +5,190 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP internal", - "Vertex": "10.0.11.0/24" + "metric": 0, + "parent": "r4(4)", + "type": "IP internal", + "vertex": "10.0.11.0/24" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.254.0.5/32" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.254.0.5/32" }, { - "Interface": "r4-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r4-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r4-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r4-eth1", + "metric": 20, + "nextHop": "r5", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" }, { - "Interface": "r4-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.254.0.3/32" + "interface": "r4-eth1", + "metric": 20, + "nextHop": "r5", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.254.0.3/32" } ], "ipv6-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 0, + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Metric": 10, - "Interface": "r4-eth1", - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 10, + "interface": "r4-eth1", + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" }, { - "Metric": 10, - "Interface": "r4-eth1", - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::5/128" + "metric": 10, + "interface": "r4-eth1", + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::5/128" }, { - "Interface": "r4-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r4-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r3" }, { - "Metric": 20, - "Interface": "r4-eth1", - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 20, + "interface": "r4-eth1", + "nextHop": "r5", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" }, { - "Metric": 20, - "Interface": "r4-eth1", - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::3/128" + "metric": 20, + "interface": "r4-eth1", + "nextHop": "r5", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::3/128" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP internal", - "Vertex": "10.0.21.0/24" + "metric": 0, + "parent": "r4(4)", + "type": "IP internal", + "vertex": "10.0.21.0/24" }, { - "Interface": "r4-eth0", - "Metric": 10, - "Next-Hop": "r2", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r2" + "interface": "r4-eth0", + "metric": 10, + "nextHop": "r2", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r2" }, { - "Interface": "r4-eth0", - "Metric": 10, - "Next-Hop": "r2", - "Parent": "r2(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r4-eth0", + "metric": 10, + "nextHop": "r2", + "parent": "r2(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" }, { - "Interface": "r4-eth0", - "Metric": 10, - "Next-Hop": "r2", - "Parent": "r2(4)", - "Type": "IP TE", - "Vertex": "10.254.0.2/32" + "interface": "r4-eth0", + "metric": 10, + "nextHop": "r2", + "parent": "r2(4)", + "type": "IP TE", + "vertex": "10.254.0.2/32" } ], "ipv6-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 0, + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" }, { - "Interface": "r4-eth0", - "Metric": 10, - "Next-Hop": "r2", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r2" + "interface": "r4-eth0", + "metric": 10, + "nextHop": "r2", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r2" }, { - "Metric": 10, - "Interface": "r4-eth0", - "Next-Hop": "r2", - "Parent": "r2(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::2/128" + "metric": 10, + "interface": "r4-eth0", + "nextHop": "r2", + "parent": "r2(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::2/128" } ] } diff --git a/tests/topotests/isis_topo1/r5/r5_topology.json b/tests/topotests/isis_topo1/r5/r5_topology.json index 37da1a08e383..64590d8eb267 100644 --- a/tests/topotests/isis_topo1/r5/r5_topology.json +++ b/tests/topotests/isis_topo1/r5/r5_topology.json @@ -5,148 +5,148 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r5" + "vertex": "r5" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP internal", - "Vertex": "10.0.10.0/24" + "metric": 0, + "parent": "r5(4)", + "type": "IP internal", + "vertex": "10.0.10.0/24" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP internal", - "Vertex": "10.0.11.0/24" + "metric": 0, + "parent": "r5(4)", + "type": "IP internal", + "vertex": "10.0.11.0/24" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.254.0.3/32" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.254.0.3/32" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.254.0.4/32" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.254.0.4/32" } ], "ipv6-paths": [ { - "Vertex": "r5" + "vertex": "r5" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 0, + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 0, + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Metric": 10, - "Interface": "r5-eth0", - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 10, + "interface": "r5-eth0", + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" }, { - "Metric": 10, - "Interface": "r5-eth0", - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::3/128" + "metric": 10, + "interface": "r5-eth0", + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::3/128" }, { - "Metric": 10, - "Interface": "r5-eth1", - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 10, + "interface": "r5-eth1", + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" }, { - "Metric": 10, - "Interface": "r5-eth1", - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:f::4/128" + "metric": 10, + "interface": "r5-eth1", + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:f::4/128" } ] } diff --git a/tests/topotests/isis_topo1_vrf/r1/r1_topology.json b/tests/topotests/isis_topo1_vrf/r1/r1_topology.json index 8d4ccc84cc9e..da537c552bfa 100644 --- a/tests/topotests/isis_topo1_vrf/r1/r1_topology.json +++ b/tests/topotests/isis_topo1_vrf/r1/r1_topology.json @@ -5,76 +5,76 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r1" + "vertex": "r1" } ], "ipv6-paths": [ { - "Vertex": "r1" + "vertex": "r1" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r1" + "vertex": "r1" }, { - "Metric": 0, - "Parent": "r1(4)", - "Type": "IP internal", - "Vertex": "10.0.20.0/24" + "metric": 0, + "parent": "r1(4)", + "type": "IP internal", + "vertex": "10.0.20.0/24" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r1(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r1(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" } ], "ipv6-paths": [ { - "Vertex": "r1" + "vertex": "r1" }, { - "Metric": 0, - "Parent": "r1(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 0, + "parent": "r1(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" }, { - "Interface": "r1-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r1(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r1-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r1(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Metric": 10, - "Interface": "r1-eth0", - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 10, + "interface": "r1-eth0", + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" } ] } diff --git a/tests/topotests/isis_topo1_vrf/r2/r2_topology.json b/tests/topotests/isis_topo1_vrf/r2/r2_topology.json index dc87c4282298..bf965659bea5 100644 --- a/tests/topotests/isis_topo1_vrf/r2/r2_topology.json +++ b/tests/topotests/isis_topo1_vrf/r2/r2_topology.json @@ -5,76 +5,76 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r2" + "vertex": "r2" } ], "ipv6-paths": [ { - "Vertex": "r2" + "vertex": "r2" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r2" + "vertex": "r2" }, { - "Metric": 0, - "Parent": "r2(4)", - "Type": "IP internal", - "Vertex": "10.0.21.0/24" + "metric": 0, + "parent": "r2(4)", + "type": "IP internal", + "vertex": "10.0.21.0/24" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r2(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r2(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" } ], "ipv6-paths": [ { - "Vertex": "r2" + "vertex": "r2" }, { - "Metric": 0, - "Parent": "r2(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 0, + "parent": "r2(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" }, { - "Interface": "r2-eth0", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r2(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r2-eth0", + "metric": 10, + "nextHop": "r4", + "parent": "r2(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Metric": 10, - "Interface": "r2-eth0", - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 10, + "interface": "r2-eth0", + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" } ] } diff --git a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json index 602dc7df55f1..94592b50a72a 100644 --- a/tests/topotests/isis_topo1_vrf/r3/r3_topology.json +++ b/tests/topotests/isis_topo1_vrf/r3/r3_topology.json @@ -5,142 +5,142 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP internal", - "Vertex": "10.0.10.0/24" + "metric": 0, + "parent": "r3(4)", + "type": "IP internal", + "vertex": "10.0.10.0/24" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r3-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r3-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r4" }, { - "Interface": "r3-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r3-eth1", + "metric": 20, + "nextHop": "r5", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" } ], "ipv6-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 0, + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" }, { - "Interface": "r3-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r3-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Metric": 10, - "Interface": "r3-eth1", - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 10, + "interface": "r3-eth1", + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" }, { - "Interface": "r3-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r3-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r4" }, { - "Metric": 20, - "Interface": "r3-eth1", - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 20, + "interface": "r3-eth1", + "nextHop": "r5", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP internal", - "Vertex": "10.0.20.0/24" + "metric": 0, + "parent": "r3(4)", + "type": "IP internal", + "vertex": "10.0.20.0/24" }, { - "Interface": "r3-eth0", - "Metric": 10, - "Next-Hop": "r1", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r1" + "interface": "r3-eth0", + "metric": 10, + "nextHop": "r1", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r1" }, { - "Interface": "r3-eth0", - "Metric": 10, - "Next-Hop": "r1", - "Parent": "r1(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r3-eth0", + "metric": 10, + "nextHop": "r1", + "parent": "r1(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" } ], "ipv6-paths": [ { - "Vertex": "r3" + "vertex": "r3" }, { - "Metric": 0, - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 0, + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" }, { - "Interface": "r3-eth0", - "Metric": 10, - "Next-Hop": "r1", - "Parent": "r3(4)", - "Type": "TE-IS", - "Vertex": "r1" + "interface": "r3-eth0", + "metric": 10, + "nextHop": "r1", + "parent": "r3(4)", + "type": "TE-IS", + "vertex": "r1" } ] } diff --git a/tests/topotests/isis_topo1_vrf/r4/r4_topology.json b/tests/topotests/isis_topo1_vrf/r4/r4_topology.json index f4c1bb376838..b8295e87b9cc 100644 --- a/tests/topotests/isis_topo1_vrf/r4/r4_topology.json +++ b/tests/topotests/isis_topo1_vrf/r4/r4_topology.json @@ -5,142 +5,142 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP internal", - "Vertex": "10.0.11.0/24" + "metric": 0, + "parent": "r4(4)", + "type": "IP internal", + "vertex": "10.0.11.0/24" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r4-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r4-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r4-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r4-eth1", + "metric": 20, + "nextHop": "r5", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" } ], "ipv6-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 0, + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" }, { - "Interface": "r4-eth1", - "Metric": 10, - "Next-Hop": "r5", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r5" + "interface": "r4-eth1", + "metric": 10, + "nextHop": "r5", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r5" }, { - "Metric": 10, - "Interface": "r4-eth1", - "Next-Hop": "r5", - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 10, + "interface": "r4-eth1", + "nextHop": "r5", + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" }, { - "Interface": "r4-eth1", - "Metric": 20, - "Next-Hop": "r5", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r4-eth1", + "metric": 20, + "nextHop": "r5", + "type": "TE-IS", + "vertex": "r3" }, { - "Metric": 20, - "Interface": "r4-eth1", - "Next-Hop": "r5", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 20, + "interface": "r4-eth1", + "nextHop": "r5", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" } ] }, "level-2": { "ipv4-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP internal", - "Vertex": "10.0.21.0/24" + "metric": 0, + "parent": "r4(4)", + "type": "IP internal", + "vertex": "10.0.21.0/24" }, { - "Interface": "r4-eth0", - "Metric": 10, - "Next-Hop": "r2", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r2" + "interface": "r4-eth0", + "metric": 10, + "nextHop": "r2", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r2" }, { - "Interface": "r4-eth0", - "Metric": 10, - "Next-Hop": "r2", - "Parent": "r2(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r4-eth0", + "metric": 10, + "nextHop": "r2", + "parent": "r2(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" } ], "ipv6-paths": [ { - "Vertex": "r4" + "vertex": "r4" }, { - "Metric": 0, - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 0, + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" }, { - "Interface": "r4-eth0", - "Metric": 10, - "Next-Hop": "r2", - "Parent": "r4(4)", - "Type": "TE-IS", - "Vertex": "r2" + "interface": "r4-eth0", + "metric": 10, + "nextHop": "r2", + "parent": "r4(4)", + "type": "TE-IS", + "vertex": "r2" } ] } diff --git a/tests/topotests/isis_topo1_vrf/r5/r5_topology.json b/tests/topotests/isis_topo1_vrf/r5/r5_topology.json index 669f31c474d3..8b5159cbfbd2 100644 --- a/tests/topotests/isis_topo1_vrf/r5/r5_topology.json +++ b/tests/topotests/isis_topo1_vrf/r5/r5_topology.json @@ -5,116 +5,116 @@ "level-1": { "ipv4-paths": [ { - "Vertex": "r5" + "vertex": "r5" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP internal", - "Vertex": "10.0.10.0/24" + "metric": 0, + "parent": "r5(4)", + "type": "IP internal", + "vertex": "10.0.10.0/24" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP internal", - "Vertex": "10.0.11.0/24" + "metric": 0, + "parent": "r5(4)", + "type": "IP internal", + "vertex": "10.0.11.0/24" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.10.0/24" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.10.0/24" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP TE", - "Vertex": "10.0.20.0/24" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP TE", + "vertex": "10.0.20.0/24" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.11.0/24" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.11.0/24" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP TE", - "Vertex": "10.0.21.0/24" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP TE", + "vertex": "10.0.21.0/24" } ], "ipv6-paths": [ { - "Vertex": "r5" + "vertex": "r5" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:1::/64" + "metric": 0, + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:1::/64" }, { - "Metric": 0, - "Parent": "r5(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:2:2::/64" + "metric": 0, + "parent": "r5(4)", + "type": "IP6 internal", + "vertex": "2001:db8:2:2::/64" }, { - "Interface": "r5-eth0", - "Metric": 10, - "Next-Hop": "r3", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r3" + "interface": "r5-eth0", + "metric": 10, + "nextHop": "r3", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r3" }, { - "Interface": "r5-eth1", - "Metric": 10, - "Next-Hop": "r4", - "Parent": "r5(4)", - "Type": "TE-IS", - "Vertex": "r4" + "interface": "r5-eth1", + "metric": 10, + "nextHop": "r4", + "parent": "r5(4)", + "type": "TE-IS", + "vertex": "r4" }, { - "Metric": 10, - "Interface": "r5-eth0", - "Next-Hop": "r3", - "Parent": "r3(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:1::/64" + "metric": 10, + "interface": "r5-eth0", + "nextHop": "r3", + "parent": "r3(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:1::/64" }, { - "Metric": 10, - "Interface": "r5-eth1", - "Next-Hop": "r4", - "Parent": "r4(4)", - "Type": "IP6 internal", - "Vertex": "2001:db8:1:2::/64" + "metric": 10, + "interface": "r5-eth1", + "nextHop": "r4", + "parent": "r4(4)", + "type": "IP6 internal", + "vertex": "2001:db8:1:2::/64" } ] } From 611f83f324a4e2a9cb0611fd74de8b32a8d22dd6 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 19 Jun 2024 16:10:48 +0200 Subject: [PATCH 336/472] isisd: change the json output for isis routes The json format for json routes should be compliant with caml format. Before: > "Prefix|Metric|Interface|Nexthop|SID|LabelOp|Algo": > "Prefix|Metric|Interface|Nexthop|Label(s)"); After: > "prefix|metric|interface|nextHop|segmentIdentifier|labelOperation|Algorithm": > "prefix|metric|interface|nextHop|label(s)"); Signed-off-by: Philippe Guibert --- isisd/isis_spf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index d6ce76960be6..7aa9147e71c0 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -3015,7 +3015,11 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree, vty_out(vty, "%s\n", table); XFREE(MTYPE_TMP, table); } else if (json) { - *json = ttable_json(tt, prefix_sid ? "sdssdsdd" : "sdsss"); + *json = ttable_json_with_json_text( + tt, prefix_sid ? "sdssdsdd" : "sdsss", + prefix_sid + ? "prefix|metric|interface|nextHop|segmentIdentifier|labelOperation|Algorithm" + : "prefix|metric|interface|nextHop|label(s)"); } ttable_del(tt); } From c06fb90b63ccf2c4d1220f4d8e4b423bc4fc6a40 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 21 Jun 2024 10:59:43 +0200 Subject: [PATCH 337/472] isisd: fix display crash srv6 sid structure in json Fix a crash when doing "show isis database detail json" in isis_srv6_topo1 topotest. > #0 raise (sig=) at ../sysdeps/unix/sysv/linux/raise.c:50 > #1 0x00007fad89524e2c in core_handler (signo=6, siginfo=0x7ffe86a4b8b0, context=0x7ffe86a4b780) at lib/sigevent.c:258 > #2 > #3 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 > #4 0x00007fad8904e537 in __GI_abort () at abort.c:79 > #5 0x00007fad8904e40f in __assert_fail_base (fmt=0x7fad891c5688 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x7fad8a3e70e8 "json_object_get_type(jso) == json_type_object", > file=0x7fad8a3e7064 "./json_object.c", line=590, function=) at assert.c:92 > #6 0x00007fad8905d662 in __GI___assert_fail (assertion=0x7fad8a3e70e8 "json_object_get_type(jso) == json_type_object", file=0x7fad8a3e7064 "./json_object.c", line=590, > function=0x7fad8a3e7440 "json_object_object_add_ex") at assert.c:101 > #7 0x00007fad8a3dfe93 in json_object_object_add_ex () from /lib/x86_64-linux-gnu/libjson-c.so.5 > #8 0x000055708e3f8f7f in format_subsubtlv_srv6_sid_structure (sid_struct=0x602000172b70, buf=0x0, json=0x6040000a21d0, indent=6) at isisd/isis_tlvs.c:2880 > #9 0x000055708e3f9acb in isis_format_subsubtlvs (subsubtlvs=0x602000172b50, buf=0x0, json=0x6040000a21d0, indent=6) at isisd/isis_tlvs.c:3022 > #10 0x000055708e3eefb0 in format_item_ext_subtlvs (exts=0x614000047440, buf=0x0, json=0x6040000a2190, indent=2, mtid=2) at isisd/isis_tlvs.c:1313 > #11 0x000055708e3fd599 in format_item_extended_reach (mtid=2, i=0x60300015aed0, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:3763 > #12 0x000055708e40d46a in format_item (mtid=2, context=ISIS_CONTEXT_LSP, type=ISIS_TLV_MT_REACH, i=0x60300015aed0, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:6789 > #13 0x000055708e40d4fc in format_items_ (mtid=2, context=ISIS_CONTEXT_LSP, type=ISIS_TLV_MT_REACH, items=0x60600021d160, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:6804 > #14 0x000055708e40edbc in format_mt_items (context=ISIS_CONTEXT_LSP, type=ISIS_TLV_MT_REACH, m=0x6180000845d8, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:7147 > #15 0x000055708e4111e9 in format_tlvs (tlvs=0x618000084480, buf=0x0, json=0x6040000a1bd0, indent=0) at isisd/isis_tlvs.c:7572 > #16 0x000055708e4114ce in isis_format_tlvs (tlvs=0x618000084480, json=0x6040000a1bd0) at isisd/isis_tlvs.c:7613 > #17 0x000055708e36f167 in lsp_print_detail (lsp=0x612000058b40, vty=0x0, json=0x6040000a1bd0, dynhost=1 '\001', isis=0x60d00001f800) at isisd/isis_lsp.c:785 > #18 0x000055708e36f31f in lsp_print_all (vty=0x0, json=0x6040000a0490, head=0x61f000005488, detail=1 '\001', dynhost=1 '\001', isis=0x60d00001f800) at isisd/isis_lsp.c:820 > #19 0x000055708e4379fc in show_isis_database_lspdb_json (json=0x6040000a0450, area=0x61f000005480, level=0, lspdb=0x61f000005488, sysid_str=0x0, ui_level=1) at isisd/isisd.c:2683 > #20 0x000055708e437ef9 in show_isis_database_json (json=0x6040000a0310, sysid_str=0x0, ui_level=1, isis=0x60d00001f800) at isisd/isisd.c:2754 > #21 0x000055708e438357 in show_isis_database_common (vty=0x62e000060400, json=0x6040000a0310, sysid_str=0x0, ui_level=1, isis=0x60d00001f800) at isisd/isisd.c:2788 > #22 0x000055708e438591 in show_isis_database (vty=0x62e000060400, json=0x6040000a0310, sysid_str=0x0, ui_level=1, vrf_name=0x7fad89806300 "default", all_vrf=false) > at isisd/isisd.c:2825 > #23 0x000055708e43891d in show_database (self=0x55708e5519c0 , vty=0x62e000060400, argc=5, argv=0x6040000a02d0) at isisd/isisd.c:2855 > #24 0x00007fad893a9767 in cmd_execute_command_real (vline=0x60300015f220, vty=0x62e000060400, cmd=0x0, up_level=0) at lib/command.c:1002 > #25 0x00007fad893a9adc in cmd_execute_command (vline=0x60300015f220, vty=0x62e000060400, cmd=0x0, vtysh=0) at lib/command.c:1061 > #26 0x00007fad893aa728 in cmd_execute (vty=0x62e000060400, cmd=0x621000025900 "show isis database detail json ", matched=0x0, vtysh=0) at lib/command.c:1227 Note that prior to 2e670cd779, there was no crash but only the last "srv6-sid-structure" was displayed. A "srv6-sid-structure" should be displayed for each "sid". This commit also fix this. Was: > "srv6-lan-endx-sid": [ > { > "sid": "fc00:0:1:1::", > "weight": 0, > "algorithm": "SPF", > "neighbor-id": "0000.0000.0002" > }, > { > "sid": "fc00:0:1:2::", > "weight": 0, > "algorithm": "SPF", > "neighbor-id": "0000.0000.0003" > } > ], > "srv6-sid-structure": { > "loc-block-len": 32, > "loc-node-len": 16, > "func-len": 16, > "arg-len": 0 > }, Now (srv6-sid-structure are identical but they are not always): > "srv6-lan-endx-sid": [ > { > "sid": "fc00:0:1:1::", > "algorithm": "SPF", > "neighbor-id": "0000.0000.0002", > "srv6-sid-structure": { > "loc-block-len": 32, > "loc-node-len": 16, > "func-len": 8, > "arg-len": 0 > }, > }, > { > "sid": "fc00:0:1:2::", > "algorithm": "SPF", > "neighbor-id": "0000.0000.0003", > "srv6-sid-structure": { > "loc-block-len": 32, > "loc-node-len": 16, > "func-len": 16, > "arg-len": 0 > }, > } > ], Fixes: 2e670cd779 ("isisd: fix display of srv6 subsubtlvs") Fixes: 648a158802 ("isisd: Add SRv6 End.X SID to Sub-TLV format func") Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 3bb8a4824698..1c345501525f 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -1311,8 +1311,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_array_add(arr_adj_json, flags_json); if (adj->subsubtlvs) isis_format_subsubtlvs(adj->subsubtlvs, - NULL, - arr_adj_json, + NULL, flags_json, indent + 4); } /* end old deprecated key format */ @@ -1350,8 +1349,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_array_add(arr_adj_json, flags_json); if (adj->subsubtlvs) isis_format_subsubtlvs(adj->subsubtlvs, - NULL, - arr_adj_json, + NULL, flags_json, indent + 4); } } else @@ -1432,8 +1430,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_array_add(arr_adj_json, flags_json); if (lan->subsubtlvs) isis_format_subsubtlvs(lan->subsubtlvs, - NULL, - arr_adj_json, + NULL, flags_json, indent + 4); } /* end old deprecated key format */ @@ -1477,8 +1474,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, json_object_array_add(arr_adj_json, flags_json); if (lan->subsubtlvs) isis_format_subsubtlvs(lan->subsubtlvs, - NULL, - arr_adj_json, + NULL, flags_json, indent + 4); } } else From fdb89ab51a83cd4cb1c4ce3068eba5e3a431954b Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 21 Jun 2024 17:01:49 +0200 Subject: [PATCH 338/472] zebra: Remove dead SRv6 code At line 1736, `alloc_mode` is set to `SRV6_SID_ALLOC_MODE_EXPLICIT` or `SRV6_SID_ALLOC_MODE_DYNAMIC` depending on the `sid_value` variable. There will never be a case where alloc_mode will be `SRV6_SID_ALLOC_MODE_MAX` or `SRV6_SID_ALLOC_MODE_UNSPEC`. Let's replace the `switch(alloc_mode) {...}` with an if-else. Fixes CID 1594015. ** CID 1594015: (DEADCODE) /zebra/zebra_srv6.c: 1782 in get_srv6_sid() /zebra/zebra_srv6.c: 1781 in get_srv6_sid() ________________________________________________________________________________________________________ *** CID 1594015: (DEADCODE) /zebra/zebra_srv6.c: 1782 in get_srv6_sid() 1776 } 1777 1778 ret = get_srv6_sid_dynamic(sid, ctx, locator); 1779 1780 break; 1781 case SRV6_SID_ALLOC_MODE_MAX: CID 1594015: (DEADCODE) Execution cannot reach this statement: "case SRV6_SID_ALLOC_MODE_UN...". 1782 case SRV6_SID_ALLOC_MODE_UNSPEC: 1783 default: 1784 flog_err(EC_ZEBRA_SM_CANNOT_ASSIGN_SID, 1785 "%s: SRv6 Manager: Unrecognized alloc mode %u", 1786 __func__, alloc_mode); 1787 /* We should never arrive here */ /zebra/zebra_srv6.c: 1781 in get_srv6_sid() 1775 return -1; 1776 } 1777 1778 ret = get_srv6_sid_dynamic(sid, ctx, locator); 1779 1780 break; CID 1594015: (DEADCODE) Execution cannot reach this statement: "case SRV6_SID_ALLOC_MODE_MAX:". 1781 case SRV6_SID_ALLOC_MODE_MAX: 1782 case SRV6_SID_ALLOC_MODE_UNSPEC: 1783 default: 1784 flog_err(EC_ZEBRA_SM_CANNOT_ASSIGN_SID, 1785 "%s: SRv6 Manager: Unrecognized alloc mode %u", 1786 __func__, alloc_mode); Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 0ca77a49740c..2c1f86a3fc3c 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -1742,8 +1742,7 @@ int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx, __func__, srv6_sid_ctx2str(buf, sizeof(buf), ctx), sid_value, srv6_sid_alloc_mode2str(alloc_mode)); - switch (alloc_mode) { - case SRV6_SID_ALLOC_MODE_EXPLICIT: + if (alloc_mode == SRV6_SID_ALLOC_MODE_EXPLICIT) { /* * Explicit SID allocation: allocate a specific SID value */ @@ -1755,9 +1754,7 @@ int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx, } ret = get_srv6_sid_explicit(sid, ctx, sid_value); - - break; - case SRV6_SID_ALLOC_MODE_DYNAMIC: + } else { /* * Dynamic SID allocation: allocate any available SID value */ @@ -1776,16 +1773,6 @@ int get_srv6_sid(struct zebra_srv6_sid **sid, struct srv6_sid_ctx *ctx, } ret = get_srv6_sid_dynamic(sid, ctx, locator); - - break; - case SRV6_SID_ALLOC_MODE_MAX: - case SRV6_SID_ALLOC_MODE_UNSPEC: - default: - flog_err(EC_ZEBRA_SM_CANNOT_ASSIGN_SID, - "%s: SRv6 Manager: Unrecognized alloc mode %u", - __func__, alloc_mode); - /* We should never arrive here */ - assert(0); } return ret; From 375a02d2a30cd7a06b568187e23226ad5d083c87 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 21 Jun 2024 17:41:34 +0200 Subject: [PATCH 339/472] zebra: Fix wrong variable used in `for` loop The `for` loop starting at line 1848 searches the `func_allocated` array for a pointer that points to a specific `sid_wide_func` element. The loop should iterate over all the elements of the `func_allocated` array and dereference each element to see if it is the one we are looking for. Currently, the loop is using the wrong variable to iterate over the array. Let's fix this issue by using the correct variable in the loop. Fixes CID 1594014 Fixes CID 1594016 ** CID 1594014: Null pointer dereferences (FORWARD_NULL) /zebra/zebra_srv6.c: 1860 in release_srv6_sid_func_explicit() ________________________________________________________________________________________________________ *** CID 1594014: Null pointer dereferences (FORWARD_NULL) /zebra/zebra_srv6.c: 1860 in release_srv6_sid_func_explicit() 1854 1855 /* Lookup SID function in the functions allocated list of EWLIB range */ 1856 for (ALL_LIST_ELEMENTS_RO(block->u.usid 1857 .wide_lib[sid_func] 1858 .func_allocated, 1859 node, sid_func_ptr)) CID 1594014: Null pointer dereferences (FORWARD_NULL) Dereferencing null pointer "sid_wide_func_ptr". 1860 if (*sid_wide_func_ptr == sid_wide_func) 1861 break; 1862 1863 /* Ensure that the SID function is allocated */ 1864 if (!sid_wide_func_ptr) { 1865 zlog_warn("%s: failed to release wide SID function %u, function is not allocated", ** CID 1594016: Possible Control flow issues (DEADCODE) /zebra/zebra_srv6.c: 1871 in release_srv6_sid_func_explicit() ________________________________________________________________________________________________________ *** CID 1594016: Possible Control flow issues (DEADCODE) /zebra/zebra_srv6.c: 1871 in release_srv6_sid_func_explicit() 1865 zlog_warn("%s: failed to release wide SID function %u, function is not allocated", 1866 __func__, sid_wide_func); 1867 return -1; 1868 } 1869 1870 /* Release the SID function from the EWLIB range */ CID 1594016: Possible Control flow issues (DEADCODE) Execution cannot reach this statement: "listnode_delete(block->u.us...". 1871 listnode_delete(block->u.usid.wide_lib[sid_func] 1872 .func_allocated, 1873 sid_wide_func_ptr); 1874 zebra_srv6_sid_func_free(sid_wide_func_ptr); 1875 } else { 1876 zlog_warn("%s: function %u is outside ELIB [%u/%u] and EWLIB alloc ranges [%u/%u]", Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 2c1f86a3fc3c..be335a5dedf2 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -1843,7 +1843,7 @@ static bool release_srv6_sid_func_explicit(struct zebra_srv6_sid_block *block, for (ALL_LIST_ELEMENTS_RO(block->u.usid .wide_lib[sid_func] .func_allocated, - node, sid_func_ptr)) + node, sid_wide_func_ptr)) if (*sid_wide_func_ptr == sid_wide_func) break; From df97a9d13318f15c59bb055b90529e9e8378a619 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Fri, 21 Jun 2024 17:47:46 +0200 Subject: [PATCH 340/472] zebra: Fix NULL pointer dereference The `locator` pointer is dereferenced before ensuring it is not NULL. Fix the issue by checking that the pointer is not NULL before dereferencing it. Fixes 1594013 ** CID 1594013: Null pointer dereferences (REVERSE_INULL) /zebra/zebra_srv6.c: 961 in zebra_srv6_sid_compose() ________________________________________________________________________________________________________ *** CID 1594013: Null pointer dereferences (REVERSE_INULL) /zebra/zebra_srv6.c: 961 in zebra_srv6_sid_compose() 955 struct srv6_locator *locator, 956 uint32_t sid_func) 957 { 958 uint8_t offset, func_len; 959 struct srv6_sid_format *format = locator->sid_format; 960 CID 1594013: Null pointer dereferences (REVERSE_INULL) Null-checking "locator" suggests that it may be null, but it has already been dereferenced on all paths leading to the check. 961 if (!sid_value || !locator) 962 return false; 963 964 if (format) { 965 offset = format->block_len + format->node_len; 966 func_len = format->function_len; Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index be335a5dedf2..e82b781c6fea 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -956,11 +956,12 @@ static bool zebra_srv6_sid_compose(struct in6_addr *sid_value, uint32_t sid_func) { uint8_t offset, func_len; - struct srv6_sid_format *format = locator->sid_format; + struct srv6_sid_format *format; if (!sid_value || !locator) return false; + format = locator->sid_format; if (format) { offset = format->block_len + format->node_len; func_len = format->function_len; From c554b5d90a40d16423a015849b76d56045fb7702 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 21 Jun 2024 11:17:32 +0200 Subject: [PATCH 341/472] isisd: remane flags_json variable The variable flags_json was incorrectly named, leading to confusion and causing the bug fixed in the previous commit. Rename the variable to refer to SRv6 End SID instead. Cosmetic change. Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 373 ++++++++++++++++++++++++---------------------- 1 file changed, 195 insertions(+), 178 deletions(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 1c345501525f..4ea384ef23bf 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -1010,7 +1010,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct isis_adj_sid *adj; if (json) { - struct json_object *arr_adj_json, *flags_json; + struct json_object *arr_adj_json, *adj_sid_json; #if CONFDATE > 20240916 CPP_NOTICE("remove deprecated key format with -") @@ -1022,42 +1022,37 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, adj; adj = adj->next) { snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", adj->sid); - flags_json = json_object_new_object(); - json_object_int_add(flags_json, "sid", + adj_sid_json = json_object_new_object(); + json_object_int_add(adj_sid_json, "sid", adj->sid); - json_object_int_add(flags_json, "weight", + json_object_int_add(adj_sid_json, "weight", adj->weight); - json_object_string_add( - flags_json, "flag-f", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-b", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-v", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-l", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-s", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-p", - adj->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG - ? "1" - : "0"); - json_object_array_add(arr_adj_json, flags_json); + json_object_string_add(adj_sid_json, "flag-f", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG + ? "1" + : "0"); + json_object_string_add(adj_sid_json, "flag-b", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG + ? "1" + : "0"); + json_object_string_add(adj_sid_json, "flag-v", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG + ? "1" + : "0"); + json_object_string_add(adj_sid_json, "flag-l", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG + ? "1" + : "0"); + json_object_string_add(adj_sid_json, "flag-s", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG + ? "1" + : "0"); + json_object_string_add(adj_sid_json, "flag-p", + adj->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG + ? "1" + : "0"); + json_object_array_add(arr_adj_json, + adj_sid_json); } /* end old deprecated key format */ @@ -1067,35 +1062,37 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, adj; adj = adj->next) { snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", adj->sid); - flags_json = json_object_new_object(); - json_object_int_add(flags_json, "sid", adj->sid); - json_object_int_add(flags_json, "weight", + adj_sid_json = json_object_new_object(); + json_object_int_add(adj_sid_json, "sid", + adj->sid); + json_object_int_add(adj_sid_json, "weight", adj->weight); - json_object_boolean_add(flags_json, "flagF", + json_object_boolean_add(adj_sid_json, "flagF", adj->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG ? true : false); - json_object_boolean_add(flags_json, "flagB", + json_object_boolean_add(adj_sid_json, "flagB", adj->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG ? true : false); - json_object_boolean_add(flags_json, "flagV", + json_object_boolean_add(adj_sid_json, "flagV", adj->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG ? true : false); - json_object_boolean_add(flags_json, "flagL", + json_object_boolean_add(adj_sid_json, "flagL", adj->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG ? true : false); - json_object_boolean_add(flags_json, "flagS", + json_object_boolean_add(adj_sid_json, "flagS", adj->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG ? true : false); - json_object_boolean_add(flags_json, "flagP", + json_object_boolean_add(adj_sid_json, "flagP", adj->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG ? true : false); - json_object_array_add(arr_adj_json, flags_json); + json_object_array_add(arr_adj_json, + adj_sid_json); } } else for (adj = (struct isis_adj_sid *)exts->adj_sid.head; @@ -1128,7 +1125,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (IS_SUBTLV(exts, EXT_LAN_ADJ_SID)) { struct isis_lan_adj_sid *lan; if (json) { - struct json_object *arr_adj_json, *flags_json; + struct json_object *arr_adj_json, *lan_adj_json; #if CONFDATE > 20240916 CPP_NOTICE("remove deprecated key format with -") @@ -1147,42 +1144,37 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, continue; snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", lan->sid); - flags_json = json_object_new_object(); - json_object_int_add(flags_json, "sid", + lan_adj_json = json_object_new_object(); + json_object_int_add(lan_adj_json, "sid", lan->sid); - json_object_int_add(flags_json, "weight", + json_object_int_add(lan_adj_json, "weight", lan->weight); - json_object_string_add( - flags_json, "flag-f", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-b", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-v", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-l", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-s", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-p", - lan->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG - ? "1" - : "0"); - json_object_array_add(arr_adj_json, flags_json); + json_object_string_add(lan_adj_json, "flag-f", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG + ? "1" + : "0"); + json_object_string_add(lan_adj_json, "flag-b", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG + ? "1" + : "0"); + json_object_string_add(lan_adj_json, "flag-v", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG + ? "1" + : "0"); + json_object_string_add(lan_adj_json, "flag-l", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG + ? "1" + : "0"); + json_object_string_add(lan_adj_json, "flag-s", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG + ? "1" + : "0"); + json_object_string_add(lan_adj_json, "flag-p", + lan->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG + ? "1" + : "0"); + json_object_array_add(arr_adj_json, + lan_adj_json); } /* end old deprecated key format */ @@ -1197,35 +1189,37 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, continue; snprintfrr(cnt_buf, sizeof(cnt_buf), "%d", lan->sid); - flags_json = json_object_new_object(); - json_object_int_add(flags_json, "sid", lan->sid); - json_object_int_add(flags_json, "weight", + lan_adj_json = json_object_new_object(); + json_object_int_add(lan_adj_json, "sid", + lan->sid); + json_object_int_add(lan_adj_json, "weight", lan->weight); - json_object_boolean_add(flags_json, "flagF", + json_object_boolean_add(lan_adj_json, "flagF", lan->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG ? true : false); - json_object_boolean_add(flags_json, "flagB", + json_object_boolean_add(lan_adj_json, "flagB", lan->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG ? true : false); - json_object_boolean_add(flags_json, "flagV", + json_object_boolean_add(lan_adj_json, "flagV", lan->flags & EXT_SUBTLV_LINK_ADJ_SID_VFLG ? true : false); - json_object_boolean_add(flags_json, "flagL", + json_object_boolean_add(lan_adj_json, "flagL", lan->flags & EXT_SUBTLV_LINK_ADJ_SID_LFLG ? true : false); - json_object_boolean_add(flags_json, "flagS", + json_object_boolean_add(lan_adj_json, "flagS", lan->flags & EXT_SUBTLV_LINK_ADJ_SID_SFLG ? true : false); - json_object_boolean_add(flags_json, "flagP", + json_object_boolean_add(lan_adj_json, "flagP", lan->flags & EXT_SUBTLV_LINK_ADJ_SID_PFLG ? true : false); - json_object_array_add(arr_adj_json, flags_json); + json_object_array_add(arr_adj_json, + lan_adj_json); } } else @@ -1268,7 +1262,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, struct isis_srv6_endx_sid_subtlv *adj; if (json) { - struct json_object *arr_adj_json, *flags_json; + struct json_object *arr_adj_json, *srv6_endx_sid_json; #if CONFDATE > 20240916 CPP_NOTICE("remove deprecated key format with -") @@ -1282,36 +1276,41 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, adj; adj = adj->next) { snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", &adj->sid); - flags_json = json_object_new_object(); - json_object_string_addf(flags_json, "sid", - "%pI6", &adj->sid); - json_object_string_add( - flags_json, "algorithm", - sr_algorithm_string(adj->algorithm)); - json_object_int_add(flags_json, "weight", - adj->weight); - json_object_string_add( - flags_json, "behavior", - seg6local_action2str(adj->behavior)); - json_object_string_add( - flags_json, "flag-b", - adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-s", - adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-p", - adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG - ? "1" - : "0"); - json_object_array_add(arr_adj_json, flags_json); + srv6_endx_sid_json = json_object_new_object(); + json_object_string_addf(srv6_endx_sid_json, + "sid", "%pI6", + &adj->sid); + json_object_string_add(srv6_endx_sid_json, + "algorithm", + sr_algorithm_string( + adj->algorithm)); + json_object_int_add(srv6_endx_sid_json, + "weight", adj->weight); + json_object_string_add(srv6_endx_sid_json, + "behavior", + seg6local_action2str( + adj->behavior)); + json_object_string_add(srv6_endx_sid_json, + "flag-b", + adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG + ? "1" + : "0"); + json_object_string_add(srv6_endx_sid_json, + "flag-s", + adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG + ? "1" + : "0"); + json_object_string_add(srv6_endx_sid_json, + "flag-p", + adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG + ? "1" + : "0"); + json_object_array_add(arr_adj_json, + srv6_endx_sid_json); if (adj->subsubtlvs) isis_format_subsubtlvs(adj->subsubtlvs, - NULL, flags_json, + NULL, + srv6_endx_sid_json, indent + 4); } /* end old deprecated key format */ @@ -1323,33 +1322,38 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, adj; adj = adj->next) { snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", &adj->sid); - flags_json = json_object_new_object(); - json_object_string_addf(flags_json, "sid", - "%pI6", &adj->sid); - json_object_string_add(flags_json, "algorithm", + srv6_endx_sid_json = json_object_new_object(); + json_object_string_addf(srv6_endx_sid_json, + "sid", "%pI6", + &adj->sid); + json_object_string_add(srv6_endx_sid_json, + "algorithm", sr_algorithm_string( adj->algorithm)); - json_object_int_add(flags_json, "weight", - adj->weight); - json_object_string_add(flags_json, "behavior", + json_object_int_add(srv6_endx_sid_json, + "weight", adj->weight); + json_object_string_add(srv6_endx_sid_json, + "behavior", seg6local_action2str( adj->behavior)); json_object_boolean_add( - flags_json, "flagB", + srv6_endx_sid_json, "flagB", !!(adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG)); json_object_boolean_add( - flags_json, "flagS", + srv6_endx_sid_json, "flagS", !!(adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG)); json_object_boolean_add( - flags_json, "flagP", + srv6_endx_sid_json, "flagP", !!(adj->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG)); - json_object_array_add(arr_adj_json, flags_json); + json_object_array_add(arr_adj_json, + srv6_endx_sid_json); if (adj->subsubtlvs) isis_format_subsubtlvs(adj->subsubtlvs, - NULL, flags_json, + NULL, + srv6_endx_sid_json, indent + 4); } } else @@ -1382,7 +1386,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, if (IS_SUBTLV(exts, EXT_SRV6_LAN_ENDX_SID)) { struct isis_srv6_lan_endx_sid_subtlv *lan; if (json) { - struct json_object *arr_adj_json, *flags_json; + struct json_object *arr_adj_json, + *srv6_lan_endx_sid_json; #if CONFDATE > 20240916 CPP_NOTICE("remove deprecated key format with -") @@ -1396,41 +1401,47 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, lan; lan = lan->next) { snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", &lan->sid); - flags_json = json_object_new_object(); - json_object_string_addf(flags_json, "sid", - "%pI6", &lan->sid); - json_object_int_add(flags_json, "weight", - lan->weight); - json_object_string_add( - flags_json, "algorithm", - sr_algorithm_string(lan->algorithm)); - json_object_int_add(flags_json, "weight", - lan->weight); - json_object_string_add( - flags_json, "behavior", - seg6local_action2str(lan->behavior)); - json_object_string_add( - flags_json, "flag-b", - lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-s", - lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG - ? "1" - : "0"); - json_object_string_add( - flags_json, "flag-p", - lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG - ? "1" - : "0"); - json_object_string_addf(flags_json, + srv6_lan_endx_sid_json = + json_object_new_object(); + json_object_string_addf(srv6_lan_endx_sid_json, + "sid", "%pI6", + &lan->sid); + json_object_int_add(srv6_lan_endx_sid_json, + "weight", lan->weight); + json_object_string_add(srv6_lan_endx_sid_json, + "algorithm", + sr_algorithm_string( + lan->algorithm)); + json_object_int_add(srv6_lan_endx_sid_json, + "weight", lan->weight); + json_object_string_add(srv6_lan_endx_sid_json, + "behavior", + seg6local_action2str( + lan->behavior)); + json_object_string_add(srv6_lan_endx_sid_json, + "flag-b", + lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG + ? "1" + : "0"); + json_object_string_add(srv6_lan_endx_sid_json, + "flag-s", + lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG + ? "1" + : "0"); + json_object_string_add(srv6_lan_endx_sid_json, + "flag-p", + lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG + ? "1" + : "0"); + json_object_string_addf(srv6_lan_endx_sid_json, "neighbor-id", "%pSY", lan->neighbor_id); - json_object_array_add(arr_adj_json, flags_json); + json_object_array_add(arr_adj_json, + srv6_lan_endx_sid_json); if (lan->subsubtlvs) isis_format_subsubtlvs(lan->subsubtlvs, - NULL, flags_json, + NULL, + srv6_lan_endx_sid_json, indent + 4); } /* end old deprecated key format */ @@ -1443,38 +1454,44 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, lan; lan = lan->next) { snprintfrr(cnt_buf, sizeof(cnt_buf), "%pI6", &lan->sid); - flags_json = json_object_new_object(); - json_object_string_addf(flags_json, "sid", - "%pI6", &lan->sid); - json_object_int_add(flags_json, "weight", - lan->weight); - json_object_string_add(flags_json, "algorithm", + srv6_lan_endx_sid_json = + json_object_new_object(); + json_object_string_addf(srv6_lan_endx_sid_json, + "sid", "%pI6", + &lan->sid); + json_object_int_add(srv6_lan_endx_sid_json, + "weight", lan->weight); + json_object_string_add(srv6_lan_endx_sid_json, + "algorithm", sr_algorithm_string( lan->algorithm)); - json_object_int_add(flags_json, "weight", - lan->weight); - json_object_string_add(flags_json, "behavior", + json_object_int_add(srv6_lan_endx_sid_json, + "weight", lan->weight); + json_object_string_add(srv6_lan_endx_sid_json, + "behavior", seg6local_action2str( lan->behavior)); json_object_boolean_add( - flags_json, "flagB", + srv6_lan_endx_sid_json, "flagB", !!(lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_BFLG)); json_object_boolean_add( - flags_json, "flagS", + srv6_lan_endx_sid_json, "flagS", !!(lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_SFLG)); json_object_boolean_add( - flags_json, "flagP", + srv6_lan_endx_sid_json, "flagP", !!(lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG)); - json_object_string_addf(flags_json, + json_object_string_addf(srv6_lan_endx_sid_json, "neighbor-id", "%pSY", lan->neighbor_id); - json_object_array_add(arr_adj_json, flags_json); + json_object_array_add(arr_adj_json, + srv6_lan_endx_sid_json); if (lan->subsubtlvs) isis_format_subsubtlvs(lan->subsubtlvs, - NULL, flags_json, + NULL, + srv6_lan_endx_sid_json, indent + 4); } } else From 3e82cf29286407eb1b088c33a5deb4b673574a74 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 21 Jun 2024 11:18:59 +0200 Subject: [PATCH 342/472] isisd: fix neighbor id json key d5879267aa ("isisd: fix show database json format") renamed JSON keys to a standard format but forgot to rename the neighbor-id key. Fixes: d5879267aa ("isisd: fix show database json format") Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 4ea384ef23bf..8405ad089c6d 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -1484,7 +1484,7 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, !!(lan->flags & EXT_SUBTLV_LINK_SRV6_ENDX_SID_PFLG)); json_object_string_addf(srv6_lan_endx_sid_json, - "neighbor-id", "%pSY", + "neighborID", "%pSY", lan->neighbor_id); json_object_array_add(arr_adj_json, srv6_lan_endx_sid_json); From cd2e872e65c0512b2d57a92517622efe21cf306e Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 24 Jun 2024 13:38:37 +0200 Subject: [PATCH 343/472] isisd: fix srv6 endx sid key name srv6EndSID is actually srv6EndXSID. Fixes: d5879267aa ("isisd: fix show database json format") Signed-off-by: Louis Scalbert --- isisd/isis_tlvs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index 8405ad089c6d..c7f45b246948 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -1316,7 +1316,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, /* end old deprecated key format */ arr_adj_json = json_object_new_array(); - json_object_object_add(json, "srv6EndSID", arr_adj_json); + json_object_object_add(json, "srv6EndXSID", + arr_adj_json); for (adj = (struct isis_srv6_endx_sid_subtlv *) exts->srv6_endx_sid.head; adj; adj = adj->next) { From 3b98ddf5018cf7526b50c15018cbaf71a38fa752 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Mon, 24 Jun 2024 20:16:16 +0300 Subject: [PATCH 344/472] bgpd: Relax OAD (One-Administration-Domain) for RFC8212 RFC 8212 defines leak prevention for eBGP peers, but BGP-OAD defines a new peering type One Administrative Domain (OAD), where multiple ASNs could be used inside a single administrative domain. OAD allows sending non-transitive attributes, so this prevention should be relaxed too. Signed-off-by: Donatas Abraitis --- bgpd/bgp_route.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 4dcb22234ac5..9c3602311f77 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6333,7 +6333,7 @@ void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi) bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) { - if (peer->sort == BGP_PEER_IBGP) + if (peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD) return true; if (peer->sort == BGP_PEER_EBGP && @@ -6346,7 +6346,7 @@ bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter) { - if (peer->sort == BGP_PEER_IBGP) + if (peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD) return true; if (peer->sort == BGP_PEER_EBGP From 8044d733009dd428c291460eb8b0e539b53b78fa Mon Sep 17 00:00:00 2001 From: Piotr Suchy Date: Wed, 22 May 2024 10:41:52 +0200 Subject: [PATCH 345/472] bgpd: Ignore routes from evpn if VRF is unknown Fix for a bug, where FRR fails to install route received for an unknown but later-created VRF - detailed description can be found here https://github.com/FRRouting/frr/issues/13708 Signed-off-by: Piotr Suchy --- bgpd/bgp_evpn.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 5d6a5a59f520..6680b54f7665 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3037,6 +3037,9 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, vrf_id_to_name(bgp_vrf->vrf_id), evp, parent_pi, parent_pi->flags); + if (bgp_vrf->vrf_id == VRF_UNKNOWN) + return -1; + /* Create (or fetch) route within the VRF. */ /* NOTE: There is no RD here. */ if (is_evpn_prefix_ipaddr_v4(evp)) { From 8ef75009a77718ceda4bb79f7a43cf7577271afa Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Tue, 25 Jun 2024 13:48:33 -0400 Subject: [PATCH 346/472] doc: improve table-of-contents organization The current TOC organization is not really following Sphinx best practices and is resulting in a jumble of articles showing up in the sidebar. This change primarily organizes existing articles into three major sections: * Introduction - Contains system requirements, architecture & design, installation, basic setup * Basics - Covers basic commands, concepts, and some random things that don't fit elsewhere * Protocols - Contains all protocol documentation, and other miscellaneous daemon docs such as those on Zebra, watchfrr, mgmtd, etc. The appendix has been left as is, but the TOC now has a caption which has the effect of adding a section separator in the nav sidebar. In order to make the new structure make sense: * Some content has been lifted up from the "Overview" page into the index page * Most content has been pushed down from the "Overview" page into the "About" page (new) * BFD's page is now titled "BFD" for consistencty; it was the only one that had the full protocol name written out in the title And a couple drivebys: * BFD's intro description paragraph was rewritten to make more sense * Old language stating that we publish platform packages on the Github releases page was removed * References to source building instructions were consolidated into that section Signed-off-by: Quentin Young --- doc/user/{overview.rst => about.rst} | 57 +++----------------- doc/user/basics.rst | 23 ++++++++ doc/user/bfd.rst | 19 ++++--- doc/user/index.rst | 81 ++++++---------------------- doc/user/installation.rst | 31 ++++++----- doc/user/introduction.rst | 13 +++++ doc/user/protocols.rst | 35 ++++++++++++ doc/user/subdir.am | 2 +- 8 files changed, 125 insertions(+), 136 deletions(-) rename doc/user/{overview.rst => about.rst} (94%) create mode 100644 doc/user/basics.rst create mode 100644 doc/user/introduction.rst create mode 100644 doc/user/protocols.rst diff --git a/doc/user/overview.rst b/doc/user/about.rst similarity index 94% rename from doc/user/overview.rst rename to doc/user/about.rst index 2ef88acd7aaf..7d30a86154a0 100644 --- a/doc/user/overview.rst +++ b/doc/user/about.rst @@ -1,47 +1,8 @@ .. _overview: -******** -Overview -******** - -`FRR`_ is a fully featured, high performance, free software IP routing suite. - -FRR implements all standard routing protocols such as BGP, RIP, OSPF, IS-IS and -more (see :ref:`feature-matrix`), as well as many of their extensions. - -FRR is a high performance suite written primarily in C. It can easily handle -full Internet routing tables and is suitable for use on hardware ranging from -cheap SBCs to commercial grade routers. It is actively used in production by -hundreds of companies, universities, research labs and governments. - -FRR is distributed under GPLv2, with development modeled after the Linux -kernel. Anyone may contribute features, bug fixes, tools, documentation -updates, or anything else. - -FRR is a fork of `Quagga `_. - -.. _how-to-get-frr: - -How to get FRR -============== - -The official FRR website is located at |PACKAGE_URL| and contains further -information, as well as links to additional resources. - -Several distributions provide packages for FRR. Check your distribution's -repositories to find out if a suitable version is available. - -Up-to-date Debian & Redhat packages are available at https://deb.frrouting.org/ -& https://rpm.frrouting.org/ respectively. - -For instructions on installing from source, refer to the -`developer documentation `_. - - -.. _about-frr: - +********* About FRR -========= +********* FRR provides IP routing services. Its role in a networking stack is to exchange routing information with other routers, make routing and policy decisions, and @@ -55,11 +16,8 @@ light L2 functionality as well, but this is mostly left to the platform. This makes it suitable for deployments ranging from small home networks with static routes to Internet exchanges running full Internet tables. -FRR runs on all modern \*NIX operating systems, including Linux and the BSDs. -Feature support varies by platform; see the :ref:`feature-matrix`. - System Requirements -------------------- +=================== System resources needed by FRR are highly dependent on workload. Routing software performance is particularly susceptible to external factors such as: @@ -86,8 +44,8 @@ information with peers about how to forward packets. Forwarding plane performance largely depends on choice of NIC / ASIC. -System Architecture -------------------- +Architecture +============ .. index:: pair: architecture; FRR @@ -146,9 +104,8 @@ routing stack. .. _supported-platforms: -Supported Platforms -------------------- - +Platform Support +================ Currently FRR supports GNU/Linux and BSD. Porting FRR to other platforms is not too difficult as platform dependent code should be mostly limited to the diff --git a/doc/user/basics.rst b/doc/user/basics.rst new file mode 100644 index 000000000000..4504e9893c41 --- /dev/null +++ b/doc/user/basics.rst @@ -0,0 +1,23 @@ +.. _basics: + +###### +Basics +###### + +.. toctree:: + :maxdepth: 2 + + basic + extlog + vtysh + grpc + filter + routemap + affinitymap + ipv6 + kernel + snmp + scripting + nexthop_groups + + diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst index 3ca104a3a93e..b2127e89552a 100644 --- a/doc/user/bfd.rst +++ b/doc/user/bfd.rst @@ -1,12 +1,19 @@ .. _bfd: -********************************** -Bidirectional Forwarding Detection -********************************** +*** +BFD +*** -:abbr:`BFD (Bidirectional Forwarding Detection)` stands for -Bidirectional Forwarding Detection and it is described and extended by -the following RFCs: +:abbr:`BFD (Bidirectional Forwarding Detection)` is: + + a protocol intended to detect faults in the bidirectional path between two + forwarding engines, including interfaces, data link(s), and to the extent + possible the forwarding engines themselves, with potentially very low + latency. + + -- :rfc:`5880` + +It is described and extended by the following RFCs: * :rfc:`5880` * :rfc:`5881` diff --git a/doc/user/index.rst b/doc/user/index.rst index 4789677a9a04..d3b632a8debb 100644 --- a/doc/user/index.rst +++ b/doc/user/index.rst @@ -1,80 +1,31 @@ FRRouting User Guide ==================== -############ -Introduction -############ +FRR is a fully featured, high performance, free software IP routing suite. It +implements all standard routing protocols such as BGP, RIP, OSPF, IS-IS and +more (see :ref:`feature-matrix`), as well as many of their extensions. It can +handle full Internet routing tables and is suitable for use on hardware ranging +from cheap SBCs to commercial grade routers, and is actively used in production +by hundreds of companies, universities, research labs and governments. -.. _introduction: -.. toctree:: - :maxdepth: 2 - - overview - installation - setup - -###### -Basics -###### +FRR runs on all modern \*NIX operating systems, including Linux and the BSDs. +Feature support varies by platform; see the :ref:`feature-matrix`. -.. _basics: -.. toctree:: - :maxdepth: 2 +FRR is distributed under GPLv2, with development modeled after the Linux +kernel. Anyone may contribute features, bug fixes, tools, documentation +updates, or anything else. - basic - extlog - vtysh - grpc - filter - routemap - affinitymap - ipv6 - kernel - snmp - scripting - nexthop_groups -.. modules +FRR is a fork of `Quagga `_. -######### -Protocols -######### - -.. _protocols: .. toctree:: :maxdepth: 2 - zebra - bfd - bgp - babeld - fabricd - ldpd - eigrpd - evpn - isisd - nhrpd - ospfd - ospf6d - pathd - pim - pimv6 - pbr - ripd - ripngd - sharp - static - vnc - vrrp - bmp - watchfrr - mgmtd - -######## -Appendix -######## + introduction + basics + protocols -.. _appendix: .. toctree:: + :caption: Appendix :maxdepth: 2 bugs diff --git a/doc/user/installation.rst b/doc/user/installation.rst index e49f10491e4e..4d2017c0f8e5 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -3,22 +3,25 @@ single: Installing FRR single: Building FRR -.. _installation: - Installation ============ -This section covers the basics of building, installing and setting up FRR. +This section covers the basics of building, installing and setting up +FRR. +The official FRR website is located at |PACKAGE_URL| and contains further +information, as well as links to additional resources. From Packages ------------- -The project publishes packages for Red Hat, Centos, Debian and Ubuntu on the -`GitHub releases `_. page. External -contributors offer packages for many other platforms including \*BSD, Alpine, -Gentoo, Docker, and others. There is currently no documentation on how to use -those but we hope to add it soon. +Up-to-date Debian & Redhat packages are available at +https://deb.frrouting.org/ & https://rpm.frrouting.org/ respectively. + +Several distributions also provide packages for FRR. Check your +distribution's repositories to find out if a suitable version is +available. + From Snapcraft -------------- @@ -29,12 +32,12 @@ universal Snap images, available at https://snapcraft.io/frr. From Source ----------- -Building FRR from source is the best way to ensure you have the latest features -and bug fixes. Details for each supported platform, including dependency -package listings, permissions, and other gotchas, are in the `developer's -documentation -`_. This -section provides a brief overview on the process. +Building FRR from source is the best way to ensure you have the latest +features and bug fixes. Details for each supported platform, including +dependency package listings, permissions, and other gotchas, are in the +`developer's documentation +`_. +This section provides a brief overview on the process. Getting the Source diff --git a/doc/user/introduction.rst b/doc/user/introduction.rst new file mode 100644 index 000000000000..89866b9c2921 --- /dev/null +++ b/doc/user/introduction.rst @@ -0,0 +1,13 @@ +.. _introduction: + +############ +Introduction +############ + +.. toctree:: + :maxdepth: 2 + + about + installation + setup + diff --git a/doc/user/protocols.rst b/doc/user/protocols.rst new file mode 100644 index 000000000000..e571cd66fc84 --- /dev/null +++ b/doc/user/protocols.rst @@ -0,0 +1,35 @@ +.. _protocols: + +######### +Protocols +######### + +.. toctree:: + :maxdepth: 2 + + zebra + bfd + bgp + babeld + fabricd + ldpd + eigrpd + evpn + isisd + nhrpd + ospfd + ospf6d + pathd + pim + pimv6 + pbr + ripd + ripngd + sharp + static + vnc + vrrp + bmp + watchfrr + mgmtd + diff --git a/doc/user/subdir.am b/doc/user/subdir.am index 4879f7f7ef3c..395ce305fe94 100644 --- a/doc/user/subdir.am +++ b/doc/user/subdir.am @@ -29,7 +29,7 @@ user_RSTFILES = \ doc/user/ospf6d.rst \ doc/user/ospfd.rst \ doc/user/ospf_fundamentals.rst \ - doc/user/overview.rst \ + doc/user/about.rst \ doc/user/packet-dumps.rst \ doc/user/pathd.rst \ doc/user/pim.rst \ From e0ae285eb8beeef7b43bdadc073d8ae346eaeb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sang?= Date: Wed, 19 Jun 2024 16:19:22 +0200 Subject: [PATCH 347/472] bgpd: avoid clearing routes for peers that were never established MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under heavy system load with many peers in passive mode and a large number of routes, bgpd can enter an infinite loop. This occurs while processing timeout BGP_OPEN messages, which prevents it from accepting new connections. The following log entries illustrate the issue: >bgpd[6151]: [VX6SM-8YE5W][EC 33554460] 3.3.2.224: nexthop_set failed, resetting connection - intf 0x0 >bgpd[6151]: [P790V-THJKS][EC 100663299] bgp_open_receive: bgp_getsockname() failed for peer: 3.3.2.224 >bgpd[6151]: [HTQD2-0R1WR][EC 33554451] bgp_process_packet: BGP OPEN receipt failed for peer: 3.3.2.224 ... repeating The issue occurs when bgpd handles a massive number of routes in the RIB while receiving numerous BGP_OPEN packets. If bgpd is overloaded, it fails to process these packets promptly, leading the remote peer to close the connection and resend BGP_OPEN packets. When bgpd eventually starts processing these timeout BGP_OPEN packets, it finds the TCP connection closed by the remote peer, resulting in "bgp_stop()" being called. For each timeout peer, bgpd must iterate through the routing table, which is time-consuming and causes new incoming BGP_OPEN packets to timeout, perpetuating the infinite loop. To address this issue, the code is modified to check if the peer has been established at least once before calling "bgp_clear_route_all()". This ensures that routes are only cleared for peers that had a successful session, preventing unnecessary iterations over the routing table for peers that never established a connection. With this change, BGP_OPEN timeout messages may still occur, but in the worst case, bgpd will stabilize. Before this patch, bgpd could enter a loop where it was unable to accpet any new connections. Signed-off-by: Loïc Sang --- bgpd/bgp_fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 15cc5dbe2ea0..d41ef8abbac9 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1241,7 +1241,7 @@ void bgp_fsm_change_status(struct peer_connection *connection, /* Transition into Clearing or Deleted must /always/ clear all routes.. * (and must do so before actually changing into Deleted.. */ - if (status >= Clearing) { + if (status >= Clearing && (peer->established || peer == bgp->peer_self)) { bgp_clear_route_all(peer); /* If no route was queued for the clear-node processing, From 163a3f582f671b1ac4a0c21cb97da341c756ed2e Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 25 Jun 2024 14:37:27 +0200 Subject: [PATCH 348/472] pimd: fix misplaced braces/logic error The `!rp_info ||` check got added during a cleanup pass. Unfortunately the braces/and/or combination is not correct :( Fixes: b1945363fbf ("pimd: Various buffer overflow reads and crashes") Signed-off-by: David Lamparter --- pimd/pim_rp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index b0fb8a509af2..4703ff8a6a0a 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -1115,8 +1115,8 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up, rp_info = pim_rp_find_match_group(pim, &g); - if (!rp_info || ((pim_rpf_addr_is_inaddr_any(&rp_info->rp)) && - (pim_addr_is_any(source)))) { + if ((!rp_info || (pim_rpf_addr_is_inaddr_any(&rp_info->rp))) && + (pim_addr_is_any(source))) { if (PIM_DEBUG_PIM_NHT_RP) zlog_debug("%s: Received a (*,G) with no RP configured", __func__); From 759e93302d8f3120ff101f047c30100430728617 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 26 Jun 2024 16:13:50 +0200 Subject: [PATCH 349/472] pimd: refactor `pim_rp_set_upstream_addr` Somehow this tiny function ended up being written in a very convoluted way that enabled the braces mixup in the previous commit. Rewrite it to be less confusing. Signed-off-by: David Lamparter --- pimd/pim_rp.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 4703ff8a6a0a..49be9c0a7339 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -1107,16 +1107,17 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up, pim_addr source, pim_addr group) { struct rp_info *rp_info; - struct prefix g; + struct prefix g = {}; - memset(&g, 0, sizeof(g)); + if (!pim_addr_is_any(source)) { + *up = source; + return 1; + } pim_addr_to_prefix(&g, group); - rp_info = pim_rp_find_match_group(pim, &g); - if ((!rp_info || (pim_rpf_addr_is_inaddr_any(&rp_info->rp))) && - (pim_addr_is_any(source))) { + if (!rp_info || pim_rpf_addr_is_inaddr_any(&rp_info->rp)) { if (PIM_DEBUG_PIM_NHT_RP) zlog_debug("%s: Received a (*,G) with no RP configured", __func__); @@ -1124,11 +1125,7 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up, return 0; } - if (pim_addr_is_any(source)) - *up = rp_info->rp.rpf_addr; - else - *up = source; - + *up = rp_info->rp.rpf_addr; return 1; } From 10231d5b99065b7567b04756ecfda8f5cbb19f47 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 26 Jun 2024 15:44:08 -0400 Subject: [PATCH 350/472] doc: reformat Sphinx conf.py files Style checking is complaining about these, rightly so. Reformat. Signed-off-by: Quentin Young --- doc/developer/conf.py | 33 ++++++++++++++++++--------------- doc/user/conf.py | 22 ++++++++++++---------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 495c604ae091..6a3ffe16380e 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -18,6 +18,7 @@ import pygments from sphinx.highlighting import lexers from sphinx.util import logging + logger = logging.getLogger(__name__) # If extensions (or modules to document with autodoc) are in another directory, @@ -53,18 +54,18 @@ master_doc = "index" # General information about the project. -project = u"FRR" -copyright = u"2017, FRR" -author = u"FRR authors" +project = "FRR" +copyright = "2017, FRR" +author = "FRR authors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # The short X.Y version. -version = u"?.?" +version = "?.?" # The full version, including alpha/beta/rc tags. -release = u"?.?-?" +release = "?.?-?" # ----------------------------------------------------------------------------- @@ -287,7 +288,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, "FRR.tex", u"FRR Developer's Manual", u"FRR", "manual"), + (master_doc, "FRR.tex", "FRR Developer's Manual", "FRR", "manual"), ] # The name of an image file (relative to this directory) to place at the top of @@ -315,7 +316,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [(master_doc, "frr", u"FRR Developer's Manual", [author], 1)] +man_pages = [(master_doc, "frr", "FRR Developer's Manual", [author], 1)] # If true, show URL addresses after external links. # man_show_urls = False @@ -330,7 +331,7 @@ ( master_doc, "frr", - u"FRR Developer's Manual", + "FRR Developer's Manual", author, "FRR", "One line description of project.", @@ -358,27 +359,29 @@ with open("../extra/frrlexer.py", "rb") as lex: frrlexerpy = lex.read() -frrfmt_re = re.compile(r'^\s*%(?P[^\s]+)\s+\((?P.*)\)\s*$') +frrfmt_re = re.compile(r"^\s*%(?P[^\s]+)\s+\((?P.*)\)\s*$") + def parse_frrfmt(env, text, node): from sphinx import addnodes m = frrfmt_re.match(text) if not m: - logger.warning('could not parse frrfmt:: %r' % (text), location=node) + logger.warning("could not parse frrfmt:: %r" % (text), location=node) node += addnodes.desc_name(text, text) return text - spec, types = m.group('spec'), m.group('types') + spec, types = m.group("spec"), m.group("types") - node += addnodes.desc_sig_operator('%', '%') - node += addnodes.desc_name(spec + ' ', spec + ' ') + node += addnodes.desc_sig_operator("%", "%") + node += addnodes.desc_name(spec + " ", spec + " ") plist = addnodes.desc_parameterlist() - for typ in types.split(','): + for typ in types.split(","): typ = typ.strip() plist += addnodes.desc_parameter(typ, typ) node += plist - return '%' + spec + return "%" + spec + # custom extensions here def setup(app): diff --git a/doc/user/conf.py b/doc/user/conf.py index 728f9c936486..629a97272601 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -52,18 +52,18 @@ master_doc = "index" # General information about the project. -project = u"FRR" -copyright = u"2017, FRR" -author = u"FRR authors" +project = "FRR" +copyright = "2017, FRR" +author = "FRR authors" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # The short X.Y version. -version = u"?.?" +version = "?.?" # The full version, including alpha/beta/rc tags. -release = u"?.?-?" +release = "?.?-?" # ----------------------------------------------------------------------------- @@ -287,7 +287,7 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, "FRR.tex", u"FRR User Manual", u"FRR", "manual"), + (master_doc, "FRR.tex", "FRR User Manual", "FRR", "manual"), ] # The name of an image file (relative to this directory) to place at the top of @@ -315,7 +315,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [(master_doc, "frr", u"FRR User Manual", [author], 1)] +man_pages = [(master_doc, "frr", "FRR User Manual", [author], 1)] # If true, show URL addresses after external links. # man_show_urls = False @@ -330,7 +330,7 @@ ( master_doc, "frr", - u"FRR User Manual", + "FRR User Manual", author, "FRR", "One line description of project.", @@ -358,6 +358,7 @@ with open("../extra/frrlexer.py", "rb") as lex: frrlexerpy = lex.read() + # Parse version string into int array def vparse(s): a = [] @@ -376,7 +377,9 @@ def vparse(s): def setup(app): # object type for FRR CLI commands, can be extended to document parent CLI # node later on - app.add_object_type("clicmd", "clicmd", indextemplate="pair: %s; configuration command") + app.add_object_type( + "clicmd", "clicmd", indextemplate="pair: %s; configuration command" + ) # I dont care how stupid this is if "add_js_file" in dir(app): @@ -389,7 +392,6 @@ def setup(app): else: app.add_stylesheet("overrides.css") - # load Pygments lexer for FRR config syntax # # NB: in Pygments 2.2+ this can be done with `load_lexer_from_file`, but we From a970bb51b5fe32335c783860a03bb02ce74a49aa Mon Sep 17 00:00:00 2001 From: zhou-run Date: Thu, 27 Jun 2024 11:51:02 +0800 Subject: [PATCH 351/472] isisd: fix crash when obtaining the next hop to calculate LFA on LAN links When a neighbor connection is disconnected, it may trigger LSP re-generation as a timer task, but this process may be delayed. As a result, the list of neighbors in area->adjacency_list may be inconsistent with the neighbors in lsp->tlvs->oldstyle_reach/extended_reach. For example, the area->adjacency_list may lack certain neighbors even though they are present in the LSP. When computing SPF, the call to isis_spf_build_adj_list() generates the spftree->sadj_list, which reflects the real neighbors in the area->adjacency_list. However, in the case of LAN links, spftree->sadj_list may include additional pseudo neighbors. The pre-loading of tents through the call to isis_spf_preload_tent involves two steps: 1. isis_spf_process_lsp() is called to generate real neighbor vertices based on the root LSP and pseudo LSP. 2. isis_spf_add_local() is called to add corresponding next hops to the vertex->Adj_N list for the real neighbor vertices. In the case of LAN links, the absence of corresponding real neighbors in the spftree->sadj_list prevents the execution of the second step. Consequently, the vertex->Adj_N list for the real neighbor vertices lacks corresponding next hops. This leads to a null pointer access when isis_lfa_compute() is called to calculate LFA. As for P2P links, since there are no pseudo neighbors, only the second step is executed, which does not create real neighbor vertices and therefore does not encounter this issue. The backtrace is as follows: (gdb) bt #0 0x00007fd065277fe1 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0 #1 0x00007fd065398972 in core_handler (signo=11, siginfo=0x7ffc5c0636b0, context=0x7ffc5c063580) at ../lib/sigevent.c:261 #2 #3 0x00005564d82f8408 in isis_lfa_compute (area=0x5564d8b143f0, circuit=0x5564d8b21d10, spftree=0x5564d8b06bf0, resource=0x7ffc5c064410) at ../isisd/isis_lfa.c:2134 #4 0x00005564d82f8d78 in isis_spf_run_lfa (area=0x5564d8b143f0, spftree=0x5564d8b06bf0) at ../isisd/isis_lfa.c:2344 #5 0x00005564d8315964 in isis_run_spf_with_protection (area=0x5564d8b143f0, spftree=0x5564d8b06bf0) at ../isisd/isis_spf.c:1827 #6 0x00005564d8315c15 in isis_run_spf_cb (thread=0x7ffc5c064590) at ../isisd/isis_spf.c:1889 #7 0x00007fd0653b1f04 in thread_call (thread=0x7ffc5c064590) at ../lib/thread.c:1990 #8 0x00007fd06534a97b in frr_run (master=0x5564d88103c0) at ../lib/libfrr.c:1198 #9 0x00005564d82e7d5d in main (argc=5, argv=0x7ffc5c0647b8, envp=0x7ffc5c0647e8) at ../isisd/isis_main.c:273 (gdb) f 3 #3 0x00005564d82f8408 in isis_lfa_compute (area=0x5564d8b143f0, circuit=0x5564d8b21d10, spftree=0x5564d8b06bf0, resource=0x7ffc5c064410) at ../isisd/isis_lfa.c:2134 2134 ../isisd/isis_lfa.c: No such file or directory. (gdb) p vadj_primary $1 = (struct isis_vertex_adj *) 0x0 (gdb) p vertex->Adj_N->head $2 = (struct listnode *) 0x0 (gdb) p (struct isis_vertex *)spftree->paths->l.list->head->next->next->next->next->data $8 = (struct isis_vertex *) 0x5564d8b5b240 (gdb) p $8->type $9 = VTYPE_NONPSEUDO_TE_IS (gdb) p $8->N.id $10 = "\000\000\000\000\000\002" (gdb) p $8->Adj_N->count $11 = 0 (gdb) p (struct isis_vertex *)spftree->paths->l.list->head->next->next->next->next->next->data $12 = (struct isis_vertex *) 0x5564d8b73dd0 (gdb) p $12->type $13 = VTYPE_NONPSEUDO_TE_IS (gdb) p $12->N.id $14 = "\000\000\000\000\000\003" (gdb) p $12->Adj_N->count $15 = 0 (gdb) p area->adjacency_list->count $16 = 0 The backtrace provided above pertains to version 8.5.4, but it seems that the same issue exists in the code of the master branch as well. The scenario where a vertex has no next hop is normal. For example, the "clear isis neighbor" command invokes isis_vertex_adj_del() to delete the next hop of a vertex. Upon reviewing all the instances where the vertex->Adj_N list is used, I found that only isis_lfa_compute() lacks a null check. Therefore, I believe that modifying this part will be sufficient. Additionally, the vertex->parents list for IP vertices is guaranteed not to be empty. Test scenario: Setting up LFA for LAN links and executing the "clear isis neighbor" command easily reproduces the issue. Signed-off-by: zhou-run --- isisd/isis_lfa.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c index 4eb57aefb0a0..dc8f0b96c028 100644 --- a/isisd/isis_lfa.c +++ b/isisd/isis_lfa.c @@ -2126,9 +2126,16 @@ void isis_lfa_compute(struct isis_area *area, struct isis_circuit *circuit, } vadj_primary = listnode_head(vertex->Adj_N); + if (!vadj_primary) { + if (IS_DEBUG_LFA) + zlog_debug( + "ISIS-LFA: skipping computing LFAs due to no adjacencies"); + continue; + } sadj_primary = vadj_primary->sadj; parent_vertex = listnode_head(vertex->parents); + assert(parent_vertex); prefix_metric = vertex->d_N - parent_vertex->d_N; /* From 1a64fe4254759245a67fb279d67478922e00255e Mon Sep 17 00:00:00 2001 From: T-Nicolas Date: Mon, 17 Jun 2024 15:05:58 +0200 Subject: [PATCH 352/472] ripd: Change the start value of sequence 1 to 0 Signed-off-by: T-Nicolas --- ripd/ripd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ripd/ripd.c b/ripd/ripd.c index b8a140c9ca5a..ab4ffe5a921d 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1051,7 +1051,7 @@ static size_t rip_auth_md5_ah_write(struct stream *s, struct rip_interface *ri, /* RFC2080: The value used in the sequence number is arbitrary, but two suggestions are the time of the message's creation or a simple message counter. */ - stream_putl(s, ++seq); + stream_putl(s, seq++); /* Reserved field must be zero. */ stream_putl(s, 0); From 4e276b93def930f3cdf475360f57a3531a9ff2c5 Mon Sep 17 00:00:00 2001 From: vivek Date: Sat, 24 Oct 2020 14:38:58 -0700 Subject: [PATCH 353/472] bgpd: Implement BGP-wide configuration for graceful restart Add support for a BGP-wide setting for graceful restart modes and parameters. This setting will apply to all BGP peers across all BGP instances, but per-neighbor configuration can override it. Per-instance configuration is disallowed if the BGP-wide setting is in effect. Signed-off-by: Vivek Venkatraman --- bgpd/bgp_vty.c | 371 ++++++++++++++++++++++++++++++++++++++++--------- bgpd/bgpd.c | 28 +++- bgpd/bgpd.h | 12 ++ 3 files changed, 343 insertions(+), 68 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 230fedf4ece8..ba392e39e6da 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3019,6 +3019,98 @@ DEFUN (no_bgp_deterministic_med, return CMD_SUCCESS; } +static int bgp_inst_gr_config_vty(struct vty *vty, struct bgp *bgp, bool on, + bool disable) +{ + int ret = BGP_GR_FAILURE; + + /* + * Update the instance and all its peers, if appropriate. + * Then, inform zebra of BGP's GR capabilities, if needed. + */ + if (disable) + ret = bgp_gr_update_all(bgp, on ? GLOBAL_DISABLE_CMD + : NO_GLOBAL_DISABLE_CMD); + else + ret = bgp_gr_update_all(bgp, + on ? GLOBAL_GR_CMD : NO_GLOBAL_GR_CMD); + + VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer, + ret); + return ret; +} + +static int bgp_global_gr_config_vty(struct vty *vty, bool on, bool disable) +{ + struct listnode *node, *nnode; + struct bgp *bgp; + bool vrf_cfg = false; + int ret = BGP_GR_FAILURE; + + if (disable) { + if ((on && CHECK_FLAG(bm->flags, BM_FLAG_GR_DISABLED)) || + (!on && !CHECK_FLAG(bm->flags, BM_FLAG_GR_DISABLED))) + return CMD_SUCCESS; + } else { + if ((on && CHECK_FLAG(bm->flags, BM_FLAG_GR_RESTARTER)) || + (!on && !CHECK_FLAG(bm->flags, BM_FLAG_GR_RESTARTER))) + return CMD_SUCCESS; + } + + /* See if GR is set per-vrf and warn user to delete */ + if (!CHECK_FLAG(bm->flags, BM_FLAG_GR_CONFIGURED)) { + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + enum global_mode gr_mode = bgp_global_gr_mode_get(bgp); + + if (gr_mode != GLOBAL_HELPER) { + vty_out(vty, + "%% graceful-restart configuration found in %s, mode %d\n", + bgp->name_pretty, gr_mode); + vrf_cfg = true; + } + } + } + + if (vrf_cfg) { + vty_out(vty, + "%%Failed: global graceful-restart not permitted with per-vrf configuration\n"); + return CMD_WARNING; + } + + /* Set flag globally */ + if (on) { + if (disable) { + UNSET_FLAG(bm->flags, BM_FLAG_GR_RESTARTER); + SET_FLAG(bm->flags, BM_FLAG_GR_DISABLED); + } else { + SET_FLAG(bm->flags, BM_FLAG_GR_RESTARTER); + UNSET_FLAG(bm->flags, BM_FLAG_GR_DISABLED); + } + } else { + if (disable) + UNSET_FLAG(bm->flags, BM_FLAG_GR_DISABLED); + else + UNSET_FLAG(bm->flags, BM_FLAG_GR_RESTARTER); + } + + /* Initiate processing for all BGP instances. */ + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + ret = bgp_inst_gr_config_vty(vty, bgp, on, disable); + if (ret != BGP_GR_SUCCESS) + vty_out(vty, + "%% Applying global graceful-restart %s config to vrf %s failed, error %d\n", + (disable) ? "disable" : "", + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT + ? "Default" + : bgp->name, + ret); + } + + vty_out(vty, + "Graceful restart configuration changed, reset all peers to take effect\n"); + return bgp_vty_return(vty, ret); +} + /* "bgp graceful-restart mode" configuration. */ DEFUN (bgp_graceful_restart, bgp_graceful_restart_cmd, @@ -3027,6 +3119,9 @@ DEFUN (bgp_graceful_restart, GR_CMD ) { + if (vty->node == CONFIG_NODE) + return bgp_global_gr_config_vty(vty, true, false); + int ret = BGP_GR_FAILURE; if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) @@ -3034,11 +3129,8 @@ DEFUN (bgp_graceful_restart, VTY_DECLVAR_CONTEXT(bgp, bgp); - ret = bgp_gr_update_all(bgp, GLOBAL_GR_CMD); + ret = bgp_inst_gr_config_vty(vty, bgp, true, false); if (ret == BGP_GR_SUCCESS) { - VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, - bgp->peer, - ret); vty_out(vty, "Graceful restart configuration changed, reset all peers to take effect\n"); } @@ -3057,6 +3149,9 @@ DEFUN (no_bgp_graceful_restart, NO_GR_CMD ) { + if (vty->node == CONFIG_NODE) + return bgp_global_gr_config_vty(vty, false, false); + VTY_DECLVAR_CONTEXT(bgp, bgp); if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) @@ -3064,7 +3159,7 @@ DEFUN (no_bgp_graceful_restart, int ret = BGP_GR_FAILURE; - ret = bgp_gr_update_all(bgp, NO_GLOBAL_GR_CMD); + ret = bgp_inst_gr_config_vty(vty, bgp, false, false); if (ret == BGP_GR_SUCCESS) { VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer, @@ -3087,12 +3182,21 @@ DEFUN (bgp_graceful_restart_stalepath_time, "Set the max time to hold onto restarting peer's stale paths\n" "Delay value (seconds)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; uint32_t stalepath; stalepath = strtoul(argv[idx_number]->arg, NULL, 10); - bgp->stalepath_time = stalepath; + if (vty->node == CONFIG_NODE) { + struct listnode *node, *nnode; + struct bgp *bgp; + + bm->stalepath_time = stalepath; + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) + bgp->stalepath_time = stalepath; + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->stalepath_time = stalepath; + } return CMD_SUCCESS; } @@ -3104,20 +3208,32 @@ DEFUN (bgp_graceful_restart_restart_time, "Set the time to wait to delete stale routes before a BGP open message is received\n" "Delay value (seconds)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; uint32_t restart; struct listnode *node, *nnode; struct peer *peer; restart = strtoul(argv[idx_number]->arg, NULL, 10); - bgp->restart_time = restart; - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) - bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, - CAPABILITY_CODE_RESTART, - CAPABILITY_ACTION_SET); + if (vty->node == CONFIG_NODE) { + struct bgp *bgp; + bm->restart_time = restart; + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + bgp->restart_time = restart; + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_SET); + } + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->restart_time = restart; + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_SET); + } return CMD_SUCCESS; } @@ -3129,16 +3245,32 @@ DEFUN (bgp_graceful_restart_select_defer_time, "Set the time to defer the BGP route selection after restart\n" "Delay value (seconds, 0 - disable)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; uint32_t defer_time; defer_time = strtoul(argv[idx_number]->arg, NULL, 10); - bgp->select_defer_time = defer_time; - if (defer_time == 0) - SET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE); - else - UNSET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE); + if (vty->node == CONFIG_NODE) { + struct listnode *node, *nnode; + struct bgp *bgp; + + bm->select_defer_time = defer_time; + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + bgp->select_defer_time = defer_time; + if (defer_time == 0) + SET_FLAG(bgp->flags, + BGP_FLAG_SELECT_DEFER_DISABLE); + else + UNSET_FLAG(bgp->flags, + BGP_FLAG_SELECT_DEFER_DISABLE); + } + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->select_defer_time = defer_time; + if (defer_time == 0) + SET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE); + else + UNSET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE); + } return CMD_SUCCESS; } @@ -3152,9 +3284,17 @@ DEFUN (no_bgp_graceful_restart_stalepath_time, "Set the max time to hold onto restarting peer's stale paths\n" "Delay value (seconds)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + if (vty->node == CONFIG_NODE) { + struct listnode *node, *nnode; + struct bgp *bgp; - bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; + bm->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) + bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; + } return CMD_SUCCESS; } @@ -3167,17 +3307,30 @@ DEFUN (no_bgp_graceful_restart_restart_time, "Set the time to wait to delete stale routes before a BGP open message is received\n" "Delay value (seconds)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); struct listnode *node, *nnode; struct peer *peer; - bgp->restart_time = BGP_DEFAULT_RESTART_TIME; + if (vty->node == CONFIG_NODE) { + struct bgp *bgp; - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) - bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, - CAPABILITY_CODE_RESTART, - CAPABILITY_ACTION_UNSET); + bm->restart_time = BGP_DEFAULT_RESTART_TIME; + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + bgp->restart_time = BGP_DEFAULT_RESTART_TIME; + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_UNSET); + } + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->restart_time = BGP_DEFAULT_RESTART_TIME; + + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) + bgp_capability_send(peer, AFI_IP, SAFI_UNICAST, + CAPABILITY_CODE_RESTART, + CAPABILITY_ACTION_UNSET); + } return CMD_SUCCESS; } @@ -3190,10 +3343,21 @@ DEFUN (no_bgp_graceful_restart_select_defer_time, "Set the time to defer the BGP route selection after restart\n" "Delay value (seconds)\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); + if (vty->node == CONFIG_NODE) { + struct listnode *node, *nnode; + struct bgp *bgp; - bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME; - UNSET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE); + bm->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME; + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + bgp->select_defer_time = + BGP_DEFAULT_SELECT_DEFERRAL_TIME; + UNSET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE); + } + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + bgp->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME; + UNSET_FLAG(bgp->flags, BGP_FLAG_SELECT_DEFER_DISABLE); + } return CMD_SUCCESS; } @@ -3205,8 +3369,17 @@ DEFUN (bgp_graceful_restart_preserve_fw, "Graceful restart capability parameters\n" "Sets F-bit indication that fib is preserved while doing Graceful Restart\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - SET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD); + if (vty->node == CONFIG_NODE) { + struct listnode *node, *nnode; + struct bgp *bgp; + + SET_FLAG(bm->flags, BM_FLAG_GR_PRESERVE_FWD); + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) + SET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD); + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + SET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD); + } return CMD_SUCCESS; } @@ -3218,8 +3391,17 @@ DEFUN (no_bgp_graceful_restart_preserve_fw, "Graceful restart capability parameters\n" "Unsets F-bit indication that fib is preserved while doing Graceful Restart\n") { - VTY_DECLVAR_CONTEXT(bgp, bgp); - UNSET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD); + if (vty->node == CONFIG_NODE) { + struct listnode *node, *nnode; + struct bgp *bgp; + + UNSET_FLAG(bm->flags, BM_FLAG_GR_PRESERVE_FWD); + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) + UNSET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD); + } else { + VTY_DECLVAR_CONTEXT(bgp, bgp); + UNSET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD); + } return CMD_SUCCESS; } @@ -3271,6 +3453,9 @@ DEFUN (bgp_graceful_restart_disable, BGP_STR GR_DISABLE) { + if (vty->node == CONFIG_NODE) + return bgp_global_gr_config_vty(vty, true, true); + int ret = BGP_GR_FAILURE; struct listnode *node, *nnode; struct peer *peer; @@ -3281,11 +3466,8 @@ DEFUN (bgp_graceful_restart_disable, VTY_DECLVAR_CONTEXT(bgp, bgp); - ret = bgp_gr_update_all(bgp, GLOBAL_DISABLE_CMD); + ret = bgp_inst_gr_config_vty(vty, bgp, true, true); if (ret == BGP_GR_SUCCESS) { - VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, - bgp->peer, - ret); vty_out(vty, "Graceful restart configuration changed, reset all peers to take effect\n"); @@ -3313,6 +3495,9 @@ DEFUN (no_bgp_graceful_restart_disable, NO_GR_DISABLE ) { + if (vty->node == CONFIG_NODE) + return bgp_global_gr_config_vty(vty, false, true); + VTY_DECLVAR_CONTEXT(bgp, bgp); if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) @@ -3321,11 +3506,8 @@ DEFUN (no_bgp_graceful_restart_disable, int ret = BGP_GR_FAILURE; - ret = bgp_gr_update_all(bgp, NO_GLOBAL_DISABLE_CMD); + ret = bgp_inst_gr_config_vty(vty, bgp, false, true); if (ret == BGP_GR_SUCCESS) { - VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, - bgp->peer, - ret); vty_out(vty, "Graceful restart configuration changed, reset all peers to take effect\n"); } @@ -19166,6 +19348,7 @@ int bgp_config_write(struct vty *vty) hook_call(bgp_snmp_traps_config_write, vty); + vty_out(vty, "!\n"); if (bm->rmap_update_timer != RMAP_DEFAULT_UPDATE_TIMER) vty_out(vty, "bgp route-map delay-timer %u\n", bm->rmap_update_timer); @@ -19180,6 +19363,30 @@ int bgp_config_write(struct vty *vty) if (bm->wait_for_fib) vty_out(vty, "bgp suppress-fib-pending\n"); + if (bm->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) + vty_out(vty, "bgp graceful-restart stalepath-time %u\n", + bm->stalepath_time); + + if (bm->restart_time != BGP_DEFAULT_RESTART_TIME) + vty_out(vty, "bgp graceful-restart restart-time %u\n", + bm->restart_time); + + if (bm->select_defer_time != BGP_DEFAULT_SELECT_DEFERRAL_TIME) + vty_out(vty, "bgp graceful-restart select-defer-time %u\n", + bm->select_defer_time); + + if (CHECK_FLAG(bm->flags, BM_FLAG_GR_RESTARTER)) + vty_out(vty, "bgp graceful-restart\n"); + else if (CHECK_FLAG(bm->flags, BM_FLAG_GR_DISABLED)) + vty_out(vty, "bgp graceful-restart-disable\n"); + + if (CHECK_FLAG(bm->flags, BM_FLAG_GR_PRESERVE_FWD)) + vty_out(vty, "bgp graceful-restart preserve-fw-state\n"); + + if (bm->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME) + vty_out(vty, "bgp graceful-restart rib-stale-time %u\n", + bm->rib_stale_time); + if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) vty_out(vty, "bgp graceful-shutdown\n"); @@ -19442,15 +19649,21 @@ int bgp_config_write(struct vty *vty) " bgp long-lived-graceful-restart stale-time %u\n", bgp->llgr_stale_time); - /* BGP graceful-restart. */ - if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) - vty_out(vty, - " bgp graceful-restart stalepath-time %u\n", - bgp->stalepath_time); + /* BGP per-instance graceful-restart. */ + /* BGP-wide settings and per-instance settings are mutually + * exclusive. + */ + if (bm->stalepath_time == BGP_DEFAULT_STALEPATH_TIME) + if (bgp->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) + vty_out(vty, + " bgp graceful-restart stalepath-time %u\n", + bgp->stalepath_time); - if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME) - vty_out(vty, " bgp graceful-restart restart-time %u\n", - bgp->restart_time); + if (bm->restart_time == BGP_DEFAULT_RESTART_TIME) + if (bgp->restart_time != BGP_DEFAULT_RESTART_TIME) + vty_out(vty, + " bgp graceful-restart restart-time %u\n", + bgp->restart_time); if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION) != SAVE_BGP_GRACEFUL_NOTIFICATION) @@ -19460,30 +19673,34 @@ int bgp_config_write(struct vty *vty) ? "" : "no "); - if (bgp->select_defer_time != BGP_DEFAULT_SELECT_DEFERRAL_TIME) - vty_out(vty, - " bgp graceful-restart select-defer-time %u\n", - bgp->select_defer_time); + if (bm->select_defer_time == BGP_DEFAULT_SELECT_DEFERRAL_TIME) + if (bgp->select_defer_time != + BGP_DEFAULT_SELECT_DEFERRAL_TIME) + vty_out(vty, + " bgp graceful-restart select-defer-time %u\n", + bgp->select_defer_time); - if (bgp_global_gr_mode_get(bgp) == GLOBAL_GR) - vty_out(vty, " bgp graceful-restart\n"); + if (!CHECK_FLAG(bm->flags, BM_FLAG_GR_CONFIGURED)) { + if (bgp_global_gr_mode_get(bgp) == GLOBAL_GR) + vty_out(vty, " bgp graceful-restart\n"); - if (bgp_global_gr_mode_get(bgp) == GLOBAL_DISABLE) - vty_out(vty, " bgp graceful-restart-disable\n"); + if (bgp_global_gr_mode_get(bgp) == GLOBAL_DISABLE) + vty_out(vty, " bgp graceful-restart-disable\n"); + } - /* BGP graceful-restart Preserve State F bit. */ - if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)) - vty_out(vty, - " bgp graceful-restart preserve-fw-state\n"); + if (!CHECK_FLAG(bm->flags, BM_FLAG_GR_PRESERVE_FWD)) + if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)) + vty_out(vty, + " bgp graceful-restart preserve-fw-state\n"); /* BGP TCP keepalive */ bgp_config_tcp_keepalive(vty, bgp); - /* Stale timer for RIB */ - if (bgp->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME) - vty_out(vty, - " bgp graceful-restart rib-stale-time %u\n", - bgp->rib_stale_time); + if (bm->rib_stale_time == BGP_DEFAULT_RIB_STALE_TIME) + if (bgp->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME) + vty_out(vty, + " bgp graceful-restart rib-stale-time %u\n", + bgp->rib_stale_time); /* BGP bestpath method. */ if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) @@ -20142,6 +20359,26 @@ void bgp_vty_init(void) install_element(CONFIG_NODE, &bgp_graceful_shutdown_cmd); install_element(CONFIG_NODE, &no_bgp_graceful_shutdown_cmd); + /* BGP-wide graceful-restart commands. */ + install_element(CONFIG_NODE, &bgp_graceful_restart_cmd); + install_element(CONFIG_NODE, &no_bgp_graceful_restart_cmd); + install_element(CONFIG_NODE, &bgp_graceful_restart_disable_cmd); + install_element(CONFIG_NODE, &no_bgp_graceful_restart_disable_cmd); + install_element(CONFIG_NODE, &bgp_graceful_restart_stalepath_time_cmd); + install_element(CONFIG_NODE, + &no_bgp_graceful_restart_stalepath_time_cmd); + install_element(CONFIG_NODE, &bgp_graceful_restart_restart_time_cmd); + install_element(CONFIG_NODE, &no_bgp_graceful_restart_restart_time_cmd); + install_element(CONFIG_NODE, + &bgp_graceful_restart_select_defer_time_cmd); + install_element(CONFIG_NODE, + &no_bgp_graceful_restart_select_defer_time_cmd); + install_element(CONFIG_NODE, &bgp_graceful_restart_preserve_fw_cmd); + install_element(CONFIG_NODE, &no_bgp_graceful_restart_preserve_fw_cmd); + install_element(CONFIG_NODE, &bgp_graceful_restart_rib_stale_time_cmd); + install_element(CONFIG_NODE, + &no_bgp_graceful_restart_rib_stale_time_cmd); + /* Dummy commands (Currently not supported) */ install_element(BGP_NODE, &no_synchronization_cmd); install_element(BGP_NODE, &no_auto_summary_cmd); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index e42b7f5ca5c4..c9abeb35da4d 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1391,9 +1391,31 @@ int bgp_global_gr_init(struct bgp *bgp) memcpy(bgp->GLOBAL_GR_FSM, local_GLOBAL_GR_FSM, sizeof(local_GLOBAL_GR_FSM)); - bgp->global_gr_present_state = GLOBAL_HELPER; + /* Inherit any BGP-wide configuration. */ + if (CHECK_FLAG(bm->flags, BM_FLAG_GR_RESTARTER)) + bgp->global_gr_present_state = GLOBAL_GR; + else if (CHECK_FLAG(bm->flags, BM_FLAG_GR_DISABLED)) + bgp->global_gr_present_state = GLOBAL_DISABLE; + else + bgp->global_gr_present_state = GLOBAL_HELPER; + + if (bm->restart_time != BGP_DEFAULT_RESTART_TIME) + bgp->restart_time = bm->restart_time; + if (bm->stalepath_time != BGP_DEFAULT_STALEPATH_TIME) + bgp->stalepath_time = bm->stalepath_time; + if (bm->select_defer_time != BGP_DEFAULT_SELECT_DEFERRAL_TIME) + bgp->select_defer_time = bm->select_defer_time; + if (bm->rib_stale_time != BGP_DEFAULT_RIB_STALE_TIME) + bgp->rib_stale_time = bm->rib_stale_time; + if (CHECK_FLAG(bm->flags, BM_FLAG_GR_PRESERVE_FWD)) + SET_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD); + bgp->present_zebra_gr_state = ZEBRA_GR_DISABLE; + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) + zlog_debug("%s: Global GR state is %s", bgp->name_pretty, + print_global_gr_mode(bgp->global_gr_present_state)); + return BGP_GR_SUCCESS; } @@ -8405,6 +8427,10 @@ void bgp_master_init(struct event_loop *master, const int buffer_size, bm->t_bgp_sync_label_manager = NULL; bm->t_bgp_start_label_manager = NULL; bm->t_bgp_zebra_route = NULL; + bm->restart_time = BGP_DEFAULT_RESTART_TIME; + bm->stalepath_time = BGP_DEFAULT_STALEPATH_TIME; + bm->select_defer_time = BGP_DEFAULT_SELECT_DEFERRAL_TIME; + bm->rib_stale_time = BGP_DEFAULT_RIB_STALE_TIME; bgp_mac_init(); /* init the rd id space. diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 1f8cc5334986..77955fd5c912 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -163,6 +163,18 @@ struct bgp_master { uint32_t flags; #define BM_FLAG_GRACEFUL_SHUTDOWN (1 << 0) #define BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA (1 << 1) +#define BM_FLAG_MAINTENANCE_MODE (1 << 2) +#define BM_FLAG_GR_RESTARTER (1 << 3) +#define BM_FLAG_GR_DISABLED (1 << 4) +#define BM_FLAG_GR_PRESERVE_FWD (1 << 5) + +#define BM_FLAG_GR_CONFIGURED (BM_FLAG_GR_RESTARTER | BM_FLAG_GR_DISABLED) + + /* BGP-wide graceful restart config params */ + uint32_t restart_time; + uint32_t stalepath_time; + uint32_t select_defer_time; + uint32_t rib_stale_time; bool terminating; /* global flag that sigint terminate seen */ From f0210cbacccf4497a79ed6f45fa61831ec5c24f9 Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Wed, 29 May 2024 14:14:20 -0700 Subject: [PATCH 354/472] bgpd: Added ! after BGP global config Signed-off-by: Pooja Jagadeesh Doijode --- bgpd/bgp_vty.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index ba392e39e6da..3dec4dd265b5 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -19408,6 +19408,8 @@ int bgp_config_write(struct vty *vty) if (bm->outq_limit != BM_DEFAULT_Q_LIMIT) vty_out(vty, "bgp output-queue-limit %u\n", bm->outq_limit); + vty_out(vty, "!\n"); + /* BGP configuration. */ for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp)) { From 15403f521a12b668e87ef8961c78e0ed97c6ff92 Mon Sep 17 00:00:00 2001 From: vivek Date: Sun, 25 Oct 2020 11:31:42 -0700 Subject: [PATCH 355/472] bgpd: Streamline GR config, act on change immediately Streamline the BGP graceful-restart configuration at the global and peer level some more. Similar to many other neighbor capability parameters like MP and ENHE, reset the session immediately upon a change to the configuration. This will be more aligned with the transactional UI model also and will not require a separate 'clear' command to be executed. Note: Peer-group graceful-restart configuration is not yet supported. Signed-off-by: Vivek Venkatraman --- bgpd/bgp_fsm.c | 379 +++++++++++++++++-------------------------------- bgpd/bgp_fsm.h | 5 +- bgpd/bgp_vty.c | 124 ++++------------ bgpd/bgp_vty.h | 47 +++--- bgpd/bgpd.c | 4 +- 5 files changed, 187 insertions(+), 372 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index d41ef8abbac9..8e1462f24b19 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -2695,53 +2695,56 @@ int bgp_event_update(struct peer_connection *connection, } /* BGP GR Code */ -int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp, - enum global_mode global_new_state, - enum global_mode global_old_state) +static inline void +bgp_peer_inherit_global_gr_mode(struct peer *peer, + enum global_mode global_gr_mode) +{ + switch (global_gr_mode) { + case GLOBAL_HELPER: + BGP_PEER_GR_HELPER_ENABLE(peer); + case GLOBAL_GR: + BGP_PEER_GR_ENABLE(peer); + case GLOBAL_DISABLE: + BGP_PEER_GR_DISABLE(peer); + default: + zlog_err("Unexpected Global GR mode %d", global_gr_mode); + } +} + +static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp, + enum global_mode global_new_state) { struct peer *peer = {0}; struct listnode *node = {0}; struct listnode *nnode = {0}; enum peer_mode peer_old_state = PEER_INVALID; - for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("%s [BGP_GR] Peer: (%s) :", __func__, - peer->host); + /* TODO: Need to handle peer-groups. */ + for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { peer_old_state = bgp_peer_gr_mode_get(peer); + if (peer_old_state != PEER_GLOBAL_INHERIT) + continue; - if (peer_old_state == PEER_GLOBAL_INHERIT) { + bgp_peer_inherit_global_gr_mode(peer, global_new_state); + bgp_peer_gr_flags_update(peer); - /* - *Reset only these peers and send a - *new open message with the change capabilities. - *Considering the mode to be "global_new_state" and - *do all operation accordingly - */ + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) + zlog_debug("%pBP: Inherited Global GR mode, GR flags 0x%x peer flags 0x%" PRIx64 + "...resetting session", + peer, peer->peer_gr_new_status_flag, + peer->flags); - switch (global_new_state) { - case GLOBAL_HELPER: - BGP_PEER_GR_HELPER_ENABLE(peer); - break; - case GLOBAL_GR: - BGP_PEER_GR_ENABLE(peer); - break; - case GLOBAL_DISABLE: - BGP_PEER_GR_DISABLE(peer); - break; - case GLOBAL_INVALID: - zlog_debug("%s [BGP_GR] GLOBAL_INVALID", - __func__); - return BGP_ERR_GR_OPERATION_FAILED; - } - } + /* Reset session to match with behavior for other peer + * configs that require the session to be re-setup. + */ + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { + peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); + } else + bgp_session_reset(peer); } - - bgp->global_gr_present_state = global_new_state; - - return BGP_GR_SUCCESS; } int bgp_gr_update_all(struct bgp *bgp, enum global_gr_command global_gr_cmd) @@ -2749,46 +2752,27 @@ int bgp_gr_update_all(struct bgp *bgp, enum global_gr_command global_gr_cmd) enum global_mode global_new_state = GLOBAL_INVALID; enum global_mode global_old_state = GLOBAL_INVALID; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("%s [BGP_GR]START: global_gr_cmd :%s:", __func__, - print_global_gr_cmd(global_gr_cmd)); - global_old_state = bgp_global_gr_mode_get(bgp); + global_new_state = bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd]; if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] global_old_gr_state :%s:", - print_global_gr_mode(global_old_state)); + zlog_debug("%s: Handle GR command %s, current GR state %s, new GR state %s", + bgp->name_pretty, print_global_gr_cmd(global_gr_cmd), + print_global_gr_mode(global_old_state), + print_global_gr_mode(global_new_state)); - if (global_old_state != GLOBAL_INVALID) { - global_new_state = - bgp->GLOBAL_GR_FSM[global_old_state][global_gr_cmd]; - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] global_new_gr_state :%s:", - print_global_gr_mode(global_new_state)); - } else { - zlog_err("%s [BGP_GR] global_old_state == GLOBAL_INVALID", - __func__); + if (global_old_state == GLOBAL_INVALID) return BGP_ERR_GR_OPERATION_FAILED; - } - - if (global_new_state == GLOBAL_INVALID) { - zlog_err("%s [BGP_GR] global_new_state == GLOBAL_INVALID", - __func__); + if (global_new_state == GLOBAL_INVALID) return BGP_ERR_GR_INVALID_CMD; - } - if (global_new_state == global_old_state) { - /* Trace msg */ - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "%s [BGP_GR] global_new_state == global_old_state :%s", - __func__, - print_global_gr_mode(global_new_state)); + if (global_new_state == global_old_state) return BGP_GR_NO_OPERATION; - } - return bgp_gr_lookup_n_update_all_peer(bgp, global_new_state, - global_old_state); + /* Update global GR mode and process all peers in instance. */ + bgp->global_gr_present_state = global_new_state; + bgp_gr_update_mode_of_all_peers(bgp, global_new_state); + + return BGP_GR_SUCCESS; } const char *print_peer_gr_mode(enum peer_mode pr_mode) @@ -2903,179 +2887,101 @@ int bgp_neighbor_graceful_restart(struct peer *peer, { enum peer_mode peer_new_state = PEER_INVALID; enum peer_mode peer_old_state = PEER_INVALID; - struct bgp_peer_gr peer_state; + struct bgp_peer_gr gr_fsm; int result = BGP_GR_FAILURE; - /* - * fetch peer_old_state from peer structure also - * fetch global_old_state from bgp structure, - * peer had a back pointer to bgpo struct ; - */ - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("%s [BGP_GR] START:Peer: (%s) : peer_gr_cmd :%s:", - __func__, peer->host, - print_peer_gr_cmd(peer_gr_cmd)); - peer_old_state = bgp_peer_gr_mode_get(peer); + gr_fsm = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd]; + peer_new_state = gr_fsm.next_state; if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("%s [BGP_GR] peer_old_state: %d", __func__, - peer_old_state); + zlog_debug("%pBP: Handle GR command %s, current GR state %s, new GR state %s", + peer, print_peer_gr_cmd(peer_gr_cmd), + print_peer_gr_mode(peer_old_state), + print_peer_gr_mode(peer_new_state)); if (peer_old_state == PEER_INVALID) return BGP_ERR_GR_OPERATION_FAILED; - peer_state = peer->PEER_GR_FSM[peer_old_state][peer_gr_cmd]; - peer_new_state = peer_state.next_state; - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("%s [BGP_GR] peer_new_state: %d", __func__, - peer_new_state); - if (peer_new_state == PEER_INVALID) return BGP_ERR_GR_INVALID_CMD; - if (peer_new_state != peer_old_state) { - result = peer_state.action_fun(peer, peer_old_state, - peer_new_state); - } else { - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] peer_old_state == peer_new_state !"); + if (peer_new_state == peer_old_state) return BGP_GR_NO_OPERATION; - } - if (result == BGP_GR_SUCCESS) { - - /* Update the mode i.e peer_new_state into the peer structure */ - peer->peer_gr_present_state = peer_new_state; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] Successfully change the state of the peer to : %s : !", - print_peer_gr_mode(peer_new_state)); - - return BGP_GR_SUCCESS; - } + result = gr_fsm.action_fun(peer, peer_old_state, peer_new_state); return result; } -unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_peer_state, - enum peer_mode new_peer_state) +static inline bool gr_mode_matches(enum peer_mode peer_gr_mode, + enum global_mode global_gr_mode) { - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "%s [BGP_GR] Move peer from old_peer_state :%s: to new_peer_state :%s: !!!!", - __func__, print_peer_gr_mode(old_peer_state), - print_peer_gr_mode(new_peer_state)); + if ((peer_gr_mode == PEER_HELPER && global_gr_mode == GLOBAL_HELPER) || + (peer_gr_mode == PEER_GR && global_gr_mode == GLOBAL_GR) || + (peer_gr_mode == PEER_DISABLE && global_gr_mode == GLOBAL_DISABLE)) + return true; + return false; +} - enum global_mode bgp_gr_global_mode = GLOBAL_INVALID; - unsigned int ret = BGP_GR_FAILURE; +unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state, + enum peer_mode new_state) +{ + enum global_mode global_gr_mode = bgp_global_gr_mode_get(peer->bgp); + bool session_reset = true; - if (old_peer_state == new_peer_state) { - /* Nothing to do over here as the present and old state is the - * same */ + if (old_state == new_state) return BGP_GR_NO_OPERATION; - } - if ((old_peer_state == PEER_INVALID) - || (new_peer_state == PEER_INVALID)) { - /* something bad happend , print error message */ + if ((old_state == PEER_INVALID) || (new_state == PEER_INVALID)) return BGP_ERR_GR_INVALID_CMD; - } - - bgp_gr_global_mode = bgp_global_gr_mode_get(peer->bgp); - - if ((old_peer_state == PEER_GLOBAL_INHERIT) - && (new_peer_state != PEER_GLOBAL_INHERIT)) { - /* fetch the Mode running in the Global state machine - *from the bgp structure into a variable called - *bgp_gr_global_mode - */ - - /* Here we are checking if the - *1. peer_new_state == global_mode == helper_mode - *2. peer_new_state == global_mode == GR_mode - *3. peer_new_state == global_mode == disabled_mode - */ + global_gr_mode = bgp_global_gr_mode_get(peer->bgp); + if ((old_state == PEER_GLOBAL_INHERIT) && + (new_state != PEER_GLOBAL_INHERIT)) { BGP_PEER_GR_GLOBAL_INHERIT_UNSET(peer); - if ((int)new_peer_state == (int)bgp_gr_global_mode) { - /* This is incremental updates i.e no tear down - * of the existing session - * as the peer is already working in the same mode. + if (gr_mode_matches(new_state, global_gr_mode)) + /* Peer was inheriting the global state and + * its new state still is the same, so a + * session reset is not needed. */ - ret = BGP_GR_SUCCESS; - } else { - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] Peer state changed from :%s ", - print_peer_gr_mode(old_peer_state)); - - bgp_peer_move_to_gr_mode(peer, new_peer_state); - - ret = BGP_GR_SUCCESS; - } - } - /* In the case below peer is going into Global inherit mode i.e. - * the peer would work as the mode configured at the global level - */ - else if ((new_peer_state == PEER_GLOBAL_INHERIT) - && (old_peer_state != PEER_GLOBAL_INHERIT)) { - /* Here in this case it would be destructive - * in all the cases except one case when, - * Global GR is configured Disabled - * and present_peer_state is not disable - */ - + session_reset = false; + } else if ((new_state == PEER_GLOBAL_INHERIT) && + (old_state != PEER_GLOBAL_INHERIT)) { BGP_PEER_GR_GLOBAL_INHERIT_SET(peer); - if ((int)old_peer_state == (int)bgp_gr_global_mode) { - /* This is incremental updates - *i.e no tear down of the existing session - *as the peer is already working in the same mode. - */ - ret = BGP_GR_SUCCESS; - } else { - /* Destructive always */ - /* Tear down the old session - * and send the new capability - * as per the bgp_gr_global_mode + if (gr_mode_matches(old_state, global_gr_mode)) + /* Peer is inheriting the global state and + * its old state was also the same, so a + * session reset is not needed. */ + session_reset = false; + } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] Peer state changed from :%s", - print_peer_gr_mode(old_peer_state)); - - bgp_peer_move_to_gr_mode(peer, bgp_gr_global_mode); + /* Ensure we move to the new state and update flags */ + bgp_peer_move_to_gr_mode(peer, new_state); - ret = BGP_GR_SUCCESS; - } - } else { - /* - *This else case, it include all the cases except --> - *(new_peer_state != Peer_Global) && - *( old_peer_state != Peer_Global ) + if (session_reset) { + /* Reset session to match with behavior for other peer + * configs that require the session to be re-setup. */ - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] Peer state changed from :%s", - print_peer_gr_mode(old_peer_state)); - - bgp_peer_move_to_gr_mode(peer, new_peer_state); - - ret = BGP_GR_SUCCESS; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { + peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; + bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, + BGP_NOTIFY_CEASE_CONFIG_CHANGE); + } else + bgp_session_reset(peer); } - return ret; + return BGP_GR_SUCCESS; } -inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state) +void bgp_peer_move_to_gr_mode(struct peer *peer, enum peer_mode new_state) { - int bgp_global_gr_mode = bgp_global_gr_mode_get(peer->bgp); + enum global_mode global_gr_mode = bgp_global_gr_mode_get(peer->bgp); + enum peer_mode old_state = bgp_peer_gr_mode_get(peer); switch (new_state) { case PEER_HELPER: @@ -3089,57 +2995,38 @@ inline void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state) break; case PEER_GLOBAL_INHERIT: BGP_PEER_GR_GLOBAL_INHERIT_SET(peer); - - if (bgp_global_gr_mode == GLOBAL_HELPER) { - BGP_PEER_GR_HELPER_ENABLE(peer); - } else if (bgp_global_gr_mode == GLOBAL_GR) { - BGP_PEER_GR_ENABLE(peer); - } else if (bgp_global_gr_mode == GLOBAL_DISABLE) { - BGP_PEER_GR_DISABLE(peer); - } else { - zlog_err( - "[BGP_GR] Default switch inherit mode ::: SOMETHING IS WRONG !!!"); - } + bgp_peer_inherit_global_gr_mode(peer, global_gr_mode); break; + case PEER_INVALID: default: zlog_err( "[BGP_GR] Default switch mode ::: SOMETHING IS WRONG !!!"); break; } + bgp_peer_gr_flags_update(peer); + peer->peer_gr_present_state = new_state; + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] Peer state changed --to--> : %d : !", - new_state); + zlog_debug("%pBP: Peer GR mode changed from %s to %s, GR flags 0x%x peer flags 0x%" PRIx64, + peer, print_peer_gr_mode(old_state), + print_peer_gr_mode(new_state), + peer->peer_gr_new_status_flag, peer->flags); } void bgp_peer_gr_flags_update(struct peer *peer) { - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("%s [BGP_GR] called !", __func__); if (CHECK_FLAG(peer->peer_gr_new_status_flag, PEER_GRACEFUL_RESTART_NEW_STATE_HELPER)) SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER); else UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER); - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_HELPER : %s : !", - peer->host, - (CHECK_FLAG(peer->flags, - PEER_FLAG_GRACEFUL_RESTART_HELPER) - ? "Set" - : "UnSet")); + if (CHECK_FLAG(peer->peer_gr_new_status_flag, PEER_GRACEFUL_RESTART_NEW_STATE_RESTART)) SET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART); else UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART); - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART : %s : !", - peer->host, - (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART) - ? "Set" - : "UnSet")); + if (CHECK_FLAG(peer->peer_gr_new_status_flag, PEER_GRACEFUL_RESTART_NEW_STATE_INHERIT)) SET_FLAG(peer->flags, @@ -3147,28 +3034,28 @@ void bgp_peer_gr_flags_update(struct peer *peer) else UNSET_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT); + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] Peer %s Flag PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT : %s : !", - peer->host, - (CHECK_FLAG(peer->flags, - PEER_FLAG_GRACEFUL_RESTART_GLOBAL_INHERIT) - ? "Set" - : "UnSet")); - - if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART) - && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) { - zlog_debug("[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_MODE!", - peer->host); + zlog_debug("%pBP: Peer flags updated to 0x%" PRIx64 + ", GR flags 0x%x, GR mode %s", + peer, peer->flags, peer->peer_gr_new_status_flag, + print_peer_gr_mode(bgp_peer_gr_mode_get(peer))); + /* + * If GR has been completely disabled for the peer and we were + * acting as the Helper for the peer (i.e., keeping stale routes + * and running the restart timer or stalepath timer), clear those + * states. + */ + if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART) && + !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) { UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE); if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) { - + if (bgp_debug_neighbor_events(peer)) + zlog_debug("%pBP: GR disabled, stopping NSF and clearing stale routes", + peer); peer_nsf_stop(peer); - zlog_debug( - "[BGP_GR] Peer %s UNSET PEER_STATUS_NSF_WAIT!", - peer->host); } } } diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index bcdd49193fc3..85c488962fc9 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -151,7 +151,7 @@ int bgp_neighbor_graceful_restart(struct peer *peer, enum peer_gr_command peer_gr_cmd); unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_peer_state, enum peer_mode new_peer_state); -void bgp_peer_move_to_gr_mode(struct peer *peer, int new_state); +void bgp_peer_move_to_gr_mode(struct peer *peer, enum peer_mode new_state); unsigned int bgp_peer_gr_helper_enable(struct peer *peer); unsigned int bgp_peer_gr_enable(struct peer *peer); unsigned int bgp_peer_gr_global_inherit(struct peer *peer); @@ -160,9 +160,6 @@ enum peer_mode bgp_peer_gr_mode_get(struct peer *peer); enum global_mode bgp_global_gr_mode_get(struct bgp *bgp); enum peer_mode bgp_get_peer_gr_mode_from_flags(struct peer *peer); unsigned int bgp_peer_gr_global_inherit_unset(struct peer *peer); -int bgp_gr_lookup_n_update_all_peer(struct bgp *bgp, - enum global_mode global_new_state, - enum global_mode global_old_state); void bgp_peer_gr_flags_update(struct peer *peer); const char *print_peer_gr_mode(enum peer_mode pr_mode); const char *print_peer_gr_cmd(enum peer_gr_command pr_gr_cmd); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 3dec4dd265b5..f5aa2e03bfc3 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3123,10 +3123,6 @@ DEFUN (bgp_graceful_restart, return bgp_global_gr_config_vty(vty, true, false); int ret = BGP_GR_FAILURE; - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] bgp_graceful_restart_cmd : START "); - VTY_DECLVAR_CONTEXT(bgp, bgp); ret = bgp_inst_gr_config_vty(vty, bgp, true, false); @@ -3135,9 +3131,6 @@ DEFUN (bgp_graceful_restart, "Graceful restart configuration changed, reset all peers to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] bgp_graceful_restart_cmd : END "); - return bgp_vty_return(vty, ret); } @@ -3153,10 +3146,6 @@ DEFUN (no_bgp_graceful_restart, return bgp_global_gr_config_vty(vty, false, false); VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] no_bgp_graceful_restart_cmd : START "); - int ret = BGP_GR_FAILURE; ret = bgp_inst_gr_config_vty(vty, bgp, false, false); @@ -3168,9 +3157,6 @@ DEFUN (no_bgp_graceful_restart, "Graceful restart configuration changed, reset all peers to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] no_bgp_graceful_restart_cmd : END "); - return bgp_vty_return(vty, ret); } @@ -3460,10 +3446,6 @@ DEFUN (bgp_graceful_restart_disable, struct listnode *node, *nnode; struct peer *peer; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] bgp_graceful_restart_disable_cmd : START "); - VTY_DECLVAR_CONTEXT(bgp, bgp); ret = bgp_inst_gr_config_vty(vty, bgp, true, true); @@ -3481,9 +3463,6 @@ DEFUN (bgp_graceful_restart_disable, } } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] bgp_graceful_restart_disable_cmd : END "); - return bgp_vty_return(vty, ret); } @@ -3499,11 +3478,6 @@ DEFUN (no_bgp_graceful_restart_disable, return bgp_global_gr_config_vty(vty, false, true); VTY_DECLVAR_CONTEXT(bgp, bgp); - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_graceful_restart_disable_cmd : START "); - int ret = BGP_GR_FAILURE; ret = bgp_inst_gr_config_vty(vty, bgp, false, true); @@ -3512,10 +3486,6 @@ DEFUN (no_bgp_graceful_restart_disable, "Graceful restart configuration changed, reset all peers to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_graceful_restart_disable_cmd : END "); - return bgp_vty_return(vty, ret); } @@ -3533,13 +3503,14 @@ DEFUN (bgp_neighbor_graceful_restart_set, VTY_BGP_GR_DEFINE_LOOP_VARIABLE; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : START "); - peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + vty_out(vty, + "Per peer-group graceful-restart configuration is not yet supported\n"); + return CMD_WARNING_CONFIG_FAILED; + } result = bgp_neighbor_graceful_restart(peer, PEER_GR_CMD); if (result == BGP_GR_SUCCESS) { @@ -3549,15 +3520,7 @@ DEFUN (bgp_neighbor_graceful_restart_set, "Graceful restart configuration changed, reset this peer to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] bgp_neighbor_graceful_restart_set_cmd : END "); - - if (ret != BGP_GR_SUCCESS) - vty_out(vty, - "As part of configuring graceful-restart, capability send to zebra failed\n"); - - return bgp_vty_return(vty, result); + return bgp_vty_return(vty, ret); } DEFUN (no_bgp_neighbor_graceful_restart, @@ -3578,10 +3541,11 @@ DEFUN (no_bgp_neighbor_graceful_restart, peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : START "); + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + vty_out(vty, + "Per peer-group graceful-restart configuration is not yet supported\n"); + return CMD_WARNING_CONFIG_FAILED; + } result = bgp_neighbor_graceful_restart(peer, NO_PEER_GR_CMD); if (ret == BGP_GR_SUCCESS) { @@ -3591,14 +3555,6 @@ DEFUN (no_bgp_neighbor_graceful_restart, "Graceful restart configuration changed, reset this peer to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_neighbor_graceful_restart_set_cmd : END "); - - if (ret != BGP_GR_SUCCESS) - vty_out(vty, - "As part of configuring graceful-restart, capability send to zebra failed\n"); - return bgp_vty_return(vty, result); } @@ -3616,15 +3572,14 @@ DEFUN (bgp_neighbor_graceful_restart_helper_set, VTY_BGP_GR_DEFINE_LOOP_VARIABLE; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] bgp_neighbor_graceful_restart_helper_set_cmd : START "); - peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); - if (!peer) return CMD_WARNING_CONFIG_FAILED; - + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + vty_out(vty, + "Per peer-group graceful-restart configuration is not yet supported\n"); + return CMD_WARNING_CONFIG_FAILED; + } ret = bgp_neighbor_graceful_restart(peer, PEER_HELPER_CMD); if (ret == BGP_GR_SUCCESS) { @@ -3634,10 +3589,6 @@ DEFUN (bgp_neighbor_graceful_restart_helper_set, "Graceful restart configuration changed, reset this peer to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] bgp_neighbor_graceful_restart_helper_set_cmd : END "); - return bgp_vty_return(vty, ret); } @@ -3659,10 +3610,11 @@ DEFUN (no_bgp_neighbor_graceful_restart_helper, peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_neighbor_graceful_restart_helper_set_cmd : START "); + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + vty_out(vty, + "Per peer-group graceful-restart configuration is not yet supported\n"); + return CMD_WARNING_CONFIG_FAILED; + } ret = bgp_neighbor_graceful_restart(peer, NO_PEER_HELPER_CMD); if (ret == BGP_GR_SUCCESS) { @@ -3672,10 +3624,6 @@ DEFUN (no_bgp_neighbor_graceful_restart_helper, "Graceful restart configuration changed, reset this peer to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_neighbor_graceful_restart_helper_set_cmd : END "); - return bgp_vty_return(vty, ret); } @@ -3693,13 +3641,14 @@ DEFUN (bgp_neighbor_graceful_restart_disable_set, VTY_BGP_GR_DEFINE_LOOP_VARIABLE; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] bgp_neighbor_graceful_restart_disable_set_cmd : START "); - peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + vty_out(vty, + "Per peer-group graceful-restart configuration is not yet supported\n"); + return CMD_WARNING_CONFIG_FAILED; + } ret = bgp_neighbor_graceful_restart(peer, PEER_DISABLE_CMD); if (ret == BGP_GR_SUCCESS) { @@ -3708,14 +3657,8 @@ DEFUN (bgp_neighbor_graceful_restart_disable_set, VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer); VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret); - vty_out(vty, - "Graceful restart configuration changed, reset this peer to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR]bgp_neighbor_graceful_restart_disable_set_cmd : END "); - return bgp_vty_return(vty, ret); } @@ -3737,23 +3680,18 @@ DEFUN (no_bgp_neighbor_graceful_restart_disable, peer = peer_and_group_lookup_vty(vty, argv[idx_peer]->arg); if (!peer) return CMD_WARNING_CONFIG_FAILED; - - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_neighbor_graceful_restart_disable_set_cmd : START "); + if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + vty_out(vty, + "Per peer-group graceful-restart configuration is not yet supported\n"); + return CMD_WARNING_CONFIG_FAILED; + } ret = bgp_neighbor_graceful_restart(peer, NO_PEER_DISABLE_CMD); if (ret == BGP_GR_SUCCESS) { VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer); VTY_SEND_BGP_GR_CAPABILITY_TO_ZEBRA(peer->bgp, ret); - vty_out(vty, - "Graceful restart configuration changed, reset this peer to take effect\n"); } - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] no_bgp_neighbor_graceful_restart_disable_set_cmd : END "); - return bgp_vty_return(vty, ret); } diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index addd71757d47..6d86f6ba086b 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -60,8 +60,6 @@ struct bgp; #define VTY_BGP_GR_ROUTER_DETECT(_bgp, _peer, _peer_list) \ do { \ - if (_peer->bgp->t_startup) \ - bgp_peer_gr_flags_update(_peer); \ for (ALL_LIST_ELEMENTS(_peer_list, node, nnode, peer_loop)) { \ if (CHECK_FLAG(peer_loop->flags, \ PEER_FLAG_GRACEFUL_RESTART)) \ @@ -84,30 +82,27 @@ struct bgp; } \ } while (0) -#define VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA( \ - _bgp, _peer_list, _ret) \ - do { \ - struct peer *peer_loop; \ - bool gr_router_detected = false; \ - struct listnode *node = {0}; \ - struct listnode *nnode = {0}; \ - for (ALL_LIST_ELEMENTS(_peer_list, node, nnode, peer_loop)) { \ - if (peer_loop->bgp->t_startup) \ - bgp_peer_gr_flags_update(peer_loop); \ - if (CHECK_FLAG(peer_loop->flags, \ - PEER_FLAG_GRACEFUL_RESTART)) \ - gr_router_detected = true; \ - } \ - if (gr_router_detected \ - && _bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) { \ - if (bgp_zebra_send_capabilities(_bgp, false)) \ - _ret = BGP_ERR_INVALID_VALUE; \ - } else if (!gr_router_detected \ - && _bgp->present_zebra_gr_state \ - == ZEBRA_GR_ENABLE) { \ - if (bgp_zebra_send_capabilities(_bgp, true)) \ - _ret = BGP_ERR_INVALID_VALUE; \ - } \ +#define VTY_BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(_bgp, \ + _peer_list, _ret) \ + do { \ + struct peer *peer_loop; \ + bool gr_router_detected = false; \ + struct listnode *node = { 0 }; \ + struct listnode *nnode = { 0 }; \ + for (ALL_LIST_ELEMENTS(_peer_list, node, nnode, peer_loop)) { \ + if (CHECK_FLAG(peer_loop->flags, \ + PEER_FLAG_GRACEFUL_RESTART)) \ + gr_router_detected = true; \ + } \ + if (gr_router_detected && \ + _bgp->present_zebra_gr_state == ZEBRA_GR_DISABLE) { \ + if (bgp_zebra_send_capabilities(_bgp, false)) \ + _ret = BGP_ERR_INVALID_VALUE; \ + } else if (!gr_router_detected && \ + _bgp->present_zebra_gr_state == ZEBRA_GR_ENABLE) { \ + if (bgp_zebra_send_capabilities(_bgp, true)) \ + _ret = BGP_ERR_INVALID_VALUE; \ + } \ } while (0) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index c9abeb35da4d..17d94bd57518 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1475,9 +1475,7 @@ int bgp_peer_gr_init(struct peer *peer) { PEER_HELPER, bgp_peer_gr_action }, { PEER_GLOBAL_INHERIT, NULL } } }; - memcpy(&peer->PEER_GR_FSM, local_Peer_GR_FSM, - sizeof(local_Peer_GR_FSM)); - peer->peer_gr_present_state = PEER_GLOBAL_INHERIT; + memcpy(&peer->PEER_GR_FSM, local_Peer_GR_FSM, sizeof(local_Peer_GR_FSM)); bgp_peer_move_to_gr_mode(peer, PEER_GLOBAL_INHERIT); return BGP_GR_SUCCESS; From dc00f2dc1d4d3f6435c31bf8d4777ff78b851d12 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Thu, 28 Sep 2023 20:11:31 -0400 Subject: [PATCH 356/472] doc: add ability to disambiguate clicmds Multiple daemons have the same CLI commands defined, but the current directive used to document CLI commands only takes the command definition string. Since CLI command objects can be cross-referenced using the :clicmd: directive, and are placed in the index, each object needs to be unique. To accomplish this, add a custom directive. This directive extends the directive class used by sphinx's add_object_type to add a :daemon: option. By specifying this option where needed, the object name becomes "() ", disambiguating it. Signed-off-by: Quentin Young --- doc/user/conf.py | 50 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/doc/user/conf.py b/doc/user/conf.py index 629a97272601..a36d4406f3b8 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -18,6 +18,8 @@ import pygments import sphinx from sphinx.highlighting import lexers +from sphinx.domains.std import GenericObject +from docutils.parsers.rst import directives # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -373,13 +375,49 @@ def vparse(s): return a[:3] -# custom extensions here +class ClicmdDirective(GenericObject): + """ + Directive for documenting CLI commands. + + The xref string, if no option is provided, will be the verbatim command + string. If the :daemon: option is provided, then it's + "() )". + + Options: + :daemon: - specify the daemon this command belongs to. Useful for + disambiguating multiple definitions of the same command. + """ + + has_content = True + required_arguments = 1 + optional_arguments = 0 + option_spec = { + **GenericObject.option_spec, + "daemon": directives.unchanged, + } + + def handle_signature(self, sig, signode): + name = super().handle_signature(sig, signode) + daemon = self.options["daemon"] if "daemon" in self.options else "" + prefix = f"({daemon}) " if daemon else "" + return prefix + name + + def run(self): + daemon = self.options["daemon"] if "daemon" in self.options else "" + if daemon: + self.indextemplate = f"pair: ({daemon}) %s; configuration command" + else: + self.indextemplate = f"pair: %s; configuration command" + + nodes = super().run() + + return nodes + + def setup(app): - # object type for FRR CLI commands, can be extended to document parent CLI - # node later on - app.add_object_type( - "clicmd", "clicmd", indextemplate="pair: %s; configuration command" - ) + app.add_object_type("clicmd", "clicmd", objname="CLI command") + # Override the directive that was just created for us + app.add_directive_to_domain("std", "clicmd", ClicmdDirective, override=True) # I dont care how stupid this is if "add_js_file" in dir(app): From ffbad581fc2f3b6e75b59b0e91393dfe0039d861 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 26 Jun 2024 18:17:07 -0400 Subject: [PATCH 357/472] doc: do not use custom directive on old sphinx Not supported. Signed-off-by: Quentin Young --- doc/user/conf.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/user/conf.py b/doc/user/conf.py index a36d4406f3b8..395875520d7f 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -415,9 +415,14 @@ def run(self): def setup(app): - app.add_object_type("clicmd", "clicmd", objname="CLI command") # Override the directive that was just created for us - app.add_directive_to_domain("std", "clicmd", ClicmdDirective, override=True) + if int(sphinx.__version__.split(".")[0]) >= 2: + app.add_object_type("clicmd", "clicmd", objname="CLI command") + app.add_directive_to_domain("std", "clicmd", ClicmdDirective, override=True) + else: + app.add_object_type( + "clicmd", "clicmd", indextemplate="pair: %s; configuration command" + ) # I dont care how stupid this is if "add_js_file" in dir(app): From fa2cc09d45d3f843564f7bd1e02346373c5741a8 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 27 Jun 2024 22:46:58 +0300 Subject: [PATCH 358/472] bgpd: Ignore RFC8212 for BGP Confederations RFC 8212 should be restricted for eBGP peers. Signed-off-by: Donatas Abraitis --- bgpd/bgp_route.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 9c3602311f77..71e4199530fb 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6333,7 +6333,8 @@ void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi) bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) { - if (peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD) + if (peer->sort == BGP_PEER_CONFED || peer->sort == BGP_PEER_IBGP || + peer->sub_sort == BGP_PEER_EBGP_OAD) return true; if (peer->sort == BGP_PEER_EBGP && @@ -6346,7 +6347,8 @@ bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter) { - if (peer->sort == BGP_PEER_IBGP || peer->sub_sort == BGP_PEER_EBGP_OAD) + if (peer->sort == BGP_PEER_CONFED || peer->sort == BGP_PEER_IBGP || + peer->sub_sort == BGP_PEER_EBGP_OAD) return true; if (peer->sort == BGP_PEER_EBGP From dd6a679e3a0e9415827643942bcc103c48a89adb Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 27 Jun 2024 22:53:24 +0300 Subject: [PATCH 359/472] tests: Test if RFC 8212 is not involved for BGP confederations Signed-off-by: Donatas Abraitis --- tests/topotests/bgp_confed1/r2/bgpd.conf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/topotests/bgp_confed1/r2/bgpd.conf b/tests/topotests/bgp_confed1/r2/bgpd.conf index fe13dfe72994..ba2da4160e3d 100644 --- a/tests/topotests/bgp_confed1/r2/bgpd.conf +++ b/tests/topotests/bgp_confed1/r2/bgpd.conf @@ -4,7 +4,6 @@ !debug bgp updates out ! router bgp 200 - no bgp ebgp-requires-policy bgp confederation identifier 300 bgp confederation peers 300 neighbor 192.0.2.1 remote-as 100 @@ -12,7 +11,9 @@ router bgp 200 ! address-family ipv4 unicast network 203.0.113.16/28 + neighbor 192.0.2.1 route-map any in + neighbor 192.0.2.1 route-map any out neighbor 192.0.2.18 default-originate exit-address-family ! - +route-map any permit 10 From c6ed1cc16d083198cc5774971126aa371e653718 Mon Sep 17 00:00:00 2001 From: vivek Date: Sun, 25 Oct 2020 17:05:48 -0700 Subject: [PATCH 360/472] bgpd: Refine restarter operation - R-bit & F-bit Introduce BGP-wide flags to denote if BGP has started gracefully and GR is in progress or not. Use this for setting of the R-bit in the GR capability, and not a timer which is set for any new instance creation. Mark graceful restart is complete when the deferred path selection has been done and route sync with zebra as well as deferred EOR advertisement has been initiated. Introduce a function to check on F-bit setting rather than just base it on configuration. Subsequent commits will extend these functionalities. Signed-off-by: Vivek Venkatraman --- bgpd/bgp_fsm.c | 16 +++++++----- bgpd/bgp_main.c | 2 ++ bgpd/bgp_open.c | 54 +++++++++++++++++++-------------------- bgpd/bgp_packet.c | 2 +- bgpd/bgp_route.c | 18 ++++++++++++- bgpd/bgp_vty.c | 2 +- bgpd/bgpd.h | 65 +++++++++++++++++++++++++++++++++++++++++++++-- 7 files changed, 121 insertions(+), 38 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 8e1462f24b19..76624fee9e43 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -2046,9 +2046,10 @@ static int bgp_start_deferral_timer(struct bgp *bgp, afi_t afi, safi_t safi, } gr_info->eor_required++; /* Send message to RIB indicating route update pending */ - if (gr_info->af_enabled[afi][safi] == false) { - gr_info->af_enabled[afi][safi] = true; - /* Send message to RIB */ + if (gr_info->af_enabled == false) { + gr_info->af_enabled = true; + gr_info->route_sync = false; + bgp->gr_route_sync_pending = true; bgp_zebra_update(bgp, afi, safi, ZEBRA_CLIENT_ROUTE_UPDATE_PENDING); } @@ -2082,7 +2083,7 @@ static int bgp_update_gr_info(struct peer *peer, afi_t afi, safi_t safi) if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer) && BGP_PEER_RESTARTING_MODE(peer)) { /* Check if the forwarding state is preserved */ - if (CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)) { + if (bgp_gr_is_forwarding_preserved(bgp)) { gr_info = &(bgp->gr_info[afi][safi]); ret = bgp_start_deferral_timer(bgp, afi, safi, gr_info); } @@ -2199,8 +2200,7 @@ bgp_establish(struct peer_connection *connection) } else { if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer) && BGP_PEER_RESTARTING_MODE(peer) && - CHECK_FLAG(peer->bgp->flags, - BGP_FLAG_GR_PRESERVE_FWD)) + bgp_gr_is_forwarding_preserved(peer->bgp)) peer->bgp->gr_info[afi][safi] .eor_required++; } @@ -2702,10 +2702,14 @@ bgp_peer_inherit_global_gr_mode(struct peer *peer, switch (global_gr_mode) { case GLOBAL_HELPER: BGP_PEER_GR_HELPER_ENABLE(peer); + break; case GLOBAL_GR: BGP_PEER_GR_ENABLE(peer); + break; case GLOBAL_DISABLE: BGP_PEER_GR_DISABLE(peer); + break; + case GLOBAL_INVALID: default: zlog_err("Unexpected Global GR mode %d", global_gr_mode); } diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 97658d340bf3..bfedb50156ce 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -511,6 +511,7 @@ int main(int argc, char **argv) /* BGP master init. */ bgp_master_init(frr_init(), buffer_size, addresses); + bm->startup_time = monotime(NULL); bm->port = bgp_port; if (bgp_port == 0) bgp_option_set(BGP_OPT_NO_LISTEN); @@ -518,6 +519,7 @@ int main(int argc, char **argv) bgp_option_set(BGP_OPT_NO_FIB); if (no_zebra_flag) bgp_option_set(BGP_OPT_NO_ZEBRA); + SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART); bgp_error_init(); /* Initializations. */ libagentx_init(); diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 248d478fe1a3..b516701b808b 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -1587,15 +1587,12 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer, uint32_t restart_time; unsigned long capp = 0; unsigned long rcapp = 0; + struct bgp *bgp = peer->bgp; if (!CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART) && !CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART_HELPER)) return; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] Sending helper Capability for Peer :%s :", - peer->host); - SET_FLAG(peer->cap, PEER_CAP_RESTART_ADV); stream_putc(s, BGP_OPEN_OPT_CAP); capp = stream_get_endp(s); /* Set Capability Len Pointer */ @@ -1605,42 +1602,41 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer, /* Set Restart Capability Len Pointer */ rcapp = stream_get_endp(s); stream_putc(s, 0); - restart_time = peer->bgp->restart_time; - if (peer->bgp->t_startup) { + restart_time = bgp->restart_time; + if (peer->bgp->t_startup || bgp_in_graceful_restart()) { SET_FLAG(restart_time, GRACEFUL_RESTART_R_BIT); SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV); - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] Sending R-Bit for peer: %s", - peer->host); } - if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION)) { + if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_NOTIFICATION)) { SET_FLAG(restart_time, GRACEFUL_RESTART_N_BIT); SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV); - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] Sending N-Bit for peer: %s", - peer->host); } stream_putw(s, restart_time); + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) + zlog_debug("%s: Sending GR Capability, Restart time %d R-bit %s, N-bit %s", + peer->host, bgp->restart_time, + CHECK_FLAG(peer->cap, + PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV) + ? "SET" + : "NOT-SET", + CHECK_FLAG(peer->cap, + PEER_CAP_GRACEFUL_RESTART_N_BIT_ADV) + ? "SET" + : "NOT-SET"); + /* Send address-family specific graceful-restart capability * only when GR config is present */ if (CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_RESTART)) { - if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_GR_PRESERVE_FWD) - && BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug("[BGP_GR] F bit Set"); - FOREACH_AFI_SAFI (afi, safi) { + bool f_bit = false; + if (!peer->afc[afi][safi]) continue; - if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) - zlog_debug( - "[BGP_GR] Sending GR Capability for AFI :%d :, SAFI :%d:", - afi, safi); - /* Convert AFI, SAFI to values for * packet. */ @@ -1648,11 +1644,15 @@ static void bgp_peer_send_gr_capability(struct stream *s, struct peer *peer, &pkt_safi); stream_putw(s, pkt_afi); stream_putc(s, pkt_safi); - if (CHECK_FLAG(peer->bgp->flags, - BGP_FLAG_GR_PRESERVE_FWD)) - stream_putc(s, GRACEFUL_RESTART_F_BIT); - else - stream_putc(s, 0); + + f_bit = bgp_gr_is_forwarding_preserved(bgp); + + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) + zlog_debug("... F-bit %s for %s", + f_bit ? "SET" : "NOT-SET", + get_afi_safi_str(afi, safi, false)); + + stream_putc(s, f_bit ? GRACEFUL_RESTART_F_BIT : 0); } } diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 8825136e1768..157468f8c99c 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1296,7 +1296,7 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, stream_putc(s, 0); gr_restart_time = peer->bgp->restart_time; - if (peer->bgp->t_startup) { + if (peer->bgp->t_startup || bgp_in_graceful_restart()) { SET_FLAG(gr_restart_time, GRACEFUL_RESTART_R_BIT); SET_FLAG(peer->cap, PEER_CAP_GRACEFUL_RESTART_R_BIT_ADV); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 9c3602311f77..c7e7b7a740ac 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3877,6 +3877,7 @@ void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi) struct bgp_dest *dest; int cnt = 0; struct afi_safi_info *thread_info; + bool route_sync_pending = false; if (bgp->gr_info[afi][safi].t_route_select) { struct event *t = bgp->gr_info[afi][safi].t_route_select; @@ -3886,7 +3887,7 @@ void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi) EVENT_OFF(bgp->gr_info[afi][safi].t_route_select); } - if (BGP_DEBUG(update, UPDATE_OUT)) { + if (BGP_DEBUG(graceful_restart, GRACEFUL_RESTART)) { zlog_debug("%s: processing route for %s : cnt %d", __func__, get_afi_safi_str(afi, safi, false), bgp->gr_info[afi][safi].gr_deferred); @@ -3919,6 +3920,21 @@ void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi) /* Send route processing complete message to RIB */ bgp_zebra_update(bgp, afi, safi, ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE); + bgp->gr_info[afi][safi].route_sync = true; + + /* If this instance is all done, check for GR completion overall */ + FOREACH_AFI_SAFI_NSF (afi, safi) { + if (bgp->gr_info[afi][safi].af_enabled && + !bgp->gr_info[afi][safi].route_sync) { + route_sync_pending = true; + break; + } + } + + if (!route_sync_pending) { + bgp->gr_route_sync_pending = false; + bgp_update_gr_completion(); + } return; } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f5aa2e03bfc3..8ba167364c94 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3652,7 +3652,7 @@ DEFUN (bgp_neighbor_graceful_restart_disable_set, ret = bgp_neighbor_graceful_restart(peer, PEER_DISABLE_CMD); if (ret == BGP_GR_SUCCESS) { - if (peer->bgp->t_startup) + if (peer->bgp->t_startup || bgp_in_graceful_restart()) bgp_peer_gr_flags_update(peer); VTY_BGP_GR_ROUTER_DETECT(bgp, peer, peer->bgp->peer); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 77955fd5c912..3c5826113dec 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -167,6 +167,8 @@ struct bgp_master { #define BM_FLAG_GR_RESTARTER (1 << 3) #define BM_FLAG_GR_DISABLED (1 << 4) #define BM_FLAG_GR_PRESERVE_FWD (1 << 5) +#define BM_FLAG_GRACEFUL_RESTART (1 << 6) +#define BM_FLAG_GR_COMPLETE (1 << 7) #define BM_FLAG_GR_CONFIGURED (BM_FLAG_GR_RESTARTER | BM_FLAG_GR_DISABLED) @@ -176,6 +178,9 @@ struct bgp_master { uint32_t select_defer_time; uint32_t rib_stale_time; + time_t startup_time; + time_t gr_completion_time; + bool terminating; /* global flag that sigint terminate seen */ /* TOS value for outgoing packets in BGP connections */ @@ -305,9 +310,9 @@ struct graceful_restart_info { /* Best route select */ struct event *t_route_select; /* AFI, SAFI enabled */ - bool af_enabled[AFI_MAX][SAFI_MAX]; + bool af_enabled; /* Route update completed */ - bool route_sync[AFI_MAX][SAFI_MAX]; + bool route_sync; }; enum global_mode { @@ -559,6 +564,9 @@ struct bgp { */ enum zebra_gr_mode present_zebra_gr_state; + /* Is deferred path selection still not complete? */ + bool gr_route_sync_pending; + /* BGP Per AF flags */ uint16_t af_flags[AFI_MAX][SAFI_MAX]; #define BGP_CONFIG_DAMPENING (1 << 0) @@ -2754,6 +2762,59 @@ static inline bool bgp_in_graceful_shutdown(struct bgp *bgp) !!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)); } +static inline bool bgp_in_graceful_restart(void) +{ + /* True if BGP has (re)started gracefully (based on flags + * noted at startup) and GR is not complete. + */ + return (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART) && + !CHECK_FLAG(bm->flags, BM_FLAG_GR_COMPLETE)); +} + +static inline bool bgp_is_graceful_restart_complete(void) +{ + /* True if BGP has (re)started gracefully (based on flags + * noted at startup) and GR is marked as complete. + */ + return (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART) && + CHECK_FLAG(bm->flags, BM_FLAG_GR_COMPLETE)); +} + +static inline void bgp_update_gr_completion(void) +{ + struct listnode *node, *nnode; + struct bgp *bgp; + + /* + * Check and mark GR complete. This is done when deferred + * path selection has been completed for all instances and + * route-advertisement/EOR and route-sync with zebra has + * been invoked. + */ + if (!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART) || + CHECK_FLAG(bm->flags, BM_FLAG_GR_COMPLETE)) + return; + + for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (bgp->gr_route_sync_pending) + return; + } + + SET_FLAG(bm->flags, BM_FLAG_GR_COMPLETE); + bm->gr_completion_time = monotime(NULL); +} + +static inline bool bgp_gr_is_forwarding_preserved(struct bgp *bgp) +{ + /* + * Is forwarding state preserved? Based either on config + * or if BGP restarted gracefully. + * TBD: Additional AFI/SAFI based checks etc. + */ + return (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART) || + CHECK_FLAG(bgp->flags, BGP_FLAG_GR_PRESERVE_FWD)); +} + /* For benefit of rfapi */ extern struct peer *peer_new(struct bgp *bgp); From 496b2d1be452538607ca1e9db1bf557c9f299fb8 Mon Sep 17 00:00:00 2001 From: vivek Date: Sun, 25 Oct 2020 21:16:32 -0700 Subject: [PATCH 361/472] bgpd: Refine OPEN debug logs for graceful restart This also fixes Rx F-bit log which was incorrect. Signed-off-by: Vivek Venkatraman --- bgpd/bgp_open.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index b516701b808b..945076709c5c 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -519,20 +519,17 @@ static int bgp_capability_restart(struct peer *peer, UNSET_FLAG(restart_flag_time, 0xF000); peer->v_gr_restart = restart_flag_time; - if (bgp_debug_neighbor_events(peer)) { - zlog_debug( - "%s Peer has%srestarted. Restart Time: %d, N-bit set: %s", - peer->host, - CHECK_FLAG(peer->cap, - PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV) - ? " " - : " not ", - peer->v_gr_restart, - CHECK_FLAG(peer->cap, - PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV) - ? "yes" - : "no"); - } + if (bgp_debug_neighbor_events(peer)) + zlog_debug("%pBP OPEN has GR capability, Restart time %d R-bit %s N-bit %s", + peer, peer->v_gr_restart, + CHECK_FLAG(peer->cap, + PEER_CAP_GRACEFUL_RESTART_R_BIT_RCV) + ? "SET" + : "NOT-SET", + CHECK_FLAG(peer->cap, + PEER_CAP_GRACEFUL_RESTART_N_BIT_RCV) + ? "SET" + : "NOT-SET"); while (stream_get_getp(s) + 4 <= end) { afi_t afi; @@ -556,14 +553,12 @@ static int bgp_capability_restart(struct peer *peer, iana_safi2str(pkt_safi)); } else { if (bgp_debug_neighbor_events(peer)) - zlog_debug( - "%s Address family %s is%spreserved", - peer->host, get_afi_safi_str(afi, safi, false), - CHECK_FLAG( - peer->af_cap[afi][safi], - PEER_CAP_RESTART_AF_PRESERVE_RCV) - ? " " - : " not "); + zlog_debug("%pBP F-bit %s for %s", peer, + CHECK_FLAG(peer->af_cap[afi][safi], + PEER_CAP_RESTART_AF_PRESERVE_RCV) + ? "SET" + : "NOT-SET", + get_afi_safi_str(afi, safi, false)); SET_FLAG(peer->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV); From 75040a0295e3b6096bde58d12d54771a491d3454 Mon Sep 17 00:00:00 2001 From: vivek Date: Sun, 25 Oct 2020 21:21:55 -0700 Subject: [PATCH 362/472] bgpd: Enhance OPEN Tx debug log Signed-off-by: Vivek Venkatraman --- bgpd/bgp_packet.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 157468f8c99c..9a047b9d456f 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -696,10 +696,9 @@ void bgp_open_send(struct peer_connection *connection) bgp_packet_set_size(s); if (bgp_debug_neighbor_events(peer)) - zlog_debug( - "%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4", - peer->host, BGP_VERSION_4, local_as, send_holdtime, - &peer->local_id); + zlog_debug("%pBP fd %d sending OPEN, version %d, my as %u, holdtime %d, id %pI4", + peer, peer->connection->fd, BGP_VERSION_4, local_as, + send_holdtime, &peer->local_id); /* Dump packet if debug option is set. */ /* bgp_packet_dump (s); */ From c30b6833388a9ea858d483c583b2d73ec2f3409e Mon Sep 17 00:00:00 2001 From: vivek Date: Sun, 25 Oct 2020 21:54:13 -0700 Subject: [PATCH 363/472] bgpd: Refine debug logs for zebra GR registration Signed-off-by: Vivek Venkatraman --- bgpd/bgp_zebra.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 7f91e3149e0b..3508f2d341bb 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -3979,6 +3979,11 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable) return BGP_GR_FAILURE; } + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("%s(%d): Sending GR capability %s to zebra", + bgp->name_pretty, bgp->vrf_id, + disable ? "disabled" : "enabled"); + /* Check if capability is already sent. If the flag force is set * send the capability since this can be initial bgp configuration */ @@ -3994,8 +3999,8 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable) if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api) == ZCLIENT_SEND_FAILURE) { - zlog_err("%s: %s error sending capability", __func__, - bgp->name_pretty); + zlog_err("%s(%d): Error sending GR capability to zebra", + bgp->name_pretty, bgp->vrf_id); ret = BGP_GR_FAILURE; } else { if (disable) @@ -4003,9 +4008,6 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable) else bgp->present_zebra_gr_state = ZEBRA_GR_ENABLE; - if (BGP_DEBUG(zebra, ZEBRA)) - zlog_debug("%s: %s send capabilty success", __func__, - bgp->name_pretty); ret = BGP_GR_SUCCESS; } return ret; From ecbca1ae1be5e4e3f68bc712696f28d01909803c Mon Sep 17 00:00:00 2001 From: Pooja Jagadeesh Doijode Date: Wed, 26 Jun 2024 17:34:44 -0700 Subject: [PATCH 364/472] tests: Updated topotest and documentation Added topotest and documentation for BGP wide GR configurations Signed-off-by: Pooja Jagadeesh Doijode --- doc/user/bgp.rst | 46 +++ .../test_bgp_gr_functionality_topo1-4.py | 301 ++++++++++++++++++ .../test_bgp_gr_notification.py | 10 +- tests/topotests/lib/bgp.py | 77 ++++- 4 files changed, 412 insertions(+), 22 deletions(-) diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 150a915e3a88..034d57956822 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1080,6 +1080,52 @@ Default global mode is helper and default peer per mode is inherit from global. If per peer mode is configured, the GR mode of this particular peer will override the global mode. +.. _bgp-GR-config-mode-cmd: + +BGP GR Config Mode Commands +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. clicmd:: bgp graceful-restart + + This command will enable BGP graceful restart functionality for all BGP instances. + +.. clicmd:: bgp graceful-restart-disable + + This command will disable both the functionality graceful restart and helper + mode for all BGP instances + +.. clicmd:: bgp graceful-restart select-defer-time (0-3600) + + This is command, will set deferral time to value specified. + +.. clicmd:: bgp graceful-restart rib-stale-time (1-3600) + + This is command, will set the time for which stale routes are kept in RIB. + +.. clicmd:: bgp graceful-restart restart-time (0-4095) + + Set the time to wait to delete stale routes before a BGP open message + is received. + + Using with Long-lived Graceful Restart capability, this is recommended + setting this timer to 0 and control stale routes with + ``bgp long-lived-graceful-restart stale-time``. + + Default value is 120. + +.. clicmd:: bgp graceful-restart stalepath-time (1-4095) + + This is command, will set the max time (in seconds) to hold onto + restarting peer's stale paths. + + It also controls Enhanced Route-Refresh timer. + + If this command is configured and the router does not receive a Route-Refresh EoRR + message, the router removes the stale routes from the BGP table after the timer + expires. The stale path timer is started when the router receives a Route-Refresh + BoRR message + + .. _bgp-GR-global-mode-cmd: BGP GR Global Mode Commands diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py index 31aaa0b8a6df..de4b94032c06 100644 --- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py +++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py @@ -81,6 +81,8 @@ import sys import time import pytest +import functools +import json # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -91,6 +93,7 @@ # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen from lib.topolog import logger +from lib import topotest # Required to instantiate the topology builder class. @@ -1680,6 +1683,304 @@ def BGP_GR_TC_52_p1(request): write_test_footer(tc_name) +def test_BGP_GR_TC_53_p1(request): + """ + Test Objective : Peer-level inherit from BGP wide Restarting + Global Mode : GR Restart + PerPeer Mode : None + GR Mode effective : GR Restart + + """ + + tgen = get_topogen() + tc_name = request.node.name + write_test_header(tc_name) + + # Check router status + check_router_status(tgen) + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Creating configuration from JSON + reset_config_on_routers(tgen) + + step("Configure R1 as GR restarting node in global level") + + input_dict = { + "r1": {"graceful-restart": {"graceful-restart": True}}, + "r2": {"graceful-restart": {"graceful-restart-helper": True}}, + } + + output = tgen.gears["r1"].vtysh_cmd( + """ + configure terminal + bgp graceful-restart + ! + """ + ) + + step("Verify that R2 receives GR restarting capabilities" " from R1") + + for addr_type in ADDR_TYPES: + result = verify_graceful_restart( + tgen, topo, addr_type, input_dict, dut="r1", peer="r2" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + result = verify_graceful_restart( + tgen, topo, addr_type, input_dict, dut="r2", peer="r1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + for addr_type in ADDR_TYPES: + dut = "r1" + peer = "r2" + protocol = "bgp" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_2 + ) + input_topo = {"r2": topo["routers"]["r2"]} + result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + dut = "r2" + peer = "r1" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_1 + ) + input_topo = {"r1": topo["routers"]["r1"]} + result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Kill BGPd on router R1") + + kill_router_daemons(tgen, "r1", ["bgpd"]) + + step( + "Verify that R1 keeps the stale entries in FIB and R2 keeps stale entries in RIB & FIB" + ) + + for addr_type in ADDR_TYPES: + dut = "r1" + peer = "r2" + protocol = "bgp" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_2 + ) + input_topo = {"r2": topo["routers"]["r2"]} + result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + dut = "r2" + peer = "r1" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_1 + ) + input_topo = {"r1": topo["routers"]["r1"]} + result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + # Configure graceful-restart-disable at config global level verify that the functionality works + step("Bring up BGP on R1 and configure graceful-restart-disable") + + start_router_daemons(tgen, "r1", ["bgpd"]) + + input_dict = { + "r1": {"graceful-restart": {"graceful-restart-disable": True}}, + "r2": {"graceful-restart": {"graceful-restart-helper": True}}, + } + + output = tgen.gears["r1"].vtysh_cmd( + """ + configure terminal + bgp graceful-restart-disable + ! + """ + ) + + step("Verify on R2 that R1 does't advertise any GR capabilities") + + for addr_type in ADDR_TYPES: + result = verify_graceful_restart( + tgen, topo, addr_type, input_dict, dut="r1", peer="r2" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + result = verify_graceful_restart( + tgen, topo, addr_type, input_dict, dut="r2", peer="r1" + ) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + for addr_type in ADDR_TYPES: + dut = "r1" + peer = "r2" + protocol = "bgp" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_2 + ) + input_topo = {"r2": topo["routers"]["r2"]} + result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + dut = "r2" + peer = "r1" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_1 + ) + input_topo = {"r1": topo["routers"]["r1"]} + result = verify_bgp_rib(tgen, addr_type, dut, input_topo, next_hop) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + result = verify_rib(tgen, addr_type, dut, input_topo, next_hop, protocol) + assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) + + step("Kill BGP on R1") + + kill_router_daemons(tgen, "r1", ["bgpd"]) + + step("Verify on R2 and R1 that none of the routers keep stale entries") + + for addr_type in ADDR_TYPES: + dut = "r1" + peer = "r2" + protocol = "bgp" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_2 + ) + input_topo = {"r2": topo["routers"]["r2"]} + result = verify_rib( + tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} FIB \n " + "Found: {}".format(tc_name, dut, result) + ) + + dut = "r2" + peer = "r1" + next_hop = next_hop_per_address_family( + tgen, dut, peer, addr_type, NEXT_HOP_IP_1 + ) + input_topo = {"r1": topo["routers"]["r1"]} + result = verify_bgp_rib( + tgen, addr_type, dut, input_topo, next_hop, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} BGP RIB \n " + "Found: {}".format(tc_name, dut, result) + ) + + result = verify_rib( + tgen, addr_type, dut, input_topo, next_hop, protocol, expected=False + ) + assert result is not True, ( + "Testcase {} : Failed \n " + "Expected: Routes should not be present in {} FIB \n " + "Found: {}".format(tc_name, dut, result) + ) + + step( + "Bring up BGP on R1, enable GR and configure bgp graceful-restart restart-time at global level" + ) + + start_router_daemons(tgen, "r1", ["bgpd"]) + + output = tgen.gears["r1"].vtysh_cmd( + """ + configure terminal + no bgp graceful-restart-disable + bgp graceful-restart + bgp graceful-restart stalepath-time 420 + bgp graceful-restart restart-time 240 + bgp graceful-restart select-defer-time 420 + ! + """ + ) + + step("Verify on R2 that R1 sent the updated GR restart-time") + + def _bgp_check_if_gr_restart_time_was_updated(): + output = json.loads(tgen.gears["r2"].vtysh_cmd("show bgp neighbor json")) + + expected = { + "192.168.0.1": { + "gracefulRestartInfo": { + "localGrMode": "Helper*", + "remoteGrMode": "Restart", + "timers": { + "configuredRestartTimer": 120, + "receivedRestartTimer": 240, + }, + }, + }, + "fd00::1": { + "gracefulRestartInfo": { + "localGrMode": "Helper*", + "remoteGrMode": "Restart", + "timers": { + "configuredRestartTimer": 120, + "receivedRestartTimer": 240, + }, + }, + }, + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_gr_restart_time_was_updated, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "R2 did not receive the updated GR restart-time of 240s" + + def _bgp_check_if_gr_timer_on_restarting_node_was_updated(): + output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp neighbor json")) + + expected = { + "192.168.0.2": { + "gracefulRestartInfo": { + "localGrMode": "Restart*", + "remoteGrMode": "Helper", + "timers": { + "configuredRestartTimer": 240, + "receivedRestartTimer": 120, + }, + "ipv4Unicast": { + "timers": {"stalePathTimer": 420, "selectionDeferralTimer": 420} + }, + }, + }, + "fd00::2": { + "gracefulRestartInfo": { + "localGrMode": "Restart*", + "remoteGrMode": "Helper", + "timers": { + "configuredRestartTimer": 240, + "receivedRestartTimer": 120, + }, + "ipv6Unicast": { + "timers": {"stalePathTimer": 420, "selectionDeferralTimer": 420} + }, + }, + }, + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_check_if_gr_timer_on_restarting_node_was_updated, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert ( + result is None + ), "R1 did not update the GR select-deferral and stale-path timer to 420s" + + write_test_footer(tc_name) + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py index 16459a25a33d..5d8338d6eb2a 100644 --- a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py +++ b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py @@ -195,16 +195,16 @@ def _bgp_clear_r1_and_shutdown(): step("Reset and shutdown R1") _bgp_clear_r1_and_shutdown() - step("Check if Hard Reset notification wasn't sent from R2") - test_func = functools.partial(_bgp_check_hard_reset) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert result is None, "Failed to send Administrative Reset notification from R2" - step("Check if stale routes are retained on R1") test_func = functools.partial(_bgp_check_gr_notification_stale) _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to see retained stale routes on R1" + step("Check if Hard Reset notification wasn't sent from R2") + test_func = functools.partial(_bgp_check_hard_reset) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to send Administrative Reset notification from R2" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 4250c405f3dc..3f4ed6e0b8b6 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -3266,27 +3266,48 @@ def verify_graceful_restart( lmode = None rmode = None - # Local GR mode - if "address_family" in input_dict[dut]["bgp"]: - bgp_neighbors = input_dict[dut]["bgp"]["address_family"][addr_type][ - "unicast" - ]["neighbor"][peer]["dest_link"] - for dest_link, data in bgp_neighbors.items(): + # Local GR mode + if "bgp" not in input_dict[dut] and "graceful-restart" in input_dict[dut]: if ( - "graceful-restart-helper" in data - and data["graceful-restart-helper"] + "graceful-restart" in input_dict[dut]["graceful-restart"] + and input_dict[dut]["graceful-restart"][ + "graceful-restart" + ] ): - lmode = "Helper" - elif "graceful-restart" in data and data["graceful-restart"]: - lmode = "Restart" + lmode = "Restart*" elif ( - "graceful-restart-disable" in data - and data["graceful-restart-disable"] + "graceful-restart-disable" + in input_dict[dut]["graceful-restart"] + and input_dict[dut]["graceful-restart"][ + "graceful-restart-disable" + ] ): - lmode = "Disable" + lmode = "Disable*" else: - lmode = None + lmode = "Helper*" + + if lmode is None: + if "address_family" in input_dict[dut]["bgp"]: + bgp_neighbors = input_dict[dut]["bgp"]["address_family"][addr_type][ + "unicast" + ]["neighbor"][peer]["dest_link"] + + for dest_link, data in bgp_neighbors.items(): + if ( + "graceful-restart-helper" in data + and data["graceful-restart-helper"] + ): + lmode = "Helper" + elif "graceful-restart" in data and data["graceful-restart"]: + lmode = "Restart" + elif ( + "graceful-restart-disable" in data + and data["graceful-restart-disable"] + ): + lmode = "Disable" + else: + lmode = None if lmode is None: if "graceful-restart" in input_dict[dut]["bgp"]: @@ -3314,7 +3335,8 @@ def verify_graceful_restart( return True # Remote GR mode - if "address_family" in input_dict[peer]["bgp"]: + + if "bgp" in input_dict[peer] and "address_family" in input_dict[peer]["bgp"]: bgp_neighbors = input_dict[peer]["bgp"]["address_family"][addr_type][ "unicast" ]["neighbor"][dut]["dest_link"] @@ -3336,7 +3358,7 @@ def verify_graceful_restart( rmode = None if rmode is None: - if "graceful-restart" in input_dict[peer]["bgp"]: + if "bgp" in input_dict[peer] and "graceful-restart" in input_dict[peer]["bgp"]: if ( "graceful-restart" in input_dict[peer]["bgp"]["graceful-restart"] @@ -3355,6 +3377,27 @@ def verify_graceful_restart( rmode = "Disable" else: rmode = "Helper" + + if rmode is None: + if "bgp" not in input_dict[peer] and "graceful-restart" in input_dict[peer]: + if ( + "graceful-restart" + in input_dict[peer]["graceful-restart"] + and input_dict[peer]["graceful-restart"][ + "graceful-restart" + ] + ): + rmode = "Restart" + elif ( + "graceful-restart-disable" + in input_dict[peer]["graceful-restart"] + and input_dict[peer]["graceful-restart"][ + "graceful-restart-disable" + ] + ): + rmode = "Disable" + else: + rmode = "Helper" else: rmode = "Helper" From b5682ffbf0051b54af972e6da4c3319adb7a292f Mon Sep 17 00:00:00 2001 From: vivek Date: Wed, 26 Jun 2024 15:49:45 -0700 Subject: [PATCH 365/472] *: Add and use option for graceful (re)start Add a new start option "-K" to libfrr to denote a graceful start, and use it in zebra and bgpd. zebra will use this option to denote a planned FRR graceful restart (supporting only bgpd currently) to wait for a route sync completion from bgpd before cleaning up old stale routes from the FIB. An optional timer provides an upper-bounds for this cleanup. bgpd will use this option to denote either a planned FRR graceful restart or a bgpd-only graceful restart, and this will drive the BGP GR restarting router procedures. Signed-off-by: Vivek Venkatraman --- bgpd/bgp_main.c | 4 +- bgpd/bgp_vty.c | 3 +- doc/user/bgp.rst | 6 +++ lib/libfrr.c | 45 +++++++++++++-------- lib/libfrr.h | 2 + tests/topotests/lib/bgp.py | 55 +++++++++++++------------- zebra/main.c | 33 +++++++++------- zebra/rib.h | 4 +- zebra/zapi_msg.c | 1 + zebra/zebra_gr.c | 81 ++++++++++++++++++++++++++------------ zebra/zebra_rib.c | 11 +++++- zebra/zebra_router.c | 2 +- zebra/zebra_router.h | 10 ++++- zebra/zebra_vty.c | 14 +++++++ zebra/zserv.c | 40 +++++++++++++++++++ zebra/zserv.h | 2 + 16 files changed, 221 insertions(+), 92 deletions(-) diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index bfedb50156ce..5e6a62c9b929 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -519,7 +519,9 @@ int main(int argc, char **argv) bgp_option_set(BGP_OPT_NO_FIB); if (no_zebra_flag) bgp_option_set(BGP_OPT_NO_ZEBRA); - SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART); + if (bgpd_di.graceful_restart) + SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_RESTART); + bgp_error_init(); /* Initializations. */ libagentx_init(); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 8ba167364c94..e9a79766ec84 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -3706,9 +3706,10 @@ DEFPY (neighbor_graceful_shutdown, afi_t afi; safi_t safi; struct peer *peer; - VTY_DECLVAR_CONTEXT(bgp, bgp); int ret; + VTY_DECLVAR_CONTEXT(bgp, bgp); + peer = peer_and_group_lookup_vty(vty, neighbor); if (!peer) return CMD_WARNING_CONFIG_FAILED; diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 034d57956822..98834c7c2349 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -92,6 +92,12 @@ be specified (:ref:`common-invocation-options`). the operator has turned off communication to zebra and is running bgpd as a complete standalone process. +.. option:: -K, --graceful_restart + + Bgpd will use this option to denote either a planned FRR graceful + restart or a bgpd-only graceful restart, and this will drive the BGP + GR restarting router procedures. + LABEL MANAGER ------------- diff --git a/lib/libfrr.c b/lib/libfrr.c index 876efe23a826..338a7d0340f7 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -102,23 +102,25 @@ static void opt_extend(const struct optspec *os) #define OPTION_SCRIPTDIR 1009 static const struct option lo_always[] = { - {"help", no_argument, NULL, 'h'}, - {"version", no_argument, NULL, 'v'}, - {"daemon", no_argument, NULL, 'd'}, - {"module", no_argument, NULL, 'M'}, - {"profile", required_argument, NULL, 'F'}, - {"pathspace", required_argument, NULL, 'N'}, - {"vrfdefaultname", required_argument, NULL, 'o'}, - {"vty_socket", required_argument, NULL, OPTION_VTYSOCK}, - {"moduledir", required_argument, NULL, OPTION_MODULEDIR}, - {"scriptdir", required_argument, NULL, OPTION_SCRIPTDIR}, - {"log", required_argument, NULL, OPTION_LOG}, - {"log-level", required_argument, NULL, OPTION_LOGLEVEL}, - {"command-log-always", no_argument, NULL, OPTION_LOGGING}, - {"limit-fds", required_argument, NULL, OPTION_LIMIT_FDS}, - {NULL}}; + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'v' }, + { "daemon", no_argument, NULL, 'd' }, + { "module", no_argument, NULL, 'M' }, + { "profile", required_argument, NULL, 'F' }, + { "pathspace", required_argument, NULL, 'N' }, + { "vrfdefaultname", required_argument, NULL, 'o' }, + { "graceful_restart", optional_argument, NULL, 'K' }, + { "vty_socket", required_argument, NULL, OPTION_VTYSOCK }, + { "moduledir", required_argument, NULL, OPTION_MODULEDIR }, + { "scriptdir", required_argument, NULL, OPTION_SCRIPTDIR }, + { "log", required_argument, NULL, OPTION_LOG }, + { "log-level", required_argument, NULL, OPTION_LOGLEVEL }, + { "command-log-always", no_argument, NULL, OPTION_LOGGING }, + { "limit-fds", required_argument, NULL, OPTION_LIMIT_FDS }, + { NULL } +}; static const struct optspec os_always = { - "hvdM:F:N:o:", + "hvdM:F:N:o:K::", " -h, --help Display this help and exit\n" " -v, --version Print program version\n" " -d, --daemon Runs in daemon mode\n" @@ -126,13 +128,15 @@ static const struct optspec os_always = { " -F, --profile Use specified configuration profile\n" " -N, --pathspace Insert prefix into config & socket paths\n" " -o, --vrfdefaultname Set default VRF name.\n" + " -K, --graceful_restart FRR starting in Graceful Restart mode, with optional route-cleanup timer\n" " --vty_socket Override vty socket path\n" " --moduledir Override modules directory\n" " --scriptdir Override scripts directory\n" " --log Set Logging to stdout, syslog, or file:\n" " --log-level Set Logging Level to use, debug, info, warn, etc\n" " --limit-fds Limit number of fds supported\n", - lo_always}; + lo_always +}; static bool logging_to_stdout = false; /* set when --log stdout specified */ @@ -358,6 +362,8 @@ void frr_preinit(struct frr_daemon_info *daemon, int argc, char **argv) strlcpy(frr_protonameinst, di->logname, sizeof(frr_protonameinst)); di->cli_mode = FRR_CLI_CLASSIC; + di->graceful_restart = false; + di->gr_cleanup_time = 0; /* we may be starting with extra FDs open for whatever purpose, * e.g. logging, some module, etc. Recording them here allows later @@ -520,6 +526,11 @@ static int frr_opt(int opt) di->db_file = optarg; break; #endif + case 'K': + di->graceful_restart = true; + if (optarg) + di->gr_cleanup_time = atoi(optarg); + break; case 'C': if (di->flags & FRR_NO_SPLIT_CONFIG) return 1; diff --git a/lib/libfrr.h b/lib/libfrr.h index 77d70448a9a1..db9cfbcb1f2b 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -118,6 +118,8 @@ struct frr_daemon_info { bool dryrun; bool daemon_mode; bool terminal; + bool graceful_restart; + int gr_cleanup_time; enum frr_cli_mode cli_mode; struct event *read_in; diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py index 3f4ed6e0b8b6..bcd1c748120f 100644 --- a/tests/topotests/lib/bgp.py +++ b/tests/topotests/lib/bgp.py @@ -3269,29 +3269,24 @@ def verify_graceful_restart( # Local GR mode if "bgp" not in input_dict[dut] and "graceful-restart" in input_dict[dut]: - if ( - "graceful-restart" in input_dict[dut]["graceful-restart"] - and input_dict[dut]["graceful-restart"][ - "graceful-restart" - ] - ): - lmode = "Restart*" - elif ( - "graceful-restart-disable" - in input_dict[dut]["graceful-restart"] - and input_dict[dut]["graceful-restart"][ - "graceful-restart-disable" - ] - ): - lmode = "Disable*" - else: - lmode = "Helper*" + if ( + "graceful-restart" in input_dict[dut]["graceful-restart"] + and input_dict[dut]["graceful-restart"]["graceful-restart"] + ): + lmode = "Restart*" + elif ( + "graceful-restart-disable" in input_dict[dut]["graceful-restart"] + and input_dict[dut]["graceful-restart"]["graceful-restart-disable"] + ): + lmode = "Disable*" + else: + lmode = "Helper*" if lmode is None: if "address_family" in input_dict[dut]["bgp"]: bgp_neighbors = input_dict[dut]["bgp"]["address_family"][addr_type][ - "unicast" - ]["neighbor"][peer]["dest_link"] + "unicast" + ]["neighbor"][peer]["dest_link"] for dest_link, data in bgp_neighbors.items(): if ( @@ -3336,7 +3331,10 @@ def verify_graceful_restart( # Remote GR mode - if "bgp" in input_dict[peer] and "address_family" in input_dict[peer]["bgp"]: + if ( + "bgp" in input_dict[peer] + and "address_family" in input_dict[peer]["bgp"] + ): bgp_neighbors = input_dict[peer]["bgp"]["address_family"][addr_type][ "unicast" ]["neighbor"][dut]["dest_link"] @@ -3358,7 +3356,10 @@ def verify_graceful_restart( rmode = None if rmode is None: - if "bgp" in input_dict[peer] and "graceful-restart" in input_dict[peer]["bgp"]: + if ( + "bgp" in input_dict[peer] + and "graceful-restart" in input_dict[peer]["bgp"] + ): if ( "graceful-restart" in input_dict[peer]["bgp"]["graceful-restart"] @@ -3379,13 +3380,13 @@ def verify_graceful_restart( rmode = "Helper" if rmode is None: - if "bgp" not in input_dict[peer] and "graceful-restart" in input_dict[peer]: + if ( + "bgp" not in input_dict[peer] + and "graceful-restart" in input_dict[peer] + ): if ( - "graceful-restart" - in input_dict[peer]["graceful-restart"] - and input_dict[peer]["graceful-restart"][ - "graceful-restart" - ] + "graceful-restart" in input_dict[peer]["graceful-restart"] + and input_dict[peer]["graceful-restart"]["graceful-restart"] ): rmode = "Restart" elif ( diff --git a/zebra/main.c b/zebra/main.c index ea1e1cbdbbd8..687da70cabce 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -65,8 +65,6 @@ struct mgmt_be_client *mgmt_be_client; /* Route retain mode flag. */ int retain_mode = 0; -int graceful_restart; - /* Receive buffer size for kernel control sockets */ #define RCVBUFSIZE_MIN 4194304 #ifdef HAVE_NETLINK @@ -88,7 +86,6 @@ const struct option longopts[] = { { "socket", required_argument, NULL, 'z' }, { "ecmp", required_argument, NULL, 'e' }, { "retain", no_argument, NULL, 'r' }, - { "graceful_restart", required_argument, NULL, 'K' }, { "asic-offload", optional_argument, NULL, OPTION_ASIC_OFFLOAD }, { "v6-with-v4-nexthops", no_argument, NULL, OPTION_V6_WITH_V4_NEXTHOP }, #ifdef HAVE_NETLINK @@ -96,7 +93,7 @@ const struct option longopts[] = { { "nl-bufsize", required_argument, NULL, 's' }, { "v6-rr-semantics", no_argument, NULL, OPTION_V6_RR_SEMANTICS }, #endif /* HAVE_NETLINK */ - {"routing-table", optional_argument, NULL, 'R'}, + { "routing-table", optional_argument, NULL, 'R' }, { 0 } }; @@ -326,7 +323,6 @@ int main(int argc, char **argv) bool v6_with_v4_nexthop = false; bool notify_on_ack = true; - graceful_restart = 0; vrf_configure_backend(VRF_BACKEND_VRF_LITE); frr_preinit(&zebra_di, argc, argv); @@ -342,7 +338,6 @@ int main(int argc, char **argv) " -z, --socket Set path of zebra socket\n" " -e, --ecmp Specify ECMP to use.\n" " -r, --retain When program terminates, retain added route by zebra.\n" - " -K, --graceful_restart Graceful restart at the kernel level, timer in seconds for expiration\n" " -A, --asic-offload FRR is interacting with an asic underneath the linux kernel\n" " --v6-with-v4-nexthops Underlying dataplane supports v6 routes with v4 nexthops" #ifdef HAVE_NETLINK @@ -352,8 +347,7 @@ int main(int argc, char **argv) #else " -s, Set kernel socket receive buffer size\n" #endif /* HAVE_NETLINK */ - " -R, --routing-table Set kernel routing table\n" - ); + " -R, --routing-table Set kernel routing table\n"); while (1) { int opt = frr_getopt(argc, argv, NULL); @@ -397,9 +391,6 @@ int main(int argc, char **argv) case 'r': retain_mode = 1; break; - case 'K': - graceful_restart = atoi(optarg); - break; case 's': rcvbufsize = atoi(optarg); if (rcvbufsize < RCVBUFSIZE_MIN) @@ -488,11 +479,25 @@ int main(int argc, char **argv) * Clean up zebra-originated routes. The requests will be sent to OS * immediately, so originating PID in notifications from kernel * will be equal to the current getpid(). To know about such routes, - * we have to have route_read() called before. + * we have to have route_read() called before. + * If FRR is gracefully restarting, we either wait for clients + * (e.g., BGP) to signal GR is complete else we wait for specified + * duration. */ zrouter.startup_time = monotime(NULL); - event_add_timer(zrouter.master, rib_sweep_route, NULL, graceful_restart, - &zrouter.sweeper); + zrouter.rib_sweep_time = 0; + zrouter.graceful_restart = zebra_di.graceful_restart; + if (!zrouter.graceful_restart) + event_add_timer(zrouter.master, rib_sweep_route, NULL, 0, NULL); + else { + int gr_cleanup_time; + + gr_cleanup_time = zebra_di.gr_cleanup_time + ? zebra_di.gr_cleanup_time + : ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME; + event_add_timer(zrouter.master, rib_sweep_route, NULL, + gr_cleanup_time, &zrouter.t_rib_sweep); + } /* Needed for BSD routing socket. */ pid = getpid(); diff --git a/zebra/rib.h b/zebra/rib.h index a721f4bac456..84ea766c4733 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -622,10 +622,10 @@ static inline struct nexthop_group *rib_get_fib_backup_nhg( } extern void zebra_gr_process_client(afi_t afi, vrf_id_t vrf_id, uint8_t proto, - uint8_t instance); + uint8_t instance, time_t restart_time); extern int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, - uint8_t instance); + uint8_t instance, time_t restart_time); extern void zebra_vty_init(void); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 2a1eea9594ee..654ade806355 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2414,6 +2414,7 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf) stream_putl(s, zrouter.multipath_num); stream_putc(s, zebra_mlag_get_role()); stream_putc(s, zrouter.v6_with_v4_nexthop); + stream_putc(s, zrouter.graceful_restart); stream_putw_at(s, 0, stream_get_endp(s)); zserv_send_message(client, s); } diff --git a/zebra/zebra_gr.c b/zebra/zebra_gr.c index cee66cc05545..d84f680e2288 100644 --- a/zebra/zebra_gr.c +++ b/zebra/zebra_gr.c @@ -103,6 +103,7 @@ static struct client_gr_info *zebra_gr_client_info_create(struct zserv *client) info->stale_client_ptr = client; TAILQ_INSERT_TAIL(&(client->gr_info_queue), info, gr_info); + info->client_ptr = client; return info; } @@ -290,6 +291,7 @@ struct zebra_gr_afi_clean { afi_t afi; uint8_t proto; uint8_t instance; + time_t restart_time; struct event *t_gac; }; @@ -420,7 +422,7 @@ void zread_client_capabilities(ZAPI_HANDLER_ARGS) * Schedule for after anything already in the meta Q */ rib_add_gr_run(api.afi, api.vrf_id, client->proto, - client->instance); + client->instance, client->restart_time); zebra_gr_process_client_stale_routes(client, info); break; case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING: @@ -455,7 +457,11 @@ static void zebra_gr_route_stale_delete_timer_expiry(struct event *thread) struct zserv *client; struct vrf *vrf = vrf_lookup_by_id(info->vrf_id); - client = (struct zserv *)info->stale_client_ptr; + info->t_stale_removal = NULL; + if (zrouter.graceful_restart) + client = (struct zserv *)info->client_ptr; + else + client = (struct zserv *)info->stale_client_ptr; cnt = zebra_gr_delete_stale_routes(info); @@ -486,16 +492,24 @@ static void zebra_gr_route_stale_delete_timer_expiry(struct event *thread) * * Returns true when a node is deleted else false */ -static bool zebra_gr_process_route_entry(struct zserv *client, - struct route_node *rn, - struct route_entry *re) +static bool zebra_gr_process_route_entry(struct route_node *rn, + struct route_entry *re, + time_t compare_time, uint8_t proto) { + struct nexthop *nexthop; + char buf[PREFIX2STR_BUFFER]; + /* If the route is not refreshed after restart, delete the entry */ - if (re->uptime < client->restart_time) { - if (IS_ZEBRA_DEBUG_RIB) - zlog_debug("%s: Client %s stale route %pFX is deleted", - __func__, zebra_route_string(client->proto), - &rn->p); + if (re->uptime < compare_time) { + if (IS_ZEBRA_DEBUG_RIB) { + prefix2str(&rn->p, buf, sizeof(buf)); + zlog_debug("%s: Client %s stale route %s is deleted", + __func__, zebra_route_string(proto), buf); + } + SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); + for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + rib_delnode(rn, re); return true; @@ -532,8 +546,9 @@ static void zebra_gr_delete_stale_route_table_afi(struct event *event) if (re->type == gac->proto && re->instance == gac->instance && - zebra_gr_process_route_entry( - gac->info->stale_client_ptr, rn, re)) + zebra_gr_process_route_entry(rn, re, + gac->restart_time, + gac->proto)) n++; /* If the max route count is reached @@ -567,28 +582,42 @@ static int32_t zebra_gr_delete_stale_route(struct client_gr_info *info, uint8_t proto; uint16_t instance; struct zserv *s_client; + struct zserv *client; + time_t restart_time = time(NULL); - s_client = info->stale_client_ptr; - if (s_client == NULL) { - LOG_GR("%s: Stale client %s(%u) not present", __func__, - zvrf->vrf->name, zvrf->vrf->vrf_id); + if ((info == NULL) || (zvrf == NULL)) return -1; - } - proto = s_client->proto; - instance = s_client->instance; + if (zrouter.graceful_restart) { + client = info->client_ptr; + if (client == NULL) { + LOG_GR("%s: client not present", __func__); + return -1; + } + proto = client->proto; + instance = client->instance; + restart_time = zrouter.startup_time; + } else { + s_client = info->stale_client_ptr; + if (s_client == NULL) { + LOG_GR("%s: Stale client not present", __func__); + return -1; + } + proto = s_client->proto; + instance = s_client->instance; + restart_time = s_client->restart_time; + } LOG_GR("%s: Client %s %s(%u) stale routes are being deleted", __func__, zebra_route_string(proto), zvrf->vrf->name, zvrf->vrf->vrf_id); /* Process routes for all AFI */ for (afi = AFI_IP; afi < AFI_MAX; afi++) { - /* * Schedule for immediately after anything in the * meta-Q */ - rib_add_gr_run(afi, info->vrf_id, proto, instance); + rib_add_gr_run(afi, info->vrf_id, proto, instance, restart_time); } return 0; } @@ -641,12 +670,13 @@ static void zebra_gr_process_client_stale_routes(struct zserv *client, /* * Route update completed for all AFI, SAFI - * Cancel the stale timer, routes are already being processed + * Also perform the cleanup if FRR itself is gracefully restarting. */ - if (info->t_stale_removal) { + info->route_sync_done_time = monotime(NULL); + if (info->t_stale_removal || zrouter.graceful_restart) { struct vrf *vrf = vrf_lookup_by_id(info->vrf_id); - LOG_GR("%s: Client %s canceled stale delete timer vrf %s(%d)", + LOG_GR("%s: Client %s route update complete for all AFI/SAFI in vrf %s(%d)", __func__, zebra_route_string(client->proto), VRF_LOGNAME(vrf), info->vrf_id); EVENT_OFF(info->t_stale_removal); @@ -654,7 +684,7 @@ static void zebra_gr_process_client_stale_routes(struct zserv *client, } void zebra_gr_process_client(afi_t afi, vrf_id_t vrf_id, uint8_t proto, - uint8_t instance) + uint8_t instance, time_t restart_time) { struct zserv *client = zserv_find_client(proto, instance); struct client_gr_info *info = NULL; @@ -676,6 +706,7 @@ void zebra_gr_process_client(afi_t afi, vrf_id_t vrf_id, uint8_t proto, gac->afi = afi; gac->proto = proto; gac->instance = instance; + gac->restart_time = restart_time; event_add_event(zrouter.master, zebra_gr_delete_stale_route_table_afi, gac, 0, &gac->t_gac); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 5b95d8668af0..b176ea2fe6c5 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -3159,6 +3159,7 @@ struct meta_q_gr_run { vrf_id_t vrf_id; uint8_t proto; uint8_t instance; + time_t restart_time; }; static void process_subq_gr_run(struct listnode *lnode) @@ -3166,7 +3167,7 @@ static void process_subq_gr_run(struct listnode *lnode) struct meta_q_gr_run *gr_run = listgetdata(lnode); zebra_gr_process_client(gr_run->afi, gr_run->vrf_id, gr_run->proto, - gr_run->instance); + gr_run->instance, gr_run->restart_time); XFREE(MTYPE_WQ_WRAPPER, gr_run); } @@ -4266,7 +4267,8 @@ static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data) return 0; } -int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, uint8_t instance) +int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, uint8_t instance, + time_t restart_time) { struct meta_q_gr_run *gr_run; @@ -4276,6 +4278,7 @@ int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, uint8_t instance) gr_run->proto = proto; gr_run->vrf_id = vrf_id; gr_run->instance = instance; + gr_run->restart_time = restart_time; return mq_add_handler(gr_run, rib_meta_queue_gr_run_add); } @@ -4694,6 +4697,10 @@ void rib_sweep_route(struct event *t) struct vrf *vrf; struct zebra_vrf *zvrf; + zrouter.rib_sweep_time = monotime(NULL); + /* TODO: Change to debug */ + zlog_info("Sweeping the RIB for stale routes..."); + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { if ((zvrf = vrf->info) == NULL) continue; diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index 3fd4e6eb1f63..8d6b2f347651 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -238,7 +238,7 @@ void zebra_router_terminate(void) { struct zebra_router_table *zrt, *tmp; - EVENT_OFF(zrouter.sweeper); + EVENT_OFF(zrouter.t_rib_sweep); RB_FOREACH_SAFE (zrt, zebra_router_table_head, &zrouter.tables, tmp) zebra_router_free_table(zrt); diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index 304170743994..c86c6be1ef56 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -191,10 +191,16 @@ struct zebra_router { enum multicast_mode ipv4_multicast_mode; /* - * Time for when we sweep the rib from old routes + * zebra start time and time of sweeping RIB of old routes */ time_t startup_time; - struct event *sweeper; + time_t rib_sweep_time; + + /* FRR fast/graceful restart info */ + bool graceful_restart; + int gr_cleanup_time; +#define ZEBRA_GR_DEFAULT_RIB_SWEEP_TIME 500 + struct event *t_rib_sweep; /* * The hash of nexthop groups associated with this router diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index c31218a7c367..858e503031a4 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3825,6 +3825,20 @@ DEFUN (show_zebra, struct vrf *vrf; struct ttable *table = ttable_new(&ttable_styles[TTSTYLE_BLANK]); char *out; + char timebuf[MONOTIME_STRLEN]; + + time_to_string(zrouter.startup_time, timebuf); + vty_out(vty, "Zebra started%s at time %s", + zrouter.graceful_restart ? " gracefully" : "", timebuf); + + if (zrouter.t_rib_sweep) + vty_out(vty, + "Zebra RIB sweep timer running, remaining time %lds\n", + event_timer_remain_second(zrouter.t_rib_sweep)); + else { + time_to_string(zrouter.rib_sweep_time, timebuf); + vty_out(vty, "Zebra RIB sweep happened at %s", timebuf); + } ttable_rowseps(table, 0, BOTTOM, true, '-'); ttable_add_row(table, "OS|%s(%s)", cmd_system_get(), cmd_release_get()); diff --git a/zebra/zserv.c b/zebra/zserv.c index 27668534ee99..a731f7f278fd 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1031,6 +1031,7 @@ static char *zserv_time_buf(time_t *time1, char *buf, int buflen) /* Display client info details */ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) { + struct client_gr_info *info; char cbuf[ZEBRA_TIME_BUF], rbuf[ZEBRA_TIME_BUF]; char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF]; time_t connect_time, last_read_time, last_write_time; @@ -1125,6 +1126,45 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) vty_out(vty, "ES-EVI %-12u%-12u%-12u\n", client->local_es_evi_add_cnt, 0, client->local_es_evi_del_cnt); vty_out(vty, "Errors: %u\n", client->error_cnt); + + TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) { + afi_t afi; + bool route_sync_done = true; + char timebuf[MONOTIME_STRLEN]; + + vty_out(vty, "VRF : %s\n", vrf_id_to_name(info->vrf_id)); + vty_out(vty, "Capabilities : "); + switch (info->capabilities) { + case ZEBRA_CLIENT_GR_CAPABILITIES: + vty_out(vty, "Graceful Restart\n"); + break; + case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE: + case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING: + case ZEBRA_CLIENT_GR_DISABLE: + case ZEBRA_CLIENT_RIB_STALE_TIME: + vty_out(vty, "None\n"); + break; + } + for (afi = AFI_IP; afi < AFI_MAX; afi++) { + if (info->af_enabled[afi]) { + if (info->route_sync[afi]) + vty_out(vty, + "AFI %d enabled, route sync DONE\n", + afi); + else { + vty_out(vty, + "AFI %d enabled, route sync NOT DONE\n", + afi); + route_sync_done = false; + } + } + } + if (route_sync_done) { + time_to_string(info->route_sync_done_time, timebuf); + vty_out(vty, "Route sync finished at %s", timebuf); + } + } + vty_out(vty, "Input Fifo: %zu:%zu Output Fifo: %zu:%zu\n", client->ibuf_fifo->count, client->ibuf_fifo->max_count, client->obuf_fifo->count, client->obuf_fifo->max_count); diff --git a/zebra/zserv.h b/zebra/zserv.h index 57d673060fe7..87d2b4adbf81 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -64,6 +64,8 @@ struct client_gr_info { /* Book keeping */ void *stale_client_ptr; struct event *t_stale_removal; + void *client_ptr; + time_t route_sync_done_time; TAILQ_ENTRY(client_gr_info) gr_info; }; From 7bde7a698c416bb4bbfbbc9aee5e52f89257e4cd Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 2 Jul 2024 17:57:06 +0300 Subject: [PATCH 366/472] tests: Add basic BGP per-safi dampening topotest Signed-off-by: Donatas Abraitis --- .../bgp_dampening_per_safi/__init__.py | 0 .../bgp_dampening_per_safi/r1/frr.conf | 13 ++ .../bgp_dampening_per_safi/r2/frr.conf | 17 ++ .../test_bgp_dampening_per_safi.py | 194 ++++++++++++++++++ 4 files changed, 224 insertions(+) create mode 100644 tests/topotests/bgp_dampening_per_safi/__init__.py create mode 100644 tests/topotests/bgp_dampening_per_safi/r1/frr.conf create mode 100644 tests/topotests/bgp_dampening_per_safi/r2/frr.conf create mode 100644 tests/topotests/bgp_dampening_per_safi/test_bgp_dampening_per_safi.py diff --git a/tests/topotests/bgp_dampening_per_safi/__init__.py b/tests/topotests/bgp_dampening_per_safi/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_dampening_per_safi/r1/frr.conf b/tests/topotests/bgp_dampening_per_safi/r1/frr.conf new file mode 100644 index 000000000000..b4e82f581de1 --- /dev/null +++ b/tests/topotests/bgp_dampening_per_safi/r1/frr.conf @@ -0,0 +1,13 @@ +! +int r1-eth0 + ip address 192.168.1.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as external + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + address-family ipv4 unicast + bgp dampening 1 1 1 1 + exit-address-family +! diff --git a/tests/topotests/bgp_dampening_per_safi/r2/frr.conf b/tests/topotests/bgp_dampening_per_safi/r2/frr.conf new file mode 100644 index 000000000000..d68d13d07599 --- /dev/null +++ b/tests/topotests/bgp_dampening_per_safi/r2/frr.conf @@ -0,0 +1,17 @@ +! +int lo + ip address 10.10.10.10/32 +! +int r2-eth0 + ip address 192.168.1.2/24 +! +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as external + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 + ! + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_dampening_per_safi/test_bgp_dampening_per_safi.py b/tests/topotests/bgp_dampening_per_safi/test_bgp_dampening_per_safi.py new file mode 100644 index 000000000000..c8d7e675d103 --- /dev/null +++ b/tests/topotests/bgp_dampening_per_safi/test_bgp_dampening_per_safi.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by +# Donatas Abraitis +# + +import os +import re +import sys +import json +import pytest +import functools + +pytestmark = [pytest.mark.bgpd] + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, get_topogen + + +def setup_module(mod): + topodef = {"s1": ("r1", "r2")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_dampening_per_peer(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + + def _show_dampening_parameters(): + output = json.loads(r1.vtysh_cmd("show ip bgp dampening parameters json")) + expected = { + "halfLifeSecs": 60, + "reusePenalty": 1, + "suppressPenalty": 1, + "maxSuppressTimeSecs": 60, + "maxSuppressPenalty": 2, + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _show_dampening_parameters, + ) + _, result = topotest.run_and_expect(test_func, None, count=15, wait=1) + assert result is None, "Can't show BGP per-safi dampening parameters" + + def _converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't converge" + + #### + # Withdraw 10.10.10.10/32, and check if it's flagged as history. + #### + r2.vtysh_cmd( + """ + configure terminal + router bgp + address-family ipv4 unicast + no redistribute connected + """ + ) + + def _check_bgp_dampening_history(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "dampeningHistoryEntry": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _check_bgp_dampening_history, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "10.10.10.10/32 is not flagged as history entry" + + #### + # Reannounce 10.10.10.10/32, and check if it's flagged as dampened. + #### + r2.vtysh_cmd( + """ + configure terminal + router bgp + address-family ipv4 unicast + redistribute connected + """ + ) + + def _check_bgp_dampening_dampened(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "dampeningSuppressed": True, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _check_bgp_dampening_dampened, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "10.10.10.10/32 is not flagged as dampened entry" + + #### + # Check if the route becomes non-dampened again after some time. + #### + def _check_bgp_dampening_undampened(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast 10.10.10.10/32 json")) + expected = { + "paths": [ + { + "valid": True, + "dampeningHistoryEntry": None, + "dampeningSuppressed": None, + "nexthops": [ + { + "hostname": "r2", + "accessible": True, + } + ], + } + ], + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _check_bgp_dampening_undampened, + ) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=10) + assert result is None, "10.10.10.10/32 is flagged as history/dampened" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From c9426177f6b699f43f299e83bd421633028e5bfb Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 2 Jul 2024 18:35:48 +0300 Subject: [PATCH 367/472] bgpd: Drop memset() before encoding EVPN extended communities memset() is already handled inside the helpers for a particular extended community. Signed-off-by: Donatas Abraitis --- bgpd/bgp_evpn.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 6680b54f7665..e5c7cb3801e8 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1161,7 +1161,6 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, /* Add MAC mobility (sticky) if needed. */ if (attr->sticky) { seqnum = 0; - memset(&ecom_sticky, 0, sizeof(ecom_sticky)); encode_mac_mobility_extcomm(1, seqnum, &eval_sticky); ecom_sticky.size = 1; ecom_sticky.unit_size = ECOMMUNITY_SIZE; @@ -1180,7 +1179,6 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, /* Add default gateway, if needed. */ if (attr->default_gw) { - memset(&ecom_default_gw, 0, sizeof(ecom_default_gw)); encode_default_gw_extcomm(&eval_default_gw); ecom_default_gw.size = 1; ecom_default_gw.unit_size = ECOMMUNITY_SIZE; @@ -1192,7 +1190,6 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, proxy = !!(attr->es_flags & ATTR_ES_PROXY_ADVERT); if (attr->router_flag || proxy) { - memset(&ecom_na, 0, sizeof(ecom_na)); encode_na_flag_extcomm(&eval_na, attr->router_flag, proxy); ecom_na.size = 1; ecom_na.unit_size = ECOMMUNITY_SIZE; From bb637fd82990a9c30819335e64ff0574206dc443 Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Wed, 3 Jul 2024 15:57:01 +0530 Subject: [PATCH 368/472] yang: Corrected typo at yang file Corrected typo at yang file Signed-off-by: y-bharath14 --- yang/frr-route-map.yang | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yang/frr-route-map.yang b/yang/frr-route-map.yang index 26d56acc039b..c875a6ec7f05 100644 --- a/yang/frr-route-map.yang +++ b/yang/frr-route-map.yang @@ -360,16 +360,16 @@ module frr-route-map { case set-min-metric { when "derived-from-or-self(../action, 'set-min-metric')"; - choice minimun-metric-value { + choice minimum-metric-value { description - "Mimimum metric to set or use"; + "Minimum metric to set or use"; case min-metric { leaf min-metric { type uint32 { range "0..4294967295"; } description - "Use the following mimumn metric value"; + "Use the following minimum metric value"; } } } From 266b0619942edd8d838235e14dc0cb71a772f585 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 7 Feb 2024 14:56:15 -0500 Subject: [PATCH 369/472] zebra: Properly note that a nhg's nexthop has gone down Current code when a link is set down is to just mark the nexthop group as not properly setup. Leaving situations where when an interface goes down and show output is entered we see incorrect state. This is true for anything that would be checking those flags at that point in time. Modify the interface down nexthop group code to notice the nexthops appropriately ( and I mean set the appropriate flags ) and to allow a `show ip route` command to actually display what is going on with the nexthops. eva# show ip route 1.0.0.0 Routing entry for 1.0.0.0/32 Known via "sharp", distance 150, metric 0, best Last update 00:00:06 ago * 192.168.44.33, via dummy1, weight 1 * 192.168.45.33, via dummy2, weight 1 sharpd@eva:~/frr1$ sudo ip link set dummy2 down eva# show ip route 1.0.0.0 Routing entry for 1.0.0.0/32 Known via "sharp", distance 150, metric 0, best Last update 00:00:12 ago * 192.168.44.33, via dummy1, weight 1 192.168.45.33, via dummy2 inactive, weight 1 Notice now that the 1.0.0.0/32 route now correctly displays the route for the nexthop group entry. Signed-off-by: Donald Sharp --- .../rt5/step10/show_ip_route.ref | 3 +- zebra/zebra_nhg.c | 28 ++++++++++++++++++- zebra/zebra_vty.c | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref index 06f432c455de..ff8ace25be5d 100644 --- a/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref +++ b/tests/topotests/isis_tilfa_topo1/rt5/step10/show_ip_route.ref @@ -457,8 +457,7 @@ "fib":true, "ip":"10.0.8.6", "afi":"ipv4", - "interfaceName":"eth-rt6", - "active":true + "interfaceName":"eth-rt6" } ] } diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 55920102bb0a..b4e25daad817 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1050,8 +1050,27 @@ static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid) } /* Update validity of nexthops depending on it */ - frr_each(nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) + frr_each (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) { + if (!valid) { + /* + * Grab the first nexthop from the depending nexthop group + * then let's find the nexthop in that group that matches + * my individual nexthop and mark it as no longer ACTIVE + */ + struct nexthop *nexthop = rb_node_dep->nhe->nhg.nexthop; + + while (nexthop) { + if (nexthop_same(nexthop, nhe->nhg.nexthop)) + break; + + nexthop = nexthop->next; + } + + if (nexthop) + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + } zebra_nhg_set_valid(rb_node_dep->nhe, valid); + } } void zebra_nhg_check_valid(struct nhg_hash_entry *nhe) @@ -1059,6 +1078,13 @@ void zebra_nhg_check_valid(struct nhg_hash_entry *nhe) struct nhg_connected *rb_node_dep = NULL; bool valid = false; + /* + * If I have other nhe's depending on me, then this is a + * singleton nhe so set this nexthops flag as appropriate. + */ + if (nhg_connected_tree_count(&nhe->nhg_depends)) + UNSET_FLAG(nhe->nhg.nexthop->flags, NEXTHOP_FLAG_ACTIVE); + /* If anthing else in the group is valid, the group is valid */ frr_each(nhg_connected_tree, &nhe->nhg_depends, rb_node_dep) { if (CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_VALID)) { diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 858e503031a4..5742c38e23ee 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -215,7 +215,7 @@ static char re_status_output_char(const struct route_entry *re, if (is_fib) { star_p = !!CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_FIB); - } else + } else if (CHECK_FLAG(nhop->flags, NEXTHOP_FLAG_ACTIVE)) star_p = true; } From 6952bea5cdd38057bf8c0a5e9c0fbe916dc73953 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 28 Jun 2024 13:22:36 +0200 Subject: [PATCH 370/472] pimd: fix crash on non-existent interface Fix the following crash when pim options are (un)configured on an non-existent interface. > r1(config)# int fgljdsf > r1(config-if)# no ip pim unicast-bsm > vtysh: error reading from pimd: Connection reset by peer (104)Warning: closing connection to pimd because of an I/O error! > #0 raise (sig=) at ../sysdeps/unix/sysv/linux/raise.c:50 > #1 0x00007f70c8f32249 in core_handler (signo=11, siginfo=0x7fffff88e4f0, context=0x7fffff88e3c0) at lib/sigevent.c:258 > #2 > #3 0x0000556cfdd9b16d in lib_interface_pim_address_family_unicast_bsm_modify (args=0x7fffff88f130) at pimd/pim_nb_config.c:1910 > #4 0x00007f70c8efdcb5 in nb_callback_modify (context=0x556d00032b60, nb_node=0x556cffeeb9b0, event=NB_EV_APPLY, dnode=0x556d00031670, resource=0x556d00032b48, errmsg=0x7fffff88f710 "", errmsg_len=8192) > at lib/northbound.c:1538 > #5 0x00007f70c8efe949 in nb_callback_configuration (context=0x556d00032b60, event=NB_EV_APPLY, change=0x556d00032b10, errmsg=0x7fffff88f710 "", errmsg_len=8192) at lib/northbound.c:1888 > #6 0x00007f70c8efee82 in nb_transaction_process (event=NB_EV_APPLY, transaction=0x556d00032b60, errmsg=0x7fffff88f710 "", errmsg_len=8192) at lib/northbound.c:2016 > #7 0x00007f70c8efd658 in nb_candidate_commit_apply (transaction=0x556d00032b60, save_transaction=true, transaction_id=0x0, errmsg=0x7fffff88f710 "", errmsg_len=8192) at lib/northbound.c:1356 > #8 0x00007f70c8efd78e in nb_candidate_commit (context=..., candidate=0x556cffeb0e80, save_transaction=true, comment=0x0, transaction_id=0x0, errmsg=0x7fffff88f710 "", errmsg_len=8192) at lib/northbound.c:1389 > #9 0x00007f70c8f03e58 in nb_cli_classic_commit (vty=0x556d00025a80) at lib/northbound_cli.c:51 > #10 0x00007f70c8f043f8 in nb_cli_apply_changes_internal (vty=0x556d00025a80, > xpath_base=0x7fffff893bb0 "/frr-interface:lib/interface[name='fgljdsf']/frr-pim:pim/address-family[address-family='frr-routing:ipv4']", clear_pending=false) at lib/northbound_cli.c:178 > #11 0x00007f70c8f0475d in nb_cli_apply_changes (vty=0x556d00025a80, xpath_base_fmt=0x556cfdde9fe0 "./frr-pim:pim/address-family[address-family='%s']") at lib/northbound_cli.c:234 > #12 0x0000556cfdd8298f in pim_process_no_unicast_bsm_cmd (vty=0x556d00025a80) at pimd/pim_cmd_common.c:3493 > #13 0x0000556cfddcf782 in no_ip_pim_ucast_bsm (self=0x556cfde40b20 , vty=0x556d00025a80, argc=4, argv=0x556d00031500) at pimd/pim_cmd.c:4950 > #14 0x00007f70c8e942f0 in cmd_execute_command_real (vline=0x556d00032070, vty=0x556d00025a80, cmd=0x0, up_level=0) at lib/command.c:1002 > #15 0x00007f70c8e94451 in cmd_execute_command (vline=0x556d00032070, vty=0x556d00025a80, cmd=0x0, vtysh=0) at lib/command.c:1061 > #16 0x00007f70c8e9499f in cmd_execute (vty=0x556d00025a80, cmd=0x556d00030320 "no ip pim unicast-bsm", matched=0x0, vtysh=0) at lib/command.c:1227 > #17 0x00007f70c8f51e44 in vty_command (vty=0x556d00025a80, buf=0x556d00030320 "no ip pim unicast-bsm") at lib/vty.c:616 > #18 0x00007f70c8f53bdd in vty_execute (vty=0x556d00025a80) at lib/vty.c:1379 > #19 0x00007f70c8f55d59 in vtysh_read (thread=0x7fffff896600) at lib/vty.c:2374 > #20 0x00007f70c8f4b209 in event_call (thread=0x7fffff896600) at lib/event.c:2011 > #21 0x00007f70c8ed109e in frr_run (master=0x556cffdb4ea0) at lib/libfrr.c:1217 > #22 0x0000556cfdddec12 in main (argc=2, argv=0x7fffff896828, envp=0x7fffff896840) at pimd/pim_main.c:165 > (gdb) f 3 > #3 0x0000556cfdd9b16d in lib_interface_pim_address_family_unicast_bsm_modify (args=0x7fffff88f130) at pimd/pim_nb_config.c:1910 > 1910 pim_ifp->ucast_bsm_accept = > (gdb) list > 1905 case NB_EV_ABORT: > 1906 break; > 1907 case NB_EV_APPLY: > 1908 ifp = nb_running_get_entry(args->dnode, NULL, true); > 1909 pim_ifp = ifp->info; > 1910 pim_ifp->ucast_bsm_accept = > 1911 yang_dnode_get_bool(args->dnode, NULL); > 1912 > 1913 break; > 1914 } > (gdb) p pim_ifp > $1 = (struct pim_interface *) 0x0 Fixes: 3bb513c399 ("lib: adapt to version 2 of libyang") Signed-off-by: Louis Scalbert --- pimd/pim_nb_config.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index 4f1a4a18524e..be0be8588b30 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -1504,11 +1504,19 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_re */ int lib_interface_pim_address_family_create(struct nb_cb_create_args *args) { + struct interface *ifp; + switch (args->event) { case NB_EV_VALIDATE: - case NB_EV_PREPARE: - case NB_EV_ABORT: case NB_EV_APPLY: + case NB_EV_ABORT: + break; + case NB_EV_PREPARE: + ifp = nb_running_get_entry(args->dnode, NULL, true); + if (ifp->info) + return NB_OK; + + pim_if_new(ifp, false, false, false, false); break; } From d4c577e483504d916629dd095d256030884231a7 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 2 Jul 2024 19:31:14 +0300 Subject: [PATCH 371/472] bgpd: Move sticky, default_gw, router_flag into a single flags variable Instead of using 3 uint8_t variables under struct attr, let's use a single uint8_t as the flags. Saving 2-bytes. Not a big deal, but it's even easier to track EVPN-related flags/variables. Signed-off-by: Donatas Abraitis --- bgpd/bgp_attr.c | 12 ++++------ bgpd/bgp_attr.h | 14 +++++------ bgpd/bgp_attr_evpn.c | 21 ++++++++--------- bgpd/bgp_attr_evpn.h | 8 +++---- bgpd/bgp_evpn.c | 52 ++++++++++++++++++++++------------------- bgpd/bgp_evpn_private.h | 2 +- bgpd/bgp_route.c | 11 ++++++--- 7 files changed, 61 insertions(+), 59 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 18c7b13535d0..3eb39d800946 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -2575,7 +2575,6 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) struct peer *const peer = args->peer; struct attr *const attr = args->attr; const bgp_size_t length = args->length; - uint8_t sticky = 0; bool proxy = false; struct ecommunity *ecomm; @@ -2605,21 +2604,20 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args) attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg); /* Extract MAC mobility sequence number, if any. */ - attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky); - attr->sticky = sticky; + attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr); /* Check if this is a Gateway MAC-IP advertisement */ - attr->default_gw = bgp_attr_default_gw(attr); + bgp_attr_default_gw(attr); /* Handle scenario where router flag ecommunity is not * set but default gw ext community is present. * Use default gateway, set and propogate R-bit. */ - if (attr->default_gw) - attr->router_flag = 1; + if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) + SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER); /* Check EVPN Neighbor advertisement flags, R-bit */ - bgp_attr_evpn_na_flag(attr, &attr->router_flag, &proxy); + bgp_attr_evpn_na_flag(attr, &proxy); if (proxy) attr->es_flags |= ATTR_ES_PROXY_ADVERT; diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index f353e76913a7..3519dc340102 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -197,9 +197,6 @@ struct attr { #define ATTR_ES_L3_NHG_ACTIVE (1 << 6) #define ATTR_ES_L3_NHG (ATTR_ES_L3_NHG_USE | ATTR_ES_L3_NHG_ACTIVE) - /* NA router flag (R-bit) support in EVPN */ - uint8_t router_flag; - /* Distance as applied by Route map */ uint8_t distance; @@ -256,11 +253,12 @@ struct attr { /* MP Nexthop length */ uint8_t mp_nexthop_len; - /* Static MAC for EVPN */ - uint8_t sticky; - - /* Flag for default gateway extended community in EVPN */ - uint8_t default_gw; + /* EVPN flags */ + uint8_t evpn_flags; +#define ATTR_EVPN_FLAG_STICKY (1 << 0) +#define ATTR_EVPN_FLAG_DEFAULT_GW (1 << 1) +/* NA router flag (R-bit) support in EVPN */ +#define ATTR_EVPN_FLAG_ROUTER (1 << 2) /* route tag */ route_tag_t tag; diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index bbc4ba9525d4..086c36f36c7a 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -115,14 +115,14 @@ bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac) /* * return true if attr contains default gw extended community */ -uint8_t bgp_attr_default_gw(struct attr *attr) +void bgp_attr_default_gw(struct attr *attr) { struct ecommunity *ecom; uint32_t i; ecom = bgp_attr_get_ecommunity(attr); if (!ecom || !ecom->size) - return 0; + return; /* If there is a default gw extendd community return true otherwise * return 0 */ @@ -136,10 +136,9 @@ uint8_t bgp_attr_default_gw(struct attr *attr) if ((type == ECOMMUNITY_ENCODE_OPAQUE && sub_type == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW)) - return 1; + SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW); } - - return 0; + UNSET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW); } /* @@ -183,7 +182,7 @@ uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg) * Fetch and return the sequence number from MAC Mobility extended * community, if present, else 0. */ -uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky) +uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr) { struct ecommunity *ecom; uint32_t i; @@ -213,9 +212,9 @@ uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky) flags = *pnt++; if (flags & ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY) - *sticky = 1; + SET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY); else - *sticky = 0; + UNSET_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY); pnt++; pnt = ptr_get_be32(pnt, &seq_num); @@ -229,8 +228,7 @@ uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, uint8_t *sticky) /* * return true if attr contains router flag extended community */ -void bgp_attr_evpn_na_flag(struct attr *attr, - uint8_t *router_flag, bool *proxy) +void bgp_attr_evpn_na_flag(struct attr *attr, bool *proxy) { struct ecommunity *ecom; uint32_t i; @@ -254,7 +252,8 @@ void bgp_attr_evpn_na_flag(struct attr *attr, val = *pnt++; if (val & ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG) - *router_flag = 1; + SET_FLAG(attr->evpn_flags, + ATTR_EVPN_FLAG_ROUTER); if (val & ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG) *proxy = true; diff --git a/bgpd/bgp_attr_evpn.h b/bgpd/bgp_attr_evpn.h index f8d3978b960b..e12fc3a86cc2 100644 --- a/bgpd/bgp_attr_evpn.h +++ b/bgpd/bgp_attr_evpn.h @@ -36,12 +36,10 @@ extern void bgp_add_routermac_ecom(struct attr *attr, extern int bgp_build_evpn_prefix(int type, uint32_t eth_tag, struct prefix *dst); extern bool bgp_attr_rmac(struct attr *attr, struct ethaddr *rmac); -extern uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr, - uint8_t *sticky); -extern uint8_t bgp_attr_default_gw(struct attr *attr); +extern uint32_t bgp_attr_mac_mobility_seqnum(struct attr *attr); +extern void bgp_attr_default_gw(struct attr *attr); -extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag, - bool *proxy); +extern void bgp_attr_evpn_na_flag(struct attr *attr, bool *proxy); extern uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index e5c7cb3801e8..75a7d85e88fc 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1159,7 +1159,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, } /* Add MAC mobility (sticky) if needed. */ - if (attr->sticky) { + if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY)) { seqnum = 0; encode_mac_mobility_extcomm(1, seqnum, &eval_sticky); ecom_sticky.size = 1; @@ -1178,7 +1178,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, } /* Add default gateway, if needed. */ - if (attr->default_gw) { + if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) { encode_default_gw_extcomm(&eval_default_gw); ecom_default_gw.size = 1; ecom_default_gw.unit_size = ECOMMUNITY_SIZE; @@ -1189,8 +1189,11 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, } proxy = !!(attr->es_flags & ATTR_ES_PROXY_ADVERT); - if (attr->router_flag || proxy) { - encode_na_flag_extcomm(&eval_na, attr->router_flag, proxy); + if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER) || proxy) { + encode_na_flag_extcomm(&eval_na, + CHECK_FLAG(attr->evpn_flags, + ATTR_EVPN_FLAG_ROUTER), + proxy); ecom_na.size = 1; ecom_na.unit_size = ECOMMUNITY_SIZE; ecom_na.val = (uint8_t *)eval_na.val; @@ -1275,12 +1278,15 @@ enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn flags = 0; if (pi->sub_type == BGP_ROUTE_IMPORTED) { - if (pi->attr->sticky) + if (CHECK_FLAG(pi->attr->evpn_flags, + ATTR_EVPN_FLAG_STICKY)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY); - if (pi->attr->default_gw) + if (CHECK_FLAG(pi->attr->evpn_flags, + ATTR_EVPN_FLAG_DEFAULT_GW)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); if (is_evpn_prefix_ipaddr_v6(p) && - pi->attr->router_flag) + CHECK_FLAG(pi->attr->evpn_flags, + ATTR_EVPN_FLAG_ROUTER)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); seq = mac_mobility_seqnum(pi->attr); @@ -1834,7 +1840,8 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, *active_on_peer = true; } - if (second_best_path->attr->router_flag) + if (CHECK_FLAG(second_best_path->attr->evpn_flags, + ATTR_EVPN_FLAG_ROUTER)) *peer_router = true; /* we use both proxy and non-proxy imports to @@ -1934,7 +1941,6 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, struct attr local_attr; struct bgp_labels bgp_labels = {}; int route_change = 1; - uint8_t sticky = 0; const struct prefix_evpn *evp; *pi = NULL; @@ -1966,9 +1972,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, local_attr = *attr; /* Extract MAC mobility sequence number, if any. */ - local_attr.mm_seqnum = - bgp_attr_mac_mobility_seqnum(&local_attr, &sticky); - local_attr.sticky = sticky; + local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum(&local_attr); /* Add (or update) attribute to hash. */ attr_new = bgp_attr_intern(&local_attr); @@ -2063,9 +2067,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, BGP_PATH_ATTR_CHANGED); /* Extract MAC mobility sequence number, if any. */ - local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum( - &local_attr, &sticky); - local_attr.sticky = sticky; + local_attr.mm_seqnum = + bgp_attr_mac_mobility_seqnum(&local_attr); attr_new = bgp_attr_intern(&local_attr); @@ -2198,10 +2201,12 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, attr.nexthop = vpn->originator_ip; attr.mp_nexthop_global_in = vpn->originator_ip; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0; - attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0; - attr.router_flag = CHECK_FLAG(flags, - ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? 1 : 0; + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY)) + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_STICKY); + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW); + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG)) + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER); if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) attr.es_flags |= ATTR_ES_PROXY_ADVERT; @@ -2503,13 +2508,12 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, attr.nexthop = vpn->originator_ip; attr.mp_nexthop_global_in = vpn->originator_ip; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr.sticky = (local_pi->attr->sticky) ? 1 : 0; - attr.router_flag = (local_pi->attr->router_flag) ? 1 : 0; + attr.evpn_flags = local_pi->attr->evpn_flags; attr.es_flags = local_pi->attr->es_flags; - if (local_pi->attr->default_gw) { - attr.default_gw = 1; + if (CHECK_FLAG(local_pi->attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) { + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW); if (is_evpn_prefix_ipaddr_v6(&evp)) - attr.router_flag = 1; + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER); } memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t)); bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h index 07bba9b42684..b05df3d82ae7 100644 --- a/bgpd/bgp_evpn_private.h +++ b/bgpd/bgp_evpn_private.h @@ -382,7 +382,7 @@ static inline void encode_mac_mobility_extcomm(int static_mac, uint32_t seq, } static inline void encode_na_flag_extcomm(struct ecommunity_val *eval, - uint8_t na_flag, bool proxy) + bool na_flag, bool proxy) { memset(eval, 0, sizeof(*eval)); eval->val[0] = ECOMMUNITY_ENCODE_EVPN; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 6a35935c7e26..2a9fc6ce0da2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -851,8 +851,13 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, * with the * sticky flag. */ - if (newattr->sticky != existattr->sticky) { - if (newattr->sticky && !existattr->sticky) { + bool new_sticky = CHECK_FLAG(newattr->evpn_flags, + ATTR_EVPN_FLAG_STICKY); + bool exist_sticky = CHECK_FLAG(existattr->evpn_flags, + ATTR_EVPN_FLAG_STICKY); + + if (new_sticky != exist_sticky) { + if (new_sticky && !exist_sticky) { *reason = bgp_path_selection_evpn_sticky_mac; if (debug) zlog_debug( @@ -861,7 +866,7 @@ int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new, return 1; } - if (!newattr->sticky && existattr->sticky) { + if (!new_sticky && exist_sticky) { *reason = bgp_path_selection_evpn_sticky_mac; if (debug) zlog_debug( From 0dfe25697f5299326046fcfb66f2c6beca7c423c Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 4 Jul 2024 14:42:19 +0300 Subject: [PATCH 372/472] bgpd: Implement `neighbor X remote-as auto` In some cases (large scale) it's desired to avoid changing configurations, but let the BGP to automatically handle ASN changes. `auto` means the peering can be iBGP or eBGP. It will be automatically detected and adjusted from the OPEN message. Signed-off-by: Donatas Abraitis --- bgpd/bgp_attr.c | 2 + bgpd/bgp_packet.c | 8 ++ bgpd/bgp_updgrp.c | 7 +- bgpd/bgp_vty.c | 62 ++++++--- bgpd/bgpd.c | 25 ++-- bgpd/bgpd.h | 10 +- doc/user/bgp.rst | 6 +- .../topotests/bgp_remote_as_auto/__init__.py | 0 .../topotests/bgp_remote_as_auto/r1/frr.conf | 17 +++ .../topotests/bgp_remote_as_auto/r2/frr.conf | 10 ++ .../topotests/bgp_remote_as_auto/r3/frr.conf | 10 ++ .../test_bgp_remote_as_auto.py | 130 ++++++++++++++++++ 12 files changed, 251 insertions(+), 36 deletions(-) create mode 100644 tests/topotests/bgp_remote_as_auto/__init__.py create mode 100644 tests/topotests/bgp_remote_as_auto/r1/frr.conf create mode 100644 tests/topotests/bgp_remote_as_auto/r2/frr.conf create mode 100644 tests/topotests/bgp_remote_as_auto/r3/frr.conf create mode 100644 tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 18c7b13535d0..f2f7cfa93da5 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -4468,6 +4468,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer, bgp_packet_mpattr_end(s, mpattrlen_pos); } + (void)peer_sort(peer); + /* Origin attribute. */ stream_putc(s, BGP_ATTR_FLAG_TRANS); stream_putc(s, BGP_ATTR_ORIGIN); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 9a047b9d456f..4625f15778a2 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -1977,6 +1977,14 @@ static int bgp_open_receive(struct peer_connection *connection, BGP_NOTIFY_OPEN_BAD_PEER_AS, notify_data_remote_as, 2); return BGP_Stop; + } else if (peer->as_type == AS_AUTO) { + if (remote_as == peer->bgp->as) { + peer->as = peer->local_as; + SET_FLAG(peer->as_type, AS_INTERNAL); + } else { + peer->as = remote_as; + SET_FLAG(peer->as_type, AS_EXTERNAL); + } } else if (peer->as_type == AS_INTERNAL) { if (remote_as != peer->bgp->as) { if (bgp_debug_neighbor_events(peer)) diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c index 124e7a388b82..b717793a4568 100644 --- a/bgpd/bgp_updgrp.c +++ b/bgpd/bgp_updgrp.c @@ -343,7 +343,12 @@ static unsigned int updgrp_hash_key_make(const void *p) key = 0; - key = jhash_1word(peer->sort, key); /* EBGP or IBGP */ + /* `remote-as auto` technically uses identical peer->sort. + * After OPEN message is parsed, this is updated accordingly, but + * we need to call the peer_sort() here also to properly create + * separate subgroups. + */ + key = jhash_1word(peer_sort((struct peer *)peer), key); key = jhash_1word(peer->sub_sort, key); /* OAD */ key = jhash_1word((peer->flags & PEER_UPDGRP_FLAGS), key); key = jhash_1word((flags & PEER_UPDGRP_AF_FLAGS), key); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index e9a79766ec84..13911b687938 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -4871,6 +4871,9 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str, } else if (as_str[0] == 'e') { as = 0; as_type = AS_EXTERNAL; + } else if (as_str[0] == 'a') { + as = 0; + as_type = AS_AUTO; } else if (!asn_str2asn(as_str, &as)) as_type = AS_UNSPECIFIED; @@ -4976,13 +4979,14 @@ ALIAS(no_bgp_shutdown, no_bgp_shutdown_msg_cmd, DEFUN (neighbor_remote_as, neighbor_remote_as_cmd, - "neighbor remote-as ", + "neighbor remote-as ", NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Specify a BGP neighbor\n" AS_STR "Internal BGP peer\n" - "External BGP peer\n") + "External BGP peer\n" + "Automatically detect remote ASN\n") { int idx_peer = 1; int idx_remote_as = 3; @@ -5054,6 +5058,8 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, as_type = AS_INTERNAL; } else if (as_str[0] == 'e') { as_type = AS_EXTERNAL; + } else if (as_str[0] == 'a') { + as_type = AS_AUTO; } else { /* Get AS number. */ if (asn_str2asn(as_str, &as)) @@ -5170,14 +5176,15 @@ DEFUN (neighbor_interface_config_v6only, DEFUN (neighbor_interface_config_remote_as, neighbor_interface_config_remote_as_cmd, - "neighbor WORD interface remote-as ", + "neighbor WORD interface remote-as ", NEIGHBOR_STR "Interface name or neighbor tag\n" "Enable BGP on interface\n" "Specify a BGP neighbor\n" AS_STR "Internal BGP peer\n" - "External BGP peer\n") + "External BGP peer\n" + "Automatically detect remote ASN\n") { int idx_word = 1; int idx_remote_as = 4; @@ -5187,7 +5194,7 @@ DEFUN (neighbor_interface_config_remote_as, DEFUN (neighbor_interface_v6only_config_remote_as, neighbor_interface_v6only_config_remote_as_cmd, - "neighbor WORD interface v6only remote-as ", + "neighbor WORD interface v6only remote-as ", NEIGHBOR_STR "Interface name or neighbor tag\n" "Enable BGP with v6 link-local only\n" @@ -5195,7 +5202,8 @@ DEFUN (neighbor_interface_v6only_config_remote_as, "Specify a BGP neighbor\n" AS_STR "Internal BGP peer\n" - "External BGP peer\n") + "External BGP peer\n" + "Automatically detect remote ASN\n") { int idx_word = 1; int idx_remote_as = 5; @@ -5232,14 +5240,15 @@ DEFUN (neighbor_peer_group, DEFUN (no_neighbor, no_neighbor_cmd, - "no neighbor [remote-as <(1-4294967295)|internal|external>]>", + "no neighbor [remote-as <(1-4294967295)|internal|external|auto>]>", NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Specify a BGP neighbor\n" AS_STR "Internal BGP peer\n" - "External BGP peer\n") + "External BGP peer\n" + "Automatically detect remote ASN\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_peer = 2; @@ -5310,7 +5319,7 @@ DEFUN (no_neighbor, DEFUN (no_neighbor_interface_config, no_neighbor_interface_config_cmd, - "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]", + "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external|auto>]", NO_STR NEIGHBOR_STR "Interface name\n" @@ -5321,7 +5330,8 @@ DEFUN (no_neighbor_interface_config, "Specify a BGP neighbor\n" AS_STR "Internal BGP peer\n" - "External BGP peer\n") + "External BGP peer\n" + "Automatically detect remote ASN\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_word = 2; @@ -5378,14 +5388,15 @@ DEFUN (no_neighbor_peer_group, DEFUN (no_neighbor_interface_peer_group_remote_as, no_neighbor_interface_peer_group_remote_as_cmd, - "no neighbor WORD remote-as ", + "no neighbor WORD remote-as ", NO_STR NEIGHBOR_STR "Interface name or neighbor tag\n" "Specify a BGP neighbor\n" AS_STR "Internal BGP peer\n" - "External BGP peer\n") + "External BGP peer\n" + "Automatically detect remote ASN\n") { VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_word = 2; @@ -11887,7 +11898,7 @@ static bool bgp_show_summary_is_peer_filtered(struct peer *peer, /* filter remote-as (internal|external) */ if (as_type != AS_UNSPECIFIED) { if (peer->as_type == AS_SPECIFIED) { - if (as_type == AS_INTERNAL) { + if (CHECK_FLAG(as_type, AS_INTERNAL)) { if (peer->as != peer->local_as) return true; } else if (peer->as == peer->local_as) @@ -12879,6 +12890,8 @@ DEFPY(show_ip_bgp_summary, show_ip_bgp_summary_cmd, as_type = AS_INTERNAL; else if (argv[idx + 1]->arg[0] == 'e') as_type = AS_EXTERNAL; + else if (argv[idx + 1]->arg[0] == 'a') + as_type = AS_AUTO; else if (!asn_str2asn(argv[idx + 1]->arg, &as)) { vty_out(vty, "%% Invalid neighbor remote-as value: %s\n", @@ -14002,9 +14015,10 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, json_object_boolean_true_add(json_neigh, "localAsReplaceAs"); } else { - if ((p->as_type == AS_SPECIFIED) || - (p->as_type == AS_EXTERNAL) || - (p->as_type == AS_INTERNAL)) { + if (p->as_type == AS_SPECIFIED || + CHECK_FLAG(p->as_type, AS_AUTO) || + CHECK_FLAG(p->as_type, AS_EXTERNAL) || + CHECK_FLAG(p->as_type, AS_INTERNAL)) { vty_out(vty, "remote AS "); vty_out(vty, ASN_FORMAT(bgp->asnotation), &p->as); vty_out(vty, ", "); @@ -14023,7 +14037,7 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, : ""); } /* peer type internal or confed-internal */ - if ((p->as == p->local_as) || (p->as_type == AS_INTERNAL)) { + if ((p->as == p->local_as) || (CHECK_FLAG(p->as_type, AS_INTERNAL))) { if (use_json) { if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) json_object_boolean_true_add( @@ -17011,7 +17025,7 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group, &conf->as); vty_out(vty, "\n"); } - } else if (conf->as_type == AS_INTERNAL) { + } else if (CHECK_FLAG(conf->as_type, AS_INTERNAL)) { if (json) asn_asn2json(json, "remoteAs", group->bgp->as, group->bgp->asnotation); @@ -17023,7 +17037,8 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group, vty_out(vty, "\nBGP peer-group %s\n", group->name); } - if ((group->bgp->as == conf->as) || (conf->as_type == AS_INTERNAL)) { + if ((group->bgp->as == conf->as) || + CHECK_FLAG(conf->as_type, AS_INTERNAL)) { if (json) json_object_string_add(json_peer_group, "type", "internal"); @@ -18525,6 +18540,9 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, } else if (peer->as_type == AS_EXTERNAL) { vty_out(vty, " remote-as external"); if_ras_printed = true; + } else if (CHECK_FLAG(peer->as_type, AS_AUTO)) { + vty_out(vty, " remote-as auto"); + if_ras_printed = true; } vty_out(vty, "\n"); @@ -18547,6 +18565,9 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, vty_out(vty, " neighbor %s remote-as external\n", addr); + } else if (CHECK_FLAG(peer->as_type, AS_AUTO)) { + vty_out(vty, " neighbor %s remote-as auto\n", + addr); } } @@ -18576,6 +18597,9 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, vty_out(vty, " neighbor %s remote-as external\n", addr); + } else if (CHECK_FLAG(peer->as_type, AS_AUTO)) { + vty_out(vty, " neighbor %s remote-as auto\n", + addr); } } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 17d94bd57518..ca752da6b415 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1074,10 +1074,10 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer) /* Peer-group */ if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - if (peer->as_type == AS_INTERNAL) + if (CHECK_FLAG(peer->as_type, AS_INTERNAL)) return BGP_PEER_IBGP; - else if (peer->as_type == AS_EXTERNAL) + if (CHECK_FLAG(peer->as_type, AS_EXTERNAL)) return BGP_PEER_EBGP; else if (peer->as_type == AS_SPECIFIED && peer->as) { @@ -1132,17 +1132,20 @@ static inline enum bgp_peer_sort peer_calc_sort(struct peer *peer) return BGP_PEER_IBGP; else return BGP_PEER_EBGP; - } else if (peer->group->conf->as_type - == AS_INTERNAL) + } else if (CHECK_FLAG(peer->group->conf->as_type, + AS_INTERNAL)) return BGP_PEER_IBGP; else return BGP_PEER_EBGP; } /* no AS information anywhere, let caller know */ return BGP_PEER_UNSPECIFIED; - } else if (peer->as_type != AS_SPECIFIED) - return (peer->as_type == AS_INTERNAL ? BGP_PEER_IBGP - : BGP_PEER_EBGP); + } else if (peer->as_type != AS_SPECIFIED) { + if (CHECK_FLAG(peer->as_type, AS_INTERNAL)) + return BGP_PEER_IBGP; + else if (CHECK_FLAG(peer->as_type, AS_EXTERNAL)) + return BGP_PEER_EBGP; + } return (local_as == 0 ? BGP_PEER_INTERNAL : local_as == peer->as ? BGP_PEER_IBGP @@ -2201,10 +2204,10 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if, } } else { /* internal/external used, compare as-types */ - if (((peer_sort_type == BGP_PEER_IBGP) - && (as_type != AS_INTERNAL)) - || ((peer_sort_type == BGP_PEER_EBGP) - && (as_type != AS_EXTERNAL))) { + if (((peer_sort_type == BGP_PEER_IBGP) && + !CHECK_FLAG(as_type, AS_INTERNAL)) || + ((peer_sort_type == BGP_PEER_EBGP) && + !CHECK_FLAG(as_type, AS_EXTERNAL))) { *as = peer->as; return BGP_ERR_PEER_GROUP_PEER_TYPE_DIFFERENT; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 3c5826113dec..709411b06eb7 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -56,10 +56,12 @@ struct bgp_pbr_config; * behavior * in the system. */ -enum { AS_UNSPECIFIED = 0, - AS_SPECIFIED, - AS_INTERNAL, - AS_EXTERNAL, +enum peer_asn_type { + AS_UNSPECIFIED = 1, + AS_SPECIFIED = 2, + AS_INTERNAL = 4, + AS_EXTERNAL = 8, + AS_AUTO = 16, }; /* Zebra Gracaful Restart states */ diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 98834c7c2349..a569a9af2889 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -1561,6 +1561,10 @@ Defining Peers peers ASN is the same as mine as specified under the :clicmd:`router bgp ASN` command the connection will be denied. +.. clicmd:: neighbor PEER remote-as auto + + The neighbor's ASN is detected automatically from the OPEN message. + .. clicmd:: neighbor PEER oad Mark a peer belonging to the One Administrative Domain. @@ -1699,7 +1703,7 @@ Configuring Peers IPv4 session addresses, see the ``neighbor PEER update-source`` command below. -.. clicmd:: neighbor PEER interface remote-as +.. clicmd:: neighbor PEER interface remote-as Configure an unnumbered BGP peer. ``PEER`` should be an interface name. The session will be established via IPv6 link locals. Use ``internal`` for iBGP diff --git a/tests/topotests/bgp_remote_as_auto/__init__.py b/tests/topotests/bgp_remote_as_auto/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_remote_as_auto/r1/frr.conf b/tests/topotests/bgp_remote_as_auto/r1/frr.conf new file mode 100644 index 000000000000..aec0e76a3fd3 --- /dev/null +++ b/tests/topotests/bgp_remote_as_auto/r1/frr.conf @@ -0,0 +1,17 @@ +! +int r1-eth0 + ip address 192.168.1.1/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + no bgp network import-check + neighbor 192.168.1.2 remote-as auto + neighbor 192.168.1.2 timers 1 3 + neighbor 192.168.1.2 timers connect 1 + neighbor 192.168.1.3 remote-as auto + neighbor 192.168.1.3 timers 1 3 + neighbor 192.168.1.3 timers connect 1 + address-family ipv4 unicast + network 10.0.0.1/32 + exit-address-family +! diff --git a/tests/topotests/bgp_remote_as_auto/r2/frr.conf b/tests/topotests/bgp_remote_as_auto/r2/frr.conf new file mode 100644 index 000000000000..f8d19a0bfd56 --- /dev/null +++ b/tests/topotests/bgp_remote_as_auto/r2/frr.conf @@ -0,0 +1,10 @@ +! +int r2-eth0 + ip address 192.168.1.2/24 +! +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as auto + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 +! diff --git a/tests/topotests/bgp_remote_as_auto/r3/frr.conf b/tests/topotests/bgp_remote_as_auto/r3/frr.conf new file mode 100644 index 000000000000..fc6862764f4d --- /dev/null +++ b/tests/topotests/bgp_remote_as_auto/r3/frr.conf @@ -0,0 +1,10 @@ +! +int r3-eth0 + ip address 192.168.1.3/24 +! +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as auto + neighbor 192.168.1.1 timers 1 3 + neighbor 192.168.1.1 timers connect 1 +! diff --git a/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py b/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py new file mode 100644 index 000000000000..b932920e09d4 --- /dev/null +++ b/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# Copyright (c) 2024 by +# Donatas Abraitis +# + +import os +import re +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, get_topogen + +pytestmark = [pytest.mark.bgpd] + + +def setup_module(mod): + topodef = {"s1": ("r1", "r2", "r3")} + tgen = Topogen(topodef, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_remote_as_auto(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + r3 = tgen.gears["r3"] + + def _bgp_converge(): + output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast summary json")) + expected = { + "peers": { + "192.168.1.2": { + "hostname": "r2", + "remoteAs": 65001, + "localAs": 65001, + "state": "Established", + }, + "192.168.1.3": { + "hostname": "r3", + "remoteAs": 65003, + "localAs": 65001, + "state": "Established", + }, + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see automatic iBGP/eBGP peerings" + + def _bgp_converge_internal(): + output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast 10.0.0.1/32 json")) + expected = { + "paths": [ + { + "aspath": { + "string": "Local", + }, + "valid": True, + "peer": { + "hostname": "r1", + "type": "internal", + }, + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge_internal, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see automatic iBGP peering" + + def _bgp_converge_external(): + output = json.loads(r3.vtysh_cmd("show bgp ipv4 unicast 10.0.0.1/32 json")) + expected = { + "paths": [ + { + "aspath": { + "string": "65001", + }, + "valid": True, + "peer": { + "hostname": "r1", + "type": "external", + }, + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge_external, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see automatic eBGP peering" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From 7f2a9114af2584c420f8c98072693b9ce2cad859 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 18 Jun 2024 17:40:08 +0200 Subject: [PATCH 373/472] sharpd: fix set ZAPI_MESSAGE_NEXTHOP in nhg only when nexthops used The ZAPI_MESSAGE_NEXTHOP flag is systematically set, even if the route message does not include any nexthops. Limit the usage of this value only when nexthops are present. Fixes: 8a71d93d85a6 ("sharpd: Add Super Happy Advanced Routing Protocol") Signed-off-by: Philippe Guibert --- sharpd/sharp_zebra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 133da918fa1a..1048436b4313 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -247,12 +247,12 @@ static bool route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance, memcpy(&api.prefix, p, sizeof(*p)); api.flags = flags; - SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); /* Only send via ID if nhgroup has been successfully installed */ if (nhgid && sharp_nhgroup_id_is_installed(nhgid)) { zapi_route_set_nhg_id(&api, &nhgid); } else { + SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); for (ALL_NEXTHOPS_PTR(nhg, nh)) { /* Check if we set a VNI label */ if (nh->nh_label && From 0ed36e44f8bf3c866d99ec549f7ed041af62e8a5 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 4 Jul 2024 23:07:01 +0300 Subject: [PATCH 374/472] bgpd: Convert int to enum peer_asn_type Signed-off-by: Donatas Abraitis --- bgpd/bgp_evpn_vty.c | 2 +- bgpd/bgp_vty.c | 23 ++++++++++++----------- bgpd/bgp_vty.h | 5 +++-- bgpd/bgpd.c | 12 ++++++------ bgpd/bgpd.h | 17 +++++++++-------- 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 846a82ba905d..c28cdb4a6521 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -4840,7 +4840,7 @@ DEFUN(show_bgp_l2vpn_evpn_summary, show_bgp_l2vpn_evpn_summary_cmd, char *vrf = NULL; char *neighbor = NULL; as_t as = 0; /* 0 means AS filter not set */ - int as_type = AS_UNSPECIFIED; + enum peer_asn_type as_type = AS_UNSPECIFIED; uint16_t show_flags = 0; if (argv_find(argv, argc, "vrf", &idx_vrf)) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 13911b687938..0ef135183540 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -4862,7 +4862,7 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str, VTY_DECLVAR_CONTEXT(bgp, bgp); int ret; as_t as; - int as_type = AS_SPECIFIED; + enum peer_asn_type as_type = AS_SPECIFIED; union sockunion su; if (as_str[0] == 'i') { @@ -5041,7 +5041,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, { VTY_DECLVAR_CONTEXT(bgp, bgp); as_t as = 0; - int as_type = AS_UNSPECIFIED; + enum peer_asn_type as_type = AS_UNSPECIFIED; struct peer *peer; struct peer_group *group; int ret = 0; @@ -11887,7 +11887,8 @@ static char *bgp_peer_description_stripped(char *desc, uint32_t size) /* Determine whether var peer should be filtered out of the summary. */ static bool bgp_show_summary_is_peer_filtered(struct peer *peer, - struct peer *fpeer, int as_type, + struct peer *fpeer, + enum peer_asn_type as_type, as_t as) { @@ -11921,8 +11922,8 @@ static bool bgp_show_summary_is_peer_filtered(struct peer *peer, * whitespaces and the whole output will be tricky. */ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, - struct peer *fpeer, int as_type, as_t as, - uint16_t show_flags) + struct peer *fpeer, enum peer_asn_type as_type, + as_t as, uint16_t show_flags) { struct peer *peer; struct listnode *node, *nnode; @@ -12729,10 +12730,9 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi, } static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi, - safi_t safi, - const char *neighbor, - int as_type, as_t as, - uint16_t show_flags) + safi_t safi, const char *neighbor, + enum peer_asn_type as_type, + as_t as, uint16_t show_flags) { struct listnode *node, *nnode; struct bgp *bgp; @@ -12774,8 +12774,9 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi, } int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, - safi_t safi, const char *neighbor, int as_type, - as_t as, uint16_t show_flags) + safi_t safi, const char *neighbor, + enum peer_asn_type as_type, as_t as, + uint16_t show_flags) { struct bgp *bgp; bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON); diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 6d86f6ba086b..f88f5c812569 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -161,8 +161,9 @@ extern int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty, int bgp_vty_find_and_parse_bgp(struct vty *vty, struct cmd_token **argv, int argc, struct bgp **bgp, bool use_json); extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi, - safi_t safi, const char *neighbor, int as_type, - as_t as, uint16_t show_flags); + safi_t safi, const char *neighbor, + enum peer_asn_type as_type, as_t as, + uint16_t show_flags); extern bool peergroup_flag_check(struct peer *peer, uint64_t flag); extern bool peergroup_af_flag_check(struct peer *peer, afi_t afi, safi_t safi, uint64_t flag); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index ca752da6b415..3810413adcf0 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1952,7 +1952,7 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp) */ struct peer *peer_create(union sockunion *su, const char *conf_if, struct bgp *bgp, as_t local_as, as_t remote_as, - int as_type, struct peer_group *group, + enum peer_asn_type as_type, struct peer_group *group, bool config_node, const char *as_str) { int active; @@ -2084,7 +2084,7 @@ bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi) } /* Change peer's AS number. */ -void peer_as_change(struct peer *peer, as_t as, int as_specified, +void peer_as_change(struct peer *peer, as_t as, enum peer_asn_type as_type, const char *as_str) { enum bgp_peer_sort origtype, newtype; @@ -2100,13 +2100,13 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified, } origtype = peer_sort_lookup(peer); peer->as = as; - if (as_specified == AS_SPECIFIED && as_str) { + if (as_type == AS_SPECIFIED && as_str) { if (peer->as_pretty) XFREE(MTYPE_BGP_NAME, peer->as_pretty); peer->as_pretty = XSTRDUP(MTYPE_BGP_NAME, as_str); } else if (peer->as_type == AS_UNSPECIFIED && peer->as_pretty) XFREE(MTYPE_BGP_NAME, peer->as_pretty); - peer->as_type = as_specified; + peer->as_type = as_type; if (bgp_config_check(peer->bgp, BGP_CONFIG_CONFEDERATION) && !bgp_confederation_peers_check(peer->bgp, as) @@ -2163,7 +2163,7 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified, /* If peer does not exist, create new one. If peer already exists, set AS number to the peer. */ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if, - as_t *as, int as_type, const char *as_str) + as_t *as, enum peer_asn_type as_type, const char *as_str) { struct peer *peer; as_t local_as; @@ -3028,7 +3028,7 @@ static void peer_group2peer_config_copy(struct peer_group *group, /* Peer group's remote AS configuration. */ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as, - int as_type, const char *as_str) + enum peer_asn_type as_type, const char *as_str) { struct peer_group *group; struct peer *peer; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 709411b06eb7..95ddba4cddf0 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1248,7 +1248,7 @@ struct peer { struct peer_af *peer_af_array[BGP_AF_MAX]; /* Peer's remote AS number. */ - int as_type; + enum peer_asn_type as_type; as_t as; /* for vty as format */ char *as_pretty; @@ -2283,8 +2283,9 @@ extern bool peer_afc_advertised(struct peer *peer); extern void bgp_recalculate_all_bestpaths(struct bgp *bgp); extern struct peer *peer_create(union sockunion *su, const char *conf_if, struct bgp *bgp, as_t local_as, as_t remote_as, - int as_type, struct peer_group *group, - bool config_node, const char *as_str); + enum peer_asn_type as_type, + struct peer_group *group, bool config_node, + const char *as_str); extern struct peer *peer_create_accept(struct bgp *); extern void peer_xfer_config(struct peer *dst, struct peer *src); extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json, @@ -2357,13 +2358,13 @@ extern void bgp_listen_limit_unset(struct bgp *bgp); extern bool bgp_update_delay_active(struct bgp *); extern bool bgp_update_delay_configured(struct bgp *); extern bool bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi); -extern void peer_as_change(struct peer *peer, as_t as, int as_type, - const char *as_str); +extern void peer_as_change(struct peer *peer, as_t as, + enum peer_asn_type as_type, const char *as_str); extern int peer_remote_as(struct bgp *bgp, union sockunion *su, - const char *conf_if, as_t *as, int as_type, - const char *as_str); + const char *conf_if, as_t *as, + enum peer_asn_type as_type, const char *as_str); extern int peer_group_remote_as(struct bgp *bgp, const char *peer_str, as_t *as, - int as_type, const char *as_str); + enum peer_asn_type as_type, const char *as_str); extern int peer_delete(struct peer *peer); extern void peer_notify_unconfig(struct peer *peer); extern int peer_group_delete(struct peer_group *); From 2aa27ac0e935286ef8ee1f3d8f3dd12960683810 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sun, 16 Jun 2024 13:20:00 +0800 Subject: [PATCH 375/472] ripngd: adjust header for display command Both rip and ripng can import routes from other protocols, e.g. ISIS. But their header doesn't list the description for these abbreviations. Adjust `show ipv6 ripng` 's header for display command. Before: ``` Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP Sub-codes: ``` After: ``` Codes: K - kernel route, C - connected, L - local, S - static, R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, f - OpenFabric, t - Table-Direct Sub-codes: ``` Signed-off-by: anlan_cs --- ripngd/ripngd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index f4dadf377df2..0aa2a9e486fb 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -2070,7 +2070,10 @@ DEFUN (show_ipv6_ripng, /* Header of display. */ vty_out(vty, - "Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP\n" + "Codes: K - kernel route, C - connected, L - local, S - static,\n" + " R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,\n" + " T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,\n" + " f - OpenFabric, t - Table-Direct\n" "Sub-codes:\n" " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n" " (i) - interface, (a/S) - aggregated/Suppressed\n\n" From c0b6095856072604cf7da5864d349a56ec37b272 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Tue, 25 Jun 2024 14:32:44 +0800 Subject: [PATCH 376/472] ripd: adjust header for display command Continue to adjust `show ip rip` 's header for display comand. Signed-off-by: anlan_cs --- ripd/ripd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ripd/ripd.c b/ripd/ripd.c index ab4ffe5a921d..8768819fe26c 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -3054,7 +3054,10 @@ DEFUN (show_ip_rip, } vty_out(vty, - "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP\n" + "Codes: K - kernel route, C - connected, L - local, S - static,\n" + " R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,\n" + " T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR,\n" + " f - OpenFabric, t - Table-Direct\n" "Sub-codes:\n" " (n) - normal, (s) - static, (d) - default, (r) - redistribute,\n" " (i) - interface\n\n" From b707ed8fe9d6e127372dcc94e79e060f866fc528 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Thu, 4 Jul 2024 21:23:08 +0800 Subject: [PATCH 377/472] tests: update tests for ripd and ripngd Since the displayed header of "show ip rip" and "show ipv6 ripng" are changed, we should update tests of ripd and ripngd. Signed-off-by: anlan_cs --- tests/topotests/rip_topo1/r1/show_ip_rip.ref | 5 ++++- tests/topotests/rip_topo1/r2/show_ip_rip.ref | 5 ++++- tests/topotests/rip_topo1/r3/show_ip_rip.ref | 5 ++++- tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref | 5 ++++- tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref | 5 ++++- tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref | 5 ++++- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/tests/topotests/rip_topo1/r1/show_ip_rip.ref b/tests/topotests/rip_topo1/r1/show_ip_rip.ref index a0b77c886e3b..b49a042dac1f 100644 --- a/tests/topotests/rip_topo1/r1/show_ip_rip.ref +++ b/tests/topotests/rip_topo1/r1/show_ip_rip.ref @@ -1,4 +1,7 @@ -Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP +Codes: K - kernel route, C - connected, L - local, S - static, + R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, + f - OpenFabric, t - Table-Direct Sub-codes: (n) - normal, (s) - static, (d) - default, (r) - redistribute, (i) - interface diff --git a/tests/topotests/rip_topo1/r2/show_ip_rip.ref b/tests/topotests/rip_topo1/r2/show_ip_rip.ref index b61fb45eac5b..d0e7e81bc528 100644 --- a/tests/topotests/rip_topo1/r2/show_ip_rip.ref +++ b/tests/topotests/rip_topo1/r2/show_ip_rip.ref @@ -1,4 +1,7 @@ -Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP +Codes: K - kernel route, C - connected, L - local, S - static, + R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, + f - OpenFabric, t - Table-Direct Sub-codes: (n) - normal, (s) - static, (d) - default, (r) - redistribute, (i) - interface diff --git a/tests/topotests/rip_topo1/r3/show_ip_rip.ref b/tests/topotests/rip_topo1/r3/show_ip_rip.ref index 1df299b5e650..bb4afc76b75d 100644 --- a/tests/topotests/rip_topo1/r3/show_ip_rip.ref +++ b/tests/topotests/rip_topo1/r3/show_ip_rip.ref @@ -1,4 +1,7 @@ -Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP +Codes: K - kernel route, C - connected, L - local, S - static, + R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, + f - OpenFabric, t - Table-Direct Sub-codes: (n) - normal, (s) - static, (d) - default, (r) - redistribute, (i) - interface diff --git a/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref b/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref index 30d0f31e18f6..8645979cc021 100644 --- a/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref +++ b/tests/topotests/ripng_topo1/r1/show_ipv6_ripng.ref @@ -1,4 +1,7 @@ -Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP +Codes: K - kernel route, C - connected, L - local, S - static, + R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, + f - OpenFabric, t - Table-Direct Sub-codes: (n) - normal, (s) - static, (d) - default, (r) - redistribute, (i) - interface, (a/S) - aggregated/Suppressed diff --git a/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref b/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref index fe5bcc8b310f..2c4db1ab5405 100644 --- a/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref +++ b/tests/topotests/ripng_topo1/r2/show_ipv6_ripng.ref @@ -1,4 +1,7 @@ -Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP +Codes: K - kernel route, C - connected, L - local, S - static, + R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, + f - OpenFabric, t - Table-Direct Sub-codes: (n) - normal, (s) - static, (d) - default, (r) - redistribute, (i) - interface, (a/S) - aggregated/Suppressed diff --git a/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref b/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref index 909ad663baeb..2ba0aa6d8fe5 100644 --- a/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref +++ b/tests/topotests/ripng_topo1/r3/show_ipv6_ripng.ref @@ -1,4 +1,7 @@ -Codes: R - RIPng, C - connected, S - Static, O - OSPF, B - BGP +Codes: K - kernel route, C - connected, L - local, S - static, + R - RIPng, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP, + T - Table, v - VNC, V - VNC-Direct, A - Babel, F - PBR, + f - OpenFabric, t - Table-Direct Sub-codes: (n) - normal, (s) - static, (d) - default, (r) - redistribute, (i) - interface, (a/S) - aggregated/Suppressed From cd9bb4dd7e19e7b383d18f5837fbcde2f5799a1e Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 5 Jul 2024 15:57:52 +0300 Subject: [PATCH 378/472] tests: Extended bgp_remote_as_auto topotest with unnumbered case Signed-off-by: Donatas Abraitis --- .../topotests/bgp_remote_as_auto/r1/frr.conf | 6 ++++ .../topotests/bgp_remote_as_auto/r4/frr.conf | 10 ++++++ .../test_bgp_remote_as_auto.py | 33 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/topotests/bgp_remote_as_auto/r4/frr.conf diff --git a/tests/topotests/bgp_remote_as_auto/r1/frr.conf b/tests/topotests/bgp_remote_as_auto/r1/frr.conf index aec0e76a3fd3..2f1bcd275f1a 100644 --- a/tests/topotests/bgp_remote_as_auto/r1/frr.conf +++ b/tests/topotests/bgp_remote_as_auto/r1/frr.conf @@ -2,6 +2,9 @@ int r1-eth0 ip address 192.168.1.1/24 ! +int r1-eth1 + ip address 192.168.14.1/24 +! router bgp 65001 no bgp ebgp-requires-policy no bgp network import-check @@ -11,6 +14,9 @@ router bgp 65001 neighbor 192.168.1.3 remote-as auto neighbor 192.168.1.3 timers 1 3 neighbor 192.168.1.3 timers connect 1 + neighbor r1-eth1 interface remote-as auto + neighbor r1-eth1 timers 1 3 + neighbor r1-eth1 timers connect 1 address-family ipv4 unicast network 10.0.0.1/32 exit-address-family diff --git a/tests/topotests/bgp_remote_as_auto/r4/frr.conf b/tests/topotests/bgp_remote_as_auto/r4/frr.conf new file mode 100644 index 000000000000..e280a6c6e884 --- /dev/null +++ b/tests/topotests/bgp_remote_as_auto/r4/frr.conf @@ -0,0 +1,10 @@ +! +int r4-eth0 + ip address 192.168.14.4/24 +! +router bgp 65004 + no bgp ebgp-requires-policy + neighbor r4-eth0 interface remote-as auto + neighbor r4-eth0 timers 1 3 + neighbor r4-eth0 timers connect 1 +! diff --git a/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py b/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py index b932920e09d4..1db6d98a42e7 100644 --- a/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py +++ b/tests/topotests/bgp_remote_as_auto/test_bgp_remote_as_auto.py @@ -23,7 +23,7 @@ def setup_module(mod): - topodef = {"s1": ("r1", "r2", "r3")} + topodef = {"s1": ("r1", "r2", "r3"), "s2": ("r1", "r4")} tgen = Topogen(topodef, mod.__name__) tgen.start_topology() @@ -49,11 +49,18 @@ def test_bgp_remote_as_auto(): r1 = tgen.gears["r1"] r2 = tgen.gears["r2"] r3 = tgen.gears["r3"] + r4 = tgen.gears["r4"] def _bgp_converge(): output = json.loads(r1.vtysh_cmd("show bgp ipv4 unicast summary json")) expected = { "peers": { + "r1-eth1": { + "hostname": "r4", + "remoteAs": 65004, + "localAs": 65001, + "state": "Established", + }, "192.168.1.2": { "hostname": "r2", "remoteAs": 65001, @@ -124,6 +131,30 @@ def _bgp_converge_external(): _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assert result is None, "Can't see automatic eBGP peering" + def _bgp_converge_external_unnumbered(): + output = json.loads(r4.vtysh_cmd("show bgp ipv4 unicast 10.0.0.1/32 json")) + expected = { + "paths": [ + { + "aspath": { + "string": "65001", + }, + "valid": True, + "peer": { + "hostname": "r1", + "type": "external", + }, + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial( + _bgp_converge_external_unnumbered, + ) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see automatic unnumbered eBGP peering" + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] From ed480148844259b7e9e30ed92489cdf44085457e Mon Sep 17 00:00:00 2001 From: Acee Lindem Date: Fri, 5 Jul 2024 20:44:30 +0000 Subject: [PATCH 379/472] ospfd: Fix several problems with direct acknowledgments and improved delay acks. 1. On P2MP interfaces, direct ack would include the same LSA multiple times multiple packets are processed before the OSPF interfae direct LSA acknowledgment event is processed. Now duplicates LSA in the same event are suppressed. 2. On non-broadcast interfaces, direct acks for multiple neighbors would be unicast to the same neighbor due to the multiple OSPF LS Update packets being process prior to the OSPF interface direct ack event. Now, separate direct acks are unicast to the neighbors requiring them. 3. The interface delayed acknowledgment timer runs would run continously (every second as long as the interace is up). Now, the timer is set when delayed acknowledgments are queued and all queued delayed acknowledges are sent when it fires. 4. For non-broadcast interface delayed acknowledgments, the logic to send to multiple neighbors wasn't working because the list was emptied while building the packet for the first neighbor. Signed-off-by: Acee Lindem --- lib/libospf.h | 1 + ospfd/ospf_flood.c | 26 ++++- ospfd/ospf_flood.h | 23 +++- ospfd/ospf_interface.c | 44 +++++--- ospfd/ospf_interface.h | 17 +-- ospfd/ospf_ism.c | 14 +-- ospfd/ospf_packet.c | 243 ++++++++++++++++++++++++++++++----------- ospfd/ospf_packet.h | 5 +- 8 files changed, 265 insertions(+), 108 deletions(-) diff --git a/lib/libospf.h b/lib/libospf.h index f2dc5d61d9eb..8a208beb3c33 100644 --- a/lib/libospf.h +++ b/lib/libospf.h @@ -61,6 +61,7 @@ extern "C" { #define OSPF_RETRANSMIT_WINDOW_DEFAULT 50 /* milliseconds */ #define OSPF_TRANSMIT_DELAY_DEFAULT 1 #define OSPF_DEFAULT_BANDWIDTH 10000 /* Mbps */ +#define OSPF_ACK_DELAY_DEFAULT 1 #define OSPF_DEFAULT_REF_BANDWIDTH 100000 /* Kbps */ diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index e9797ce935a7..2af4ae317098 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -110,6 +110,9 @@ void ospf_area_update_fr_state(struct ospf_area *area) static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr, struct ospf_lsa *lsa) { + struct ospf_lsa_list_entry *ls_ack_list_entry; + struct ospf_interface *oi = inbr->oi; + /* LSA is more recent than database copy, but was not flooded back out receiving interface. Delayed acknowledgment sent. If interface is in Backup state @@ -122,12 +125,27 @@ static void ospf_flood_delayed_lsa_ack(struct ospf_neighbor *inbr, worked out previously */ /* Deal with router as BDR */ - if (inbr->oi->state == ISM_Backup && !NBR_IS_DR(inbr)) + if (oi->state == ISM_Backup && !NBR_IS_DR(inbr)) return; - /* Schedule a delayed LSA Ack to be sent */ - listnode_add(inbr->oi->ls_ack, - ospf_lsa_lock(lsa)); /* delayed LSA Ack */ + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("%s:Add LSA[Type%d:%pI4:%pI4]: seq 0x%x age %u NBR %pI4 (%s) ack queue", + __func__, lsa->data->type, &lsa->data->id, + &lsa->data->adv_router, ntohl(lsa->data->ls_seqnum), + ntohs(lsa->data->ls_age), &inbr->router_id, + IF_NAME(inbr->oi)); + + /* Add the LSA to the interface delayed Ack list. */ + ls_ack_list_entry = XCALLOC(MTYPE_OSPF_LSA_LIST, + sizeof(struct ospf_lsa_list_entry)); + ls_ack_list_entry->lsa = ospf_lsa_lock(lsa); + ospf_lsa_list_add_tail(&oi->ls_ack_delayed, ls_ack_list_entry); + + /* Set LS Ack timer if it is not already scheduled. */ + if (!oi->t_ls_ack_delayed) + OSPF_ISM_TIMER_ON(oi->t_ls_ack_delayed, + ospf_ls_ack_delayed_timer, + oi->v_ls_ack_delayed); } /* Check LSA is related to external info. */ diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h index d9d953735148..241205297000 100644 --- a/ospfd/ospf_flood.h +++ b/ospfd/ospf_flood.h @@ -7,6 +7,8 @@ #ifndef _ZEBRA_OSPF_FLOOD_H #define _ZEBRA_OSPF_FLOOD_H +#include "typesafe.h" + /* * OSPF Temporal LSA List */ @@ -16,14 +18,25 @@ struct ospf_lsa_list_entry { /* Linkage for LSA List */ struct ospf_lsa_list_item list_linkage; - /* - * Time associated with the list entry. For example, for a neigbhor - * link retransmission list, this is the retransmission time. - */ - struct timeval list_entry_time; + union { + /* + * Time associated with the list entry. For example, for a + * neigbhor link retransmission list, this is the + * retransmission time. + */ + struct timeval list_entry_timeval; + + /* + * Destanation address specific to the LSA list. For example, + * the distination for an associated direct LS acknowledgment. + */ + struct in_addr list_entry_dst_addr; + } u; struct ospf_lsa *lsa; }; +#define list_entry_time u.list_entry_timeval +#define list_entry_dst u.list_entry_dst_addr DECLARE_DLIST(ospf_lsa_list, struct ospf_lsa_list_entry, list_linkage); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 803c36861dcd..c4210eb70c7c 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -186,10 +186,12 @@ static void ospf_if_default_variables(struct ospf_interface *oi) oi->crypt_seqnum = 0; - /* This must be short, (less than RxmtInterval) - - RFC 2328 Section 13.5 para 3. Set to 1 second to avoid Acks being - held back for too long - MAG */ - oi->v_ls_ack = 1; + /* + * The OSPF LS ACK Delay timer must be less than the LS Retransmision + * timer. As per RFC 2328 Section 13.5 paragraph 3, Set to 1 second + * to avoid Acks being held back for too long + */ + oi->v_ls_ack_delayed = OSPF_ACK_DELAY_DEFAULT; } /* lookup oi for specified prefix/ifp */ @@ -272,9 +274,9 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp, /* Initialize static neighbor list. */ oi->nbr_nbma = list_new(); - /* Initialize Link State Acknowledgment list. */ - oi->ls_ack = list_new(); - oi->ls_ack_direct.ls_ack = list_new(); + /* Initialize Link State Acknowledgment lists. */ + ospf_lsa_list_init(&oi->ls_ack_delayed); + ospf_lsa_list_init(&oi->ls_ack_direct); /* Set default values. */ ospf_if_default_variables(oi); @@ -306,6 +308,22 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp, return oi; } +/* + * Cleanup Interface Ack List + */ +static void ospf_if_cleanup_ack_list(struct ospf_lsa_list_head *ls_ack_list) +{ + struct ospf_lsa_list_entry *ls_ack_list_entry; + struct ospf_lsa *lsa; + + frr_each_safe (ospf_lsa_list, ls_ack_list, ls_ack_list_entry) { + lsa = ls_ack_list_entry->lsa; + ospf_lsa_list_del(ls_ack_list, ls_ack_list_entry); + XFREE(MTYPE_OSPF_LSA_LIST, ls_ack_list_entry); + ospf_lsa_unlock(&lsa); + } +} + /* Restore an interface to its pre UP state Used from ism_interface_down only */ void ospf_if_cleanup(struct ospf_interface *oi) @@ -314,7 +332,6 @@ void ospf_if_cleanup(struct ospf_interface *oi) struct listnode *node, *nnode; struct ospf_neighbor *nbr; struct ospf_nbr_nbma *nbr_nbma; - struct ospf_lsa *lsa; /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */ /* delete all static neighbors attached to this interface */ @@ -338,10 +355,9 @@ void ospf_if_cleanup(struct ospf_interface *oi) OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr); } - /* Cleanup Link State Acknowlegdment list. */ - for (ALL_LIST_ELEMENTS(oi->ls_ack, node, nnode, lsa)) - ospf_lsa_unlock(&lsa); /* oi->ls_ack */ - list_delete_all_node(oi->ls_ack); + /* Cleanup Link State Delayed Acknowlegdment list. */ + ospf_if_cleanup_ack_list(&oi->ls_ack_delayed); + ospf_if_cleanup_ack_list(&oi->ls_ack_direct); oi->crypt_seqnum = 0; @@ -377,8 +393,8 @@ void ospf_if_free(struct ospf_interface *oi) /* Free any lists that should be freed */ list_delete(&oi->nbr_nbma); - list_delete(&oi->ls_ack); - list_delete(&oi->ls_ack_direct.ls_ack); + ospf_if_cleanup_ack_list(&oi->ls_ack_delayed); + ospf_if_cleanup_ack_list(&oi->ls_ack_direct); if (IS_DEBUG_OSPF_EVENT) zlog_debug("%s: ospf interface %s vrf %s id %u deleted", diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index a944847b5d9b..78a4fb9e59f9 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -13,6 +13,7 @@ #include "keychain.h" #include "ospfd/ospf_packet.h" #include "ospfd/ospf_spf.h" +#include #define IF_OSPF_IF_INFO(I) ((struct ospf_if_info *)((I)->info)) #define IF_DEF_PARAMS(I) (IF_OSPF_IF_INFO (I)->def_params) @@ -265,20 +266,20 @@ struct ospf_interface { struct route_table *ls_upd_queue; - struct list *ls_ack; /* Link State Acknowledgment list. */ - - struct { - struct list *ls_ack; - struct in_addr dst; - } ls_ack_direct; + /* + * List of LSAs for delayed and direct link + * state acknowledgment transmission. + */ + struct ospf_lsa_list_head ls_ack_delayed; + struct ospf_lsa_list_head ls_ack_direct; /* Timer values. */ - uint32_t v_ls_ack; /* Delayed Link State Acknowledgment */ + uint32_t v_ls_ack_delayed; /* Delayed Link State Acknowledgment */ /* Threads. */ struct event *t_hello; /* timer */ struct event *t_wait; /* timer */ - struct event *t_ls_ack; /* timer */ + struct event *t_ls_ack_delayed; /* timer */ struct event *t_ls_ack_direct; /* event */ struct event *t_ls_upd_event; /* event */ struct event *t_opaque_lsa_self; /* Type-9 Opaque-LSAs */ diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index 878ab725bd32..377e7a6bcc20 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -285,7 +285,7 @@ static void ism_timer_set(struct ospf_interface *oi) reset also. */ EVENT_OFF(oi->t_hello); EVENT_OFF(oi->t_wait); - EVENT_OFF(oi->t_ls_ack); + EVENT_OFF(oi->t_ls_ack_delayed); EVENT_OFF(oi->gr.hello_delay.t_grace_send); break; case ISM_Loopback: @@ -293,7 +293,7 @@ static void ism_timer_set(struct ospf_interface *oi) unavailable for regular data traffic. */ EVENT_OFF(oi->t_hello); EVENT_OFF(oi->t_wait); - EVENT_OFF(oi->t_ls_ack); + EVENT_OFF(oi->t_ls_ack_delayed); EVENT_OFF(oi->gr.hello_delay.t_grace_send); break; case ISM_Waiting: @@ -304,7 +304,7 @@ static void ism_timer_set(struct ospf_interface *oi) OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1); OSPF_ISM_TIMER_ON(oi->t_wait, ospf_wait_timer, OSPF_IF_PARAM(oi, v_wait)); - EVENT_OFF(oi->t_ls_ack); + EVENT_OFF(oi->t_ls_ack_delayed); break; case ISM_PointToPoint: /* The interface connects to a physical Point-to-point network @@ -314,8 +314,6 @@ static void ism_timer_set(struct ospf_interface *oi) /* send first hello immediately */ OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1); EVENT_OFF(oi->t_wait); - OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, - oi->v_ls_ack); break; case ISM_DROther: /* The network type of the interface is broadcast or NBMA @@ -324,8 +322,6 @@ static void ism_timer_set(struct ospf_interface *oi) Backup Designated Router. */ OSPF_HELLO_TIMER_ON(oi); EVENT_OFF(oi->t_wait); - OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, - oi->v_ls_ack); break; case ISM_Backup: /* The network type of the interface is broadcast os NBMA @@ -333,8 +329,6 @@ static void ism_timer_set(struct ospf_interface *oi) and the router is Backup Designated Router. */ OSPF_HELLO_TIMER_ON(oi); EVENT_OFF(oi->t_wait); - OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, - oi->v_ls_ack); break; case ISM_DR: /* The network type of the interface is broadcast or NBMA @@ -342,8 +336,6 @@ static void ism_timer_set(struct ospf_interface *oi) and the router is Designated Router. */ OSPF_HELLO_TIMER_ON(oi); EVENT_OFF(oi->t_wait); - OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, - oi->v_ls_ack); break; } } diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 86f877b6214e..2d15a7ecca33 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -369,19 +369,16 @@ void ospf_ls_rxmt_timer(struct event *thread) ospf_ls_retransmit_set_timer(nbr); } -void ospf_ls_ack_timer(struct event *thread) +void ospf_ls_ack_delayed_timer(struct event *thread) { struct ospf_interface *oi; oi = EVENT_ARG(thread); - oi->t_ls_ack = NULL; + oi->t_ls_ack_delayed = NULL; /* Send Link State Acknowledgment. */ - if (listcount(oi->ls_ack) > 0) + if (ospf_lsa_list_count(&oi->ls_ack_delayed)) ospf_ls_ack_send_delayed(oi); - - /* Set LS Ack timer. */ - OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack); } #ifdef WANT_OSPF_WRITE_FRAGMENT @@ -1820,7 +1817,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, if (IS_LSA_MAXAGE(lsa) && !current && ospf_check_nbr_status(oi->ospf)) { /* (4a) Response Link State Acknowledgment. */ - ospf_ls_ack_send(nbr, lsa); + ospf_ls_ack_send_direct(nbr, lsa); /* (4b) Discard LSA. */ if (IS_DEBUG_OSPF(lsa, LSA)) { @@ -1845,7 +1842,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, if (IS_LSA_MAXAGE(lsa)) { zlog_info("LSA[%s]: Boomerang effect?", dump_lsa_key(lsa)); - ospf_ls_ack_send(nbr, lsa); + ospf_ls_ack_send_direct(nbr, lsa); ospf_lsa_discard(lsa); if (current != NULL && !IS_LSA_MAXAGE(current)) @@ -1879,7 +1876,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, SET_FLAG(lsa->flags, OSPF_LSA_SELF); - ospf_ls_ack_send(nbr, lsa); + ospf_ls_ack_send_direct(nbr, lsa); if (!ospf->gr_info.restart_in_progress) { ospf_opaque_self_originated_lsa_received( @@ -2018,9 +2015,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, */ if (oi->state == ISM_Backup) if (NBR_IS_DR(nbr)) - listnode_add( - oi->ls_ack, - ospf_lsa_lock(lsa)); + ospf_ls_ack_send_direct(nbr, + lsa); DISCARD_LSA(lsa, 6); } else @@ -2029,7 +2025,7 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph, receiving interface. */ { - ospf_ls_ack_send(nbr, lsa); + ospf_ls_ack_send_direct(nbr, lsa); DISCARD_LSA(lsa, 7); } } @@ -3331,17 +3327,36 @@ static int ospf_make_ls_upd(struct ospf_interface *oi, struct list *update, return length; } -static int ospf_make_ls_ack(struct ospf_interface *oi, struct list *ack, - struct stream *s) +static int ospf_make_ls_ack(struct ospf_interface *oi, + struct ospf_lsa_list_head *ls_ack_list, + bool direct_ack, bool delete_ack, struct stream *s) { - struct listnode *node, *nnode; + struct ospf_lsa_list_entry *ls_ack_list_first; + struct ospf_lsa_list_entry *ls_ack_list_entry; uint16_t length = OSPF_LS_ACK_MIN_SIZE; - unsigned long delta = OSPF_LSA_HEADER_SIZE; struct ospf_lsa *lsa; + struct in_addr first_dst_addr; - for (ALL_LIST_ELEMENTS(ack, node, nnode, lsa)) { + /* + * For direct LS Acks, assure the destination address doesn't + * change between queued acknowledgments. + */ + if (direct_ack) { + ls_ack_list_first = ospf_lsa_list_first(ls_ack_list); + if (ls_ack_list_first) + first_dst_addr.s_addr = + ls_ack_list_first->list_entry_dst.s_addr; + } else + first_dst_addr.s_addr = INADDR_ANY; + + frr_each_safe (ospf_lsa_list, ls_ack_list, ls_ack_list_entry) { + lsa = ls_ack_list_entry->lsa; assert(lsa); + if (direct_ack && (ls_ack_list_entry->list_entry_dst.s_addr != + first_dst_addr.s_addr)) + break; + /* LS Ack packet overflows interface MTU * delta is just number of bytes required for * 1 LS Ack(1 LS Hdr) ospf_packet_max will return @@ -3350,19 +3365,46 @@ static int ospf_make_ls_ack(struct ospf_interface *oi, struct list *ack, * against ospf_packet_max to check if it can fit * another ls header in the same packet. */ - if ((length + delta) > ospf_packet_max(oi)) + if ((length + OSPF_LSA_HEADER_SIZE) > ospf_packet_max(oi)) break; stream_put(s, lsa->data, OSPF_LSA_HEADER_SIZE); length += OSPF_LSA_HEADER_SIZE; - listnode_delete(ack, lsa); - ospf_lsa_unlock(&lsa); /* oi->ls_ack_direct.ls_ack */ + if (delete_ack) { + ospf_lsa_list_del(ls_ack_list, ls_ack_list_entry); + XFREE(MTYPE_OSPF_LSA_LIST, ls_ack_list_entry); + ospf_lsa_unlock(&lsa); + } } return length; } +/* + * On non-braodcast networks, the same LS acks must be sent to multiple + * neighbors and deletion must be deferred until after the LS Ack packet + * is sent to all neighbors. + */ +static void ospf_delete_ls_ack_delayed(struct ospf_interface *oi) +{ + struct ospf_lsa_list_entry *ls_ack_list_entry; + struct ospf_lsa *lsa; + uint16_t length = OSPF_LS_ACK_MIN_SIZE; + + frr_each_safe (ospf_lsa_list, &oi->ls_ack_delayed, ls_ack_list_entry) { + lsa = ls_ack_list_entry->lsa; + assert(lsa); + if ((length + OSPF_LSA_HEADER_SIZE) > ospf_packet_max(oi)) + break; + + length += OSPF_LSA_HEADER_SIZE; + ospf_lsa_list_del(&oi->ls_ack_delayed, ls_ack_list_entry); + XFREE(MTYPE_OSPF_LSA_LIST, ls_ack_list_entry); + ospf_lsa_unlock(&lsa); + } +} + static void ospf_hello_send_sub(struct ospf_interface *oi, in_addr_t addr) { struct ospf_packet *op; @@ -3934,10 +3976,13 @@ void ospf_ls_upd_send(struct ospf_neighbor *nbr, struct list *update, int flag, &oi->t_ls_upd_event); } -static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, +static void ospf_ls_ack_send_list(struct ospf_interface *oi, + struct ospf_lsa_list_head *ls_ack_list, + bool direct_ack, bool delete_ack, struct in_addr dst) { struct ospf_packet *op; + struct ospf_lsa_list_entry *ls_ack_list_first; uint16_t length = OSPF_HEADER_SIZE; op = ospf_packet_new(oi->ifp->mtu); @@ -3945,8 +3990,18 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, /* Prepare OSPF common header. */ ospf_make_header(OSPF_MSG_LS_ACK, oi, op->s); + /* Determine the destination address - for direct acks, + * the list entries always include the distination address. + */ + if (direct_ack) { + ls_ack_list_first = ospf_lsa_list_first(ls_ack_list); + op->dst.s_addr = ls_ack_list_first->list_entry_dst.s_addr; + } else + op->dst.s_addr = dst.s_addr; + /* Prepare OSPF Link State Acknowledgment body. */ - length += ospf_make_ls_ack(oi, ack, op->s); + length += ospf_make_ls_ack(oi, ls_ack_list, direct_ack, delete_ack, + op->s); /* Fill OSPF header. */ ospf_fill_header(oi, op->s, length); @@ -3954,14 +4009,6 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, /* Set packet length. */ op->length = length; - /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT || - (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT && - !oi->p2mp_non_broadcast)) - op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); - else - op->dst.s_addr = dst.s_addr; - /* Add packet to the interface output queue. */ ospf_packet_add(oi, op); @@ -3969,34 +4016,96 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, OSPF_ISM_WRITE_ON(oi->ospf); } -static void ospf_ls_ack_send_event(struct event *thread) +static void ospf_ls_ack_send_direct_event(struct event *thread) { struct ospf_interface *oi = EVENT_ARG(thread); + struct in_addr dst = { INADDR_ANY }; oi->t_ls_ack_direct = NULL; - while (listcount(oi->ls_ack_direct.ls_ack)) - ospf_ls_ack_send_list(oi, oi->ls_ack_direct.ls_ack, - oi->ls_ack_direct.dst); + while (ospf_lsa_list_count(&oi->ls_ack_direct)) + ospf_ls_ack_send_list(oi, &(oi->ls_ack_direct), true, true, dst); } -void ospf_ls_ack_send(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) +void ospf_ls_ack_send_direct(struct ospf_neighbor *nbr, struct ospf_lsa *lsa) { + struct ospf_lsa_list_entry *ls_ack_list_entry; struct ospf_interface *oi = nbr->oi; + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("%s:Add LSA[Type%d:%pI4:%pI4]: seq 0x%x age %u NBR %pI4 (%s) ack queue", + __func__, lsa->data->type, &lsa->data->id, + &lsa->data->adv_router, ntohl(lsa->data->ls_seqnum), + ntohs(lsa->data->ls_age), &nbr->router_id, + IF_NAME(nbr->oi)); + + /* + * On Point-to-Multipoint broadcast-capabile interfaces, + * where direct acks from are sent to the ALLSPFRouters + * address and one direct ack send event, may include LSAs + * from multiple neighbors, there is a possibility of the same + * LSA being processed more than once in the same send event. + * In this case, the instances subsequent to the first can be + * ignored. + */ + if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT && !oi->p2mp_non_broadcast) { + struct ospf_lsa_list_entry *ls_ack_list_entry; + struct ospf_lsa *ack_queue_lsa; + + frr_each (ospf_lsa_list, &oi->ls_ack_direct, ls_ack_list_entry) { + ack_queue_lsa = ls_ack_list_entry->lsa; + if ((lsa == ack_queue_lsa) || + ((lsa->data->type == ack_queue_lsa->data->type) && + (lsa->data->id.s_addr == + ack_queue_lsa->data->id.s_addr) && + (lsa->data->adv_router.s_addr == + ack_queue_lsa->data->adv_router.s_addr) && + (lsa->data->ls_seqnum == + ack_queue_lsa->data->ls_seqnum))) { + if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) + zlog_debug("%s:LSA[Type%d:%pI4:%pI4]: seq 0x%x age %u NBR %pI4 (%s) ack queue duplicate", + __func__, lsa->data->type, + &lsa->data->id, + &lsa->data->adv_router, + ntohl(lsa->data->ls_seqnum), + ntohs(lsa->data->ls_age), + &nbr->router_id, + IF_NAME(nbr->oi)); + return; + } + } + } + if (IS_GRACE_LSA(lsa)) { if (IS_DEBUG_OSPF_GR) zlog_debug("%s, Sending GRACE ACK to Restarter.", __func__); } - if (listcount(oi->ls_ack_direct.ls_ack) == 0) - oi->ls_ack_direct.dst = nbr->address.u.prefix4; + ls_ack_list_entry = XCALLOC(MTYPE_OSPF_LSA_LIST, + sizeof(struct ospf_lsa_list_entry)); - listnode_add(oi->ls_ack_direct.ls_ack, ospf_lsa_lock(lsa)); + /* + * Determine the destination address - Direct LS acknowledgments + * are sent the AllSPFRouters multicast address on Point-to-Point + * and Point-to-Multipoint broadcast-capable interfaces. For all other + * interface types, they are unicast directly to the neighbor. + */ + if (oi->type == OSPF_IFTYPE_POINTOPOINT || + (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT && + !oi->p2mp_non_broadcast)) + ls_ack_list_entry->list_entry_dst.s_addr = + htonl(OSPF_ALLSPFROUTERS); + else + ls_ack_list_entry->list_entry_dst.s_addr = + nbr->address.u.prefix4.s_addr; - event_add_event(master, ospf_ls_ack_send_event, oi, 0, - &oi->t_ls_ack_direct); + ls_ack_list_entry->lsa = ospf_lsa_lock(lsa); + ospf_lsa_list_add_tail(&nbr->oi->ls_ack_direct, ls_ack_list_entry); + + if (oi->t_ls_ack_direct == NULL) + event_add_event(master, ospf_ls_ack_send_direct_event, oi, 0, + &oi->t_ls_ack_direct); } /* Send Link State Acknowledgment delayed. */ @@ -4013,33 +4122,39 @@ void ospf_ls_ack_send_delayed(struct ospf_interface *oi) struct ospf_neighbor *nbr; struct route_node *rn; - for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { - nbr = rn->info; + while (ospf_lsa_list_count(&oi->ls_ack_delayed)) { + for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) { + nbr = rn->info; - if (!nbr) - continue; + if (!nbr) + continue; - if (nbr != oi->nbr_self && nbr->state >= NSM_Exchange) - while (listcount(oi->ls_ack)) - ospf_ls_ack_send_list( - oi, oi->ls_ack, - nbr->address.u.prefix4); + if (nbr != oi->nbr_self && + nbr->state >= NSM_Exchange) + ospf_ls_ack_send_list(oi, + &oi->ls_ack_delayed, + false, false, + nbr->address.u + .prefix4); + } + ospf_delete_ls_ack_delayed(oi); } - return; - } - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - dst.s_addr = oi->vl_data->peer_addr.s_addr; - else if (oi->state == ISM_DR || oi->state == ISM_Backup) - dst.s_addr = htonl(OSPF_ALLSPFROUTERS); - else if (oi->type == OSPF_IFTYPE_POINTOPOINT) - dst.s_addr = htonl(OSPF_ALLSPFROUTERS); - else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) - dst.s_addr = htonl(OSPF_ALLSPFROUTERS); - else - dst.s_addr = htonl(OSPF_ALLDROUTERS); + } else { + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + dst.s_addr = oi->vl_data->peer_addr.s_addr; + else if (oi->state == ISM_DR || oi->state == ISM_Backup) + dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else if (oi->type == OSPF_IFTYPE_POINTOPOINT) + dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) + dst.s_addr = htonl(OSPF_ALLSPFROUTERS); + else + dst.s_addr = htonl(OSPF_ALLDROUTERS); - while (listcount(oi->ls_ack)) - ospf_ls_ack_send_list(oi, oi->ls_ack, dst); + while (ospf_lsa_list_count(&oi->ls_ack_delayed)) + ospf_ls_ack_send_list(oi, &oi->ls_ack_delayed, false, + true, dst); + } } /* diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 2c9dba6c8819..84e4b027e694 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -135,13 +135,14 @@ extern void ospf_ls_upd_send(struct ospf_neighbor *, struct list *, int, int); extern void ospf_ls_upd_queue_send(struct ospf_interface *oi, struct list *update, struct in_addr addr, int send_lsupd_now); -extern void ospf_ls_ack_send(struct ospf_neighbor *, struct ospf_lsa *); +extern void ospf_ls_ack_send_direct(struct ospf_neighbor *nbr, + struct ospf_lsa *lsa); extern void ospf_ls_ack_send_delayed(struct ospf_interface *); extern void ospf_ls_retransmit(struct ospf_interface *, struct ospf_lsa *); extern void ospf_ls_req_event(struct ospf_neighbor *); extern void ospf_ls_rxmt_timer(struct event *thread); -extern void ospf_ls_ack_timer(struct event *thread); +extern void ospf_ls_ack_delayed_timer(struct event *thread); extern void ospf_poll_timer(struct event *thread); extern void ospf_hello_reply_timer(struct event *thread); From 6477f73c0b0e16d2364d2c5f972f3988c387fa44 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 7 Jul 2024 18:26:30 +0300 Subject: [PATCH 380/472] tests: Rename BGP OAD test function Signed-off-by: Donatas Abraitis --- tests/topotests/bgp_oad/test_bgp_oad.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/topotests/bgp_oad/test_bgp_oad.py b/tests/topotests/bgp_oad/test_bgp_oad.py index a2ca37a2b7c8..bb779462db27 100644 --- a/tests/topotests/bgp_oad/test_bgp_oad.py +++ b/tests/topotests/bgp_oad/test_bgp_oad.py @@ -46,7 +46,7 @@ def teardown_module(mod): tgen.stop_topology() -def test_bgp_dynamic_capability_role(): +def test_bgp_oad(): tgen = get_topogen() if tgen.routers_have_failure(): From d7144594cab0708139dcd736ba5166a052be9d3b Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 7 Jul 2024 18:42:08 +0300 Subject: [PATCH 381/472] bgpd: Drop unnecessary is_add check for bgp_zebra_announce_actual() Fixes: ccfe452763d16c432fa81fd20e805bec819b345e ("bgpd : backpressure - Handle BGP-Zebra Install evt Creation") Signed-off-by: Donatas Abraitis --- bgpd/bgp_zebra.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 3508f2d341bb..13f5337cdf9c 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1556,7 +1556,6 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, struct peer *peer; uint32_t metric; route_tag_t tag; - bool is_add; uint32_t nhg_id = 0; struct bgp_table *table = bgp_dest_table(dest); const struct prefix *p = bgp_dest_get_prefix(dest); @@ -1610,9 +1609,7 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, table->afi, table->safi, &nhg_id, &metric, &tag, &allow_recursion); - is_add = (valid_nh_count || nhg_id) ? true : false; - - if (is_add && CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) { + if (CHECK_FLAG(bm->flags, BM_FLAG_SEND_EXTRA_DATA_TO_ZEBRA)) { struct bgp_zebra_opaque bzo = {}; const char *reason = bgp_path_selection_reason2str(dest->reason); @@ -1668,18 +1665,17 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, } if (bgp_debug_zebra(p)) { - zlog_debug("Tx route %s %s %pFX metric %u tag %" ROUTE_TAG_PRI + zlog_debug("Tx route add %s %pFX metric %u tag %" ROUTE_TAG_PRI " count %d nhg %d", - is_add ? "add" : "delete", bgp->name_pretty, - &api.prefix, api.metric, api.tag, api.nexthop_num, - nhg_id); + bgp->name_pretty, &api.prefix, api.metric, api.tag, + api.nexthop_num, nhg_id); bgp_debug_zebra_nh(&api); zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)", __func__, p, (allow_recursion ? "" : "NOT ")); } - return zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, - zclient, &api); + + return zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api); } From 16bfdf58f757681230eb05a7f2d2da4ecdf66d0c Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 7 Jul 2024 18:49:05 +0300 Subject: [PATCH 382/472] bgpd: Print tableid when sending (add/remove) routes to Zebra In case this is used under `set table X` via route-maps, it's good to know in debugs the table id. Signed-off-by: Donatas Abraitis --- bgpd/bgp_zebra.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 13f5337cdf9c..72620de7d98e 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1665,10 +1665,10 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, } if (bgp_debug_zebra(p)) { - zlog_debug("Tx route add %s %pFX metric %u tag %" ROUTE_TAG_PRI + zlog_debug("Tx route add %s (table id %u) %pFX metric %u tag %" ROUTE_TAG_PRI " count %d nhg %d", - bgp->name_pretty, &api.prefix, api.metric, api.tag, - api.nexthop_num, nhg_id); + bgp->name_pretty, api.tableid, &api.prefix, + api.metric, api.tag, api.nexthop_num, nhg_id); bgp_debug_zebra_nh(&api); zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)", @@ -1757,8 +1757,8 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest, } if (bgp_debug_zebra(p)) - zlog_debug("Tx route delete %s %pFX", bgp->name_pretty, - &api.prefix); + zlog_debug("Tx route delete %s (table id %u) %pFX", + bgp->name_pretty, api.tableid, &api.prefix); return zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api); } From f54970ff43d6dc376081328614febb31f58df75d Mon Sep 17 00:00:00 2001 From: zhou-run Date: Fri, 21 Jun 2024 14:26:44 +0800 Subject: [PATCH 383/472] isisd: The neighbor entry still displays the deleted hostname of the neighbor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. The lsp_update_data() function will check for the presence of the ISIS_TLV_DYNAMIC_HOSTNAME in the LSP, and then call isis_dynhn_insert() to add a hostname entry corresponding to the LSP ID. However, when the ISIS_TLV_DYNAMIC_HOSTNAME is not present in the LSP, the hostname entry corresponding to the LSP ID should also be deleted. 2. The command “show isis neighbor” invokes isis_adj_name() to display the System ID or hostname, but it does not check the area->dynhostname flag. 3. When the LSP expires and is removed, the corresponding hostname entry should also be deleted. 4. The TLV for LSP fragmentation will not contain the hostname and should be skipped. Signed-off-by: zhou-run --- isisd/isis_adjacency.c | 2 +- isisd/isis_lsp.c | 24 +++++++++++++------ tests/topotests/isis_topo1/test_isis_topo1.py | 3 +++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 430bee92bf97..ad6339871576 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -293,7 +293,7 @@ const char *isis_adj_name(const struct isis_adjacency *adj) struct isis_dynhn *dyn; dyn = dynhn_find_by_id(adj->circuit->isis, adj->sysid); - if (dyn) + if (adj->circuit->area->dynhostname && dyn) return dyn->hostname; snprintfrr(buf, sizeof(buf), "%pSY", adj->sysid); diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index c98cee06a568..79c291444597 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -482,13 +482,19 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, lsp->tlvs = tlvs; - if (area->dynhostname && lsp->tlvs->hostname - && lsp->hdr.rem_lifetime) { - isis_dynhn_insert( - area->isis, lsp->hdr.lsp_id, lsp->tlvs->hostname, - (lsp->hdr.lsp_bits & LSPBIT_IST) == IS_LEVEL_1_AND_2 - ? IS_LEVEL_2 - : IS_LEVEL_1); + if (area->dynhostname && lsp->hdr.rem_lifetime) { + if (lsp->tlvs->hostname) { + isis_dynhn_insert(area->isis, lsp->hdr.lsp_id, + lsp->tlvs->hostname, + (lsp->hdr.lsp_bits & LSPBIT_IST) == + IS_LEVEL_1_AND_2 + ? IS_LEVEL_2 + : IS_LEVEL_1); + } else { + if (!LSP_PSEUDO_ID(lsp->hdr.lsp_id) && + !LSP_FRAGMENT(lsp->hdr.lsp_id)) + isis_dynhn_remove(area->isis, lsp->hdr.lsp_id); + } } return; @@ -2225,6 +2231,10 @@ void lsp_tick(struct event *thread) &area->lspdb[level], next); + if (!LSP_PSEUDO_ID(lsp->hdr.lsp_id)) + isis_dynhn_remove(area->isis, + lsp->hdr.lsp_id); + lspdb_del(&area->lspdb[level], lsp); lsp_destroy(lsp); lsp = NULL; diff --git a/tests/topotests/isis_topo1/test_isis_topo1.py b/tests/topotests/isis_topo1/test_isis_topo1.py index b388f52bd9bd..9615d30d3c13 100644 --- a/tests/topotests/isis_topo1/test_isis_topo1.py +++ b/tests/topotests/isis_topo1/test_isis_topo1.py @@ -685,6 +685,9 @@ def _check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected): ) database_json = json.loads(isis_database_output) + if "lsps" not in database_json["areas"][0]["levels"][1]: + return "The LSP of {} has not been synchronized yet ".format(router.name) + att_p_ol = database_json["areas"][0]["levels"][1]["lsps"][0]["attPOl"] if att_p_ol == att_p_ol_expected: return True From 66a84c7c107d7b70befdae77f923b72f3d5956b2 Mon Sep 17 00:00:00 2001 From: Xiao Liang Date: Fri, 17 Nov 2023 10:44:10 +0800 Subject: [PATCH 384/472] tests: Add IPv6 network adv/withdraw case in bgp_evpn_rt5 topotest Note that withdrawing IPv6 route should not affect IPv4. Signed-off-by: Xiao Liang --- tests/topotests/bgp_evpn_rt5/r1/bgpd.conf | 4 + tests/topotests/bgp_evpn_rt5/r1/zebra.conf | 1 + tests/topotests/bgp_evpn_rt5/r2/bgpd.conf | 4 + tests/topotests/bgp_evpn_rt5/r2/zebra.conf | 1 + tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py | 125 +++++++++++++++++- 5 files changed, 134 insertions(+), 1 deletion(-) diff --git a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf index ccbeae6ed78e..c8c4faf222cc 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r1/bgpd.conf @@ -20,7 +20,11 @@ router bgp 65000 vrf r1-vrf-101 address-family ipv4 unicast network 192.168.102.21/32 exit-address-family + address-family ipv6 unicast + network fd00::1/128 + exit-address-family address-family l2vpn evpn advertise ipv4 unicast + advertise ipv6 unicast exit-address-family ! diff --git a/tests/topotests/bgp_evpn_rt5/r1/zebra.conf b/tests/topotests/bgp_evpn_rt5/r1/zebra.conf index 4f1804c67657..c3d508c2b628 100644 --- a/tests/topotests/bgp_evpn_rt5/r1/zebra.conf +++ b/tests/topotests/bgp_evpn_rt5/r1/zebra.conf @@ -17,6 +17,7 @@ interface r1-eth0 ! interface loop101 vrf r1-vrf-101 ip address 192.168.102.21/32 + ipv6 address fd00::1/128 ! diff --git a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf index 744c259d9a18..de5a0efc445f 100644 --- a/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf +++ b/tests/topotests/bgp_evpn_rt5/r2/bgpd.conf @@ -21,7 +21,11 @@ router bgp 65000 vrf r2-vrf-101 address-family ipv4 unicast network 192.168.101.41/32 exit-address-family + address-family ipv6 unicast + network fd00::2/128 + exit-address-family address-family l2vpn evpn advertise ipv4 unicast + advertise ipv6 unicast exit-address-family ! diff --git a/tests/topotests/bgp_evpn_rt5/r2/zebra.conf b/tests/topotests/bgp_evpn_rt5/r2/zebra.conf index 7d19a5b38162..7db40cb59c0d 100644 --- a/tests/topotests/bgp_evpn_rt5/r2/zebra.conf +++ b/tests/topotests/bgp_evpn_rt5/r2/zebra.conf @@ -11,6 +11,7 @@ vrf r2-vrf-101 ! interface loop101 vrf r2-vrf-101 ip address 192.168.101.41/32 + ipv6 address fd00::2/128 ! interface r2-eth0 ip address 192.168.100.41/24 diff --git a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py index d9177b4d25d1..2d027081cb55 100644 --- a/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py +++ b/tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py @@ -25,6 +25,8 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib import topotest +from lib.bgp import verify_bgp_rib +from lib.common_config import apply_raw_config from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger @@ -179,12 +181,18 @@ def test_protocols_convergence(): output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101 ipv4", isjson=False) logger.info("==== result from show bgp vrf r1-vrf-101 ipv4") logger.info(output) + output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101 ipv6", isjson=False) + logger.info("==== result from show bgp vrf r1-vrf-101 ipv6") + logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101", isjson=False) logger.info("==== result from show bgp vrf r1-vrf-101 ") logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show ip route vrf r1-vrf-101", isjson=False) logger.info("==== result from show ip route vrf r1-vrf-101") logger.info(output) + output = tgen.gears["r1"].vtysh_cmd("show ipv6 route vrf r1-vrf-101", isjson=False) + logger.info("==== result from show ipv6 route vrf r1-vrf-101") + logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show evpn vni detail", isjson=False) logger.info("==== result from show evpn vni detail") logger.info(output) @@ -192,8 +200,49 @@ def test_protocols_convergence(): logger.info("==== result from show evpn next-hops vni all") logger.info(output) output = tgen.gears["r1"].vtysh_cmd("show evpn rmac vni all", isjson=False) - logger.info("==== result from show evpn next-hops vni all") + logger.info("==== result from show evpn rmac vni all") logger.info(output) + + expected = { + "fd00::2/128": [ + { + "prefix": "fd00::2/128", + "vrfName": "r1-vrf-101", + "nexthops": [ + { + "ip": "::ffff:c0a8:6429", + } + ], + } + ] + } + result = topotest.router_json_cmp( + tgen.gears["r1"], "show ipv6 route vrf r1-vrf-101 fd00::2/128 json", expected + ) + assert result is None, "ipv6 route check failed" + + expected = { + "101": { + "numNextHops": 2, + "192.168.100.41": { + "nexthopIp": "192.168.100.41", + }, + "::ffff:c0a8:6429": { + "nexthopIp": "::ffff:c0a8:6429", + }, + } + } + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn next-hops vni all json", expected + ) + assert result is None, "evpn next-hops check failed" + + expected = {"101": {"numRmacs": 1}} + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn rmac vni all json", expected + ) + assert result is None, "evpn rmac number check failed" + # Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn) pingrouter = tgen.gears["r1"] logger.info( @@ -209,6 +258,80 @@ def test_protocols_convergence(): else: logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK") + logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(r2-vrf-101 = fd00::2)") + output = pingrouter.run("ip netns exec r1-vrf-101 ping fd00::2 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assert 0, "expected ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) should be ok" + else: + logger.info("Check Ping IPv6 from R1(r1-vrf-101) to R2(fd00::2) OK") + + config_no_ipv6 = { + "r2": { + "raw_config": [ + "router bgp 65000 vrf r2-vrf-101", + "address-family ipv6 unicast", + "no network fd00::2/128", + ] + } + } + + logger.info("==== Remove IPv6 network on R2") + result = apply_raw_config(tgen, config_no_ipv6) + assert result is True, "Failed to remove IPv6 network on R2, Error: {} ".format( + result + ) + ipv6_routes = { + "r1": { + "static_routes": [ + { + "vrf": "r1-vrf-101", + "network": ["fd00::2/128"], + } + ] + } + } + result = verify_bgp_rib(tgen, "ipv6", "r1", ipv6_routes, expected=False) + assert result is not True, "expect IPv6 route fd00::2/128 withdrawn" + output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False) + logger.info("==== result from show evpn next-hops vni all") + logger.info(output) + output = tgen.gears["r1"].vtysh_cmd("show evpn rmac vni all", isjson=False) + logger.info("==== result from show evpn next-hops vni all") + logger.info(output) + + expected = { + "101": { + "numNextHops": 1, + "192.168.100.41": { + "nexthopIp": "192.168.100.41", + }, + } + } + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn next-hops vni all json", expected + ) + assert result is None, "evpn next-hops check failed" + + expected = {"101": {"numRmacs": 1}} + result = topotest.router_json_cmp( + tgen.gears["r1"], "show evpn rmac vni all json", expected + ) + assert result is None, "evpn rmac number check failed" + + logger.info( + "Check Ping IPv4 from R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)" + ) + output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000") + logger.info(output) + if "1000 packets transmitted, 1000 received" not in output: + assertmsg = ( + "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok" + ) + assert 0, assertmsg + else: + logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK") + def test_memory_leak(): "Run the memory leak test and report results." From f883c7119e76e264fb8045bf1884e436eb66527a Mon Sep 17 00:00:00 2001 From: Eugene Crosser Date: Tue, 2 Jul 2024 19:02:53 +0200 Subject: [PATCH 385/472] zebra: evpn: not coerce VTEP IP to IPv4 in nh_list In L3 BGP-EVPN, if there are both IPv4 and IPv6 routes in the VPN, zebra maintains two instances of `struct zebra_neigh` object: one with IPv4 address of the nexthop, and another with IPv6 address that is an IPv4 mapped to IPv6, but only one intance of `struct zebra_mac` object, that contains a list of nexthop addresses that use this mac. The code in `zebra_vxlan` module uses the fact that the list is empty as the indication that the `zebra_mac` object is unused, and needs to be dropped. However, preexisting code used nexthop address converted to IPv4 notation for the element of this list. As a result, when two `zebra_neigh` objects, one IPv4 and one IPv6-mapped-IPv4 were linked to the `zebra_mac` object, only one element was added to the list. Consequently, when one of the two `zebra_neigh` objects was dropped, the only element in the list was removed, making it empty, and `zebra_mac` object was dropped, and neigbrour cache elements uninstalled from the kernel. As a result, after the last route in _one_ family was removed from a remote vtep, all remaining routes in the _other_ family became unreachable, because RMAC of the vtep was removed. This commit makes `zebra_mac` use uncoerced IP address of the `zebra_neigh` object for the entries in the `nh_list`. This way, `zebra_mac` object no longer loses track of `zebra_neigh` objects that need it. Bug-URL: https://github.com/FRRouting/frr/issues/16340 Signed-off-by: Eugene Crosser --- zebra/zebra_vxlan.c | 78 ++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index b8c11e186a7b..f1ae42e32043 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1356,6 +1356,18 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, { struct zebra_mac *zrmac = NULL; struct ipaddr *vtep = NULL; + struct ipaddr ipv4_vtep; + + /* vtep_ip may be v4 or v6-mapped-v4. But zrmac->fwd_info + * can only contain v4 version. So convert if needed + */ + memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); + ipv4_vtep.ipa_type = IPADDR_V4; + if (vtep_ip->ipa_type == IPADDR_V6) + ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6, + &(ipv4_vtep.ipaddr_v4)); + else + IPV4_ADDR_COPY(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4); zrmac = zl3vni_rmac_lookup(zl3vni, rmac); if (!zrmac) { @@ -1369,7 +1381,7 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, return -1; } memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info)); - zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4; + zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4; vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr)); memcpy(vtep, vtep_ip, sizeof(struct ipaddr)); @@ -1383,14 +1395,14 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni, /* install rmac in kernel */ zl3vni_rmac_install(zl3vni, zrmac); } else if (!IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip, - &vtep_ip->ipaddr_v4)) { + &(ipv4_vtep.ipaddr_v4))) { if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA", zl3vni->vni, &zrmac->fwd_info.r_vtep_ip, vtep_ip, rmac); - zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4; + zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4; vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr)); memcpy(vtep, vtep_ip, sizeof(struct ipaddr)); @@ -1410,36 +1422,29 @@ static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni, struct zebra_mac *zrmac, struct ipaddr *vtep_ip) { - struct ipaddr ipv4_vtep; - if (!zl3vni_nh_lookup(zl3vni, vtep_ip)) { - memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); - ipv4_vtep.ipa_type = IPADDR_V4; - if (vtep_ip->ipa_type == IPADDR_V6) - ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6, - &ipv4_vtep.ipaddr_v4); - else - memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4, - sizeof(struct in_addr)); - /* remove nh from rmac's list */ - l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, &ipv4_vtep); - /* delete nh is same as current selected, fall back to - * one present in the list - */ - if (IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip, - &ipv4_vtep.ipaddr_v4) && - listcount(zrmac->nh_list)) { + l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, vtep_ip); + /* If there are remaining entries, use IPv4 from one */ + if (listcount(zrmac->nh_list)) { struct ipaddr *vtep; + struct ipaddr ipv4_vtep; vtep = listgetdata(listhead(zrmac->nh_list)); - zrmac->fwd_info.r_vtep_ip = vtep->ipaddr_v4; + memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); + ipv4_vtep.ipa_type = IPADDR_V4; + if (vtep->ipa_type == IPADDR_V6) + ipv4_mapped_ipv6_to_ipv4(&vtep->ipaddr_v6, + &(ipv4_vtep.ipaddr_v4)); + else + IPV4_ADDR_COPY(&(ipv4_vtep.ipaddr_v4), + &vtep->ipaddr_v4); + zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4; if (IS_ZEBRA_DEBUG_VXLAN) - zlog_debug( - "L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA", - zl3vni->vni, &ipv4_vtep, - &zrmac->fwd_info.r_vtep_ip, - &zrmac->macaddr); + zlog_debug("L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA", + zl3vni->vni, vtep_ip, + &zrmac->fwd_info.r_vtep_ip, + &zrmac->macaddr); /* install rmac in kernel */ zl3vni_rmac_install(zl3vni, zrmac); @@ -2531,7 +2536,6 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, const struct prefix *host_prefix) { struct zebra_l3vni *zl3vni = NULL; - struct ipaddr ipv4_vtep; zl3vni = zl3vni_from_vrf(vrf_id); if (!zl3vni || !is_l3vni_oper_up(zl3vni)) @@ -2547,24 +2551,10 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac, svd_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix); /* - * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4 - * address. Rmac is programmed against the ipv4 vtep because we only - * support ipv4 tunnels in the h/w right now - */ - memset(&ipv4_vtep, 0, sizeof(ipv4_vtep)); - ipv4_vtep.ipa_type = IPADDR_V4; - if (vtep_ip->ipa_type == IPADDR_V6) - ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6, - &(ipv4_vtep.ipaddr_v4)); - else - memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4, - sizeof(struct in_addr)); - - /* - * add the rmac - remote rmac to be installed is against the ipv4 + * add the rmac - remote rmac to be installed is against the * nexthop address */ - zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep); + zl3vni_remote_rmac_add(zl3vni, rmac, vtep_ip); } /* handle evpn vrf route delete */ From 7dfe12eef838f2a8be15e8c58e47f4bcd8b64239 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 3 Jul 2024 14:37:52 +0200 Subject: [PATCH 386/472] topotests: bgp_peer_type_multipath_relax, adds the duplicate flag During the bgp_peer_type_multipath_relax_test, the test does not check the 'duplicate' flag value of the duplicate nexthop. Fix this by adding the duplicate value in the expected json files. Fixes: ee88563ac2ea ("bgpd: Add 'bgp bestpath peer-type multipath-relax'") Signed-off-by: Philippe Guibert --- .../bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json | 1 + .../bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json index 22ec2c298b0e..791b92df65ee 100644 --- a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json +++ b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json @@ -24,6 +24,7 @@ }, { "fib":true, + "duplicate":true, "ip":"10.0.3.2", "active":true } diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json index facddcda463f..1fe9a6799f75 100644 --- a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json +++ b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json @@ -24,6 +24,7 @@ }, { "fib":true, + "duplicate":true, "ip":"10.0.3.2", "active":true } From 731f74e35fa2c1636208f4bf64650d2d00a199b4 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 3 Jul 2024 08:51:51 +0200 Subject: [PATCH 387/472] zebra, topotests: do not set nexthop's FIB flag when DUPLICATE present The bgp_duplicate_nexthop test installs routes with nexthop's flags set to both DUPLICATE and FIB: this should not happen. The DUPLICATE flag of a nexthop indicates this nexthop is already used in the same nexthop-group, and there is no need to install it twice in the system; having the FIB flag set indicates that the nexthop is installed in the system. This is why both flags should not be set on the same nexthop. This case happens at installation time, but can also happen at update time. - Fix this by not setting the FIB flag value when the DUPLICATE flag is present. - Modify the bgp_duplicate_test to check that the FIB flag is not present on duplicated nexthops. - Modify the bgp_peer_type_multipath_relax test. Signed-off-by: Philippe Guibert --- .../test_bgp_duplicate_nexthop.py | 2 +- .../r1/prefix1-eBGP-confed.json | 1 - .../r1/prefix1-eBGP-iBGP.json | 1 - tests/topotests/lib/common_check.py | 27 +++++++++++++++---- zebra/zebra_dplane.c | 4 +++ zebra/zebra_rib.c | 3 +++ 6 files changed, 30 insertions(+), 8 deletions(-) diff --git a/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py index 955881e6f905..83fae71bf59f 100644 --- a/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py +++ b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py @@ -320,7 +320,7 @@ def check_ipv4_prefix_recursive_with_multiple_nexthops( ) test_func = functools.partial( - ip_check_path_selection, tgen.gears["r1"], prefix, expected + ip_check_path_selection, tgen.gears["r1"], prefix, expected, check_fib=True ) _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert ( diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json index 791b92df65ee..483165c0f377 100644 --- a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json +++ b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-confed.json @@ -23,7 +23,6 @@ "recursive":true }, { - "fib":true, "duplicate":true, "ip":"10.0.3.2", "active":true diff --git a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json index 1fe9a6799f75..638a825395e2 100644 --- a/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json +++ b/tests/topotests/bgp_peer_type_multipath_relax/r1/prefix1-eBGP-iBGP.json @@ -23,7 +23,6 @@ "recursive":true }, { - "fib":true, "duplicate":true, "ip":"10.0.3.2", "active":true diff --git a/tests/topotests/lib/common_check.py b/tests/topotests/lib/common_check.py index be3241fd2022..19f02dbadc9f 100644 --- a/tests/topotests/lib/common_check.py +++ b/tests/topotests/lib/common_check.py @@ -10,11 +10,13 @@ from lib import topotest -def ip_check_path_selection(router, ipaddr_str, expected, vrf_name=None): +def ip_check_path_selection( + router, ipaddr_str, expected, vrf_name=None, check_fib=False +): if vrf_name: - cmdstr = f'show ip route vrf {vrf_name} {ipaddr_str} json' + cmdstr = f"show ip route vrf {vrf_name} {ipaddr_str} json" else: - cmdstr = f'show ip route {ipaddr_str} json' + cmdstr = f"show ip route {ipaddr_str} json" try: output = json.loads(router.vtysh_cmd(cmdstr)) except: @@ -25,6 +27,21 @@ def ip_check_path_selection(router, ipaddr_str, expected, vrf_name=None): num_nh_expected = len(expected[ipaddr_str][0]["nexthops"]) num_nh_observed = len(output[ipaddr_str][0]["nexthops"]) if num_nh_expected == num_nh_observed: + if check_fib: + # special case: when fib flag is unset, + # an extra test should be done to check that the flag is really unset + for nh_output, nh_expected in zip( + output[ipaddr_str][0]["nexthops"], + expected[ipaddr_str][0]["nexthops"], + ): + if ( + "fib" in nh_output.keys() + and nh_output["fib"] + and ("fib" not in nh_expected.keys() or not nh_expected["fib"]) + ): + return "{}, prefix {} nexthop {} has the fib flag set, whereas it is not expected".format( + router.name, ipaddr_str, nh_output["ip"] + ) return ret return "{}, prefix {} does not have the correct number of nexthops : observed {}, expected {}".format( router.name, ipaddr_str, num_nh_observed, num_nh_expected @@ -37,9 +54,9 @@ def iproute2_check_path_selection(router, ipaddr_str, expected, vrf_name=None): return None if vrf_name: - cmdstr = f'ip -json route show vrf {vrf_name} {ipaddr_str}' + cmdstr = f"ip -json route show vrf {vrf_name} {ipaddr_str}" else: - cmdstr = f'ip -json route show {ipaddr_str}' + cmdstr = f"ip -json route show {ipaddr_str}" try: output = json.loads(cmdstr) except: diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 7910559c4b41..0844b346723b 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -4314,6 +4314,10 @@ dplane_route_update_internal(struct route_node *rn, NEXTHOP_FLAG_RECURSIVE)) continue; + if (CHECK_FLAG(nexthop->flags, + NEXTHOP_FLAG_DUPLICATE)) + continue; + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) SET_FLAG(nexthop->flags, diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b176ea2fe6c5..142f83fb366d 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1659,6 +1659,9 @@ static bool rib_update_nhg_from_ctx(struct nexthop_group *re_nhg, if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) continue; + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) + continue; + /* Check for a FIB nexthop corresponding to the RIB nexthop */ if (!nexthop_same(ctx_nexthop, nexthop)) { /* If the FIB doesn't know about the nexthop, From 54b72028c6059c8c69ec77335a5e828884fffbfe Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 10 Jul 2024 09:49:51 +0200 Subject: [PATCH 388/472] ospfd: fix state location mixup In the "2x2 matrix" of these, I accidentally edited "row-wise" when I should've edited "column-wise"... *sigh* Reported-by: github.com/rbfnet Fixes: #16349 Fixes: 110945ba0d2 ("ospfd: fix GR state location") Signed-off-by: David Lamparter --- ospfd/ospf_main.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index fdb4e5c5875f..5c11027506dd 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -48,14 +48,20 @@ #include "ospfd/ospf_apiserver.h" #define OSPFD_STATE_NAME "%s/ospfd.json", frr_libstatedir -#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i +#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_libstatedir, i /* this one includes the path... because the instance number was in the path * before :( ... which totally didn't have a mkdir anywhere. + * + * ... and libstatedir & runstatedir got switched around while changing this; + * for non-instance it read the wrong path, for instance it wrote the wrong + * path. (There is no COMPAT2 for non-instance because it was writing to the + * right place, i.e. no extra path to check exists from reading a wrong path.) */ -#define OSPFD_COMPAT_STATE_NAME "%s/ospfd-gr.json", frr_libstatedir -#define OSPFD_COMPAT_INST_STATE_NAME(i) \ +#define OSPFD_COMPAT_STATE_NAME "%s/ospfd-gr.json", frr_runstatedir +#define OSPFD_COMPAT1_INST_STATE_NAME(i) \ "%s-%d/ospfd-gr.json", frr_runstatedir, i +#define OSPFD_COMPAT2_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_runstatedir, i /* ospfd privileges */ zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_NET_ADMIN, @@ -139,10 +145,12 @@ static const struct frr_yang_module_info *const ospfd_yang_modules[] = { /* actual paths filled in main() */ static char state_path[512]; -static char state_compat_path[512]; +static char state_compat1_path[512]; +static char state_compat2_path[512]; static char *state_paths[] = { state_path, - state_compat_path, + state_compat1_path, + state_compat2_path, /* NULLed out if not needed */ NULL, }; @@ -242,12 +250,18 @@ int main(int argc, char **argv) if (ospf_instance) { snprintf(state_path, sizeof(state_path), OSPFD_INST_STATE_NAME(ospf_instance)); - snprintf(state_compat_path, sizeof(state_compat_path), - OSPFD_COMPAT_INST_STATE_NAME(ospf_instance)); + snprintf(state_compat1_path, sizeof(state_compat1_path), + OSPFD_COMPAT1_INST_STATE_NAME(ospf_instance)); + snprintf(state_compat2_path, sizeof(state_compat2_path), + OSPFD_COMPAT2_INST_STATE_NAME(ospf_instance)); } else { snprintf(state_path, sizeof(state_path), OSPFD_STATE_NAME); - snprintf(state_compat_path, sizeof(state_compat_path), + snprintf(state_compat1_path, sizeof(state_compat1_path), OSPFD_COMPAT_STATE_NAME); + /* no COMPAT2 here since it was reading that was broken, + * there is no additional path that would've been written + */ + state_paths[2] = NULL; } /* OSPF master init. */ From e905177a8c9d67713682d46934c7a87a0913c250 Mon Sep 17 00:00:00 2001 From: zhou-run Date: Thu, 11 Jul 2024 11:35:34 +0800 Subject: [PATCH 389/472] isisd: fix crash when calculating the neighbor spanning tree based on the fragmented LSP 1. When the root IS regenerates an LSP, it calls lsp_build() -> lsp_clear_data() to free the TLV memory of the first fragment and all other fragments. If the number of fragments in the regenerated LSP decreases or if no fragmentation is needed, the extra LSP fragments are not immediately deleted. Instead, lsp_seqno_update() -> lsp_purge() is called to set the remaining time to zero and start aging, while also notifying other IS nodes to age these fragments. lsp_purge() usually does not reset lsp->hdr.seqno to zero because the LSP might recover during the aging process. 2. When other IS nodes receive an LSP, they always call process_lsp() -> isis_unpack_tlvs() to allocate TLV memory for the LSP. This does not differentiate whether the received LSP has a remaining lifetime of zero. Therefore, it is rare for an LSP of a non-root IS to have empty TLVs. Of course, if an LSP with a remaining time of zero and already corrupted is received, lsp_update() -> lsp_purge() will be called to free the TLV memory of the LSP, but this scenario is rare. 3. In LFA calculations, neighbors of the root IS are traversed, and each neighbor is taken as a new root to compute the neighbor SPT. During this process, the old root IS will serve as a neighbor of the new root IS, triggering a call to isis_spf_process_lsp() to parse the LSP of the old root IS and obtain its IP vertices and neighboring IS vertices. However, isis_spf_process_lsp() only checks whether the TLVs in the first fragment of the LSP exist, and does not check the TLVs in the fragmented LSP. If the TLV memory of the fragmented LSP of the old root IS has been freed, it can lead to a null pointer access, causing the current crash. Additionally, for the base SPT, there are only two places where the LSP of the root IS is parsed: 1. When obtaining the UP neighbors of the root IS via spf_adj_list_parse_lsp(). 2. When preloading the IP vertices of the root IS via isis_lsp_iterate_ip_reach(). Both of these checks ensure that frag->tlvs is not null, and they do not subsequently call isis_spf_process_lsp() to parse the root IS's LSP. It is very rare for non-root IS LSPs to have empty TLVs unless they are corrupted LSPs awaiting deletion. If it happens, a crash will occur. The backtrace is as follows: (gdb) bt #0 0x00007f3097281fe1 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0 #1 0x00007f30973a2972 in core_handler (signo=11, siginfo=0x7ffce66c2870, context=0x7ffce66c2740) at ../lib/sigevent.c:261 #2 #3 0x000055dfa805512b in isis_spf_process_lsp (spftree=0x55dfa950eee0, lsp=0x55dfa94cb590, cost=10, depth=1, root_sysid=0x55dfa950ef6c "", parent=0x55dfa952fca0) at ../isisd/isis_spf.c:898 #4 0x000055dfa805743b in isis_spf_loop (spftree=0x55dfa950eee0, root_sysid=0x55dfa950ef6c "") at ../isisd/isis_spf.c:1688 #5 0x000055dfa805784f in isis_run_spf (spftree=0x55dfa950eee0) at ../isisd/isis_spf.c:1808 #6 0x000055dfa8037ff5 in isis_spf_run_neighbors (spftree=0x55dfa9474440) at ../isisd/isis_lfa.c:1259 #7 0x000055dfa803ac17 in isis_spf_run_lfa (area=0x55dfa9477510, spftree=0x55dfa9474440) at ../isisd/isis_lfa.c:2300 #8 0x000055dfa8057964 in isis_run_spf_with_protection (area=0x55dfa9477510, spftree=0x55dfa9474440) at ../isisd/isis_spf.c:1827 #9 0x000055dfa8057c15 in isis_run_spf_cb (thread=0x7ffce66c38e0) at ../isisd/isis_spf.c:1889 #10 0x00007f30973bbf04 in thread_call (thread=0x7ffce66c38e0) at ../lib/thread.c:1990 #11 0x00007f309735497b in frr_run (master=0x55dfa91733c0) at ../lib/libfrr.c:1198 #12 0x000055dfa8029d5d in main (argc=5, argv=0x7ffce66c3b08, envp=0x7ffce66c3b38) at ../isisd/isis_main.c:273 (gdb) f 3 #3 0x000055dfa805512b in isis_spf_process_lsp (spftree=0x55dfa950eee0, lsp=0x55dfa94cb590, cost=10, depth=1, root_sysid=0x55dfa950ef6c "", parent=0x55dfa952fca0) at ../isisd/isis_spf.c:898 898 ../isisd/isis_spf.c: No such file or directory. (gdb) p te_neighs $1 = (struct isis_item_list *) 0x120 (gdb) p lsp->tlvs $2 = (struct isis_tlvs *) 0x0 (gdb) p lsp->hdr $3 = {pdu_len = 27, rem_lifetime = 0, lsp_id = "\000\000\000\000\000\001\000\001", seqno = 4, checksum = 59918, lsp_bits = 1 '\001'} The backtrace provided above pertains to version 8.5.4, but it seems that the same issue exists in the code of the master branch as well. I have reviewed the process for calculating the SPT based on the LSP, and isis_spf_process_lsp() is the only function that does not check whether the TLVs in the fragments are empty. Therefore, I believe that modifying this function alone should be sufficient. If the TLVs of the current fragment are already empty, we do not need to continue processing subsequent fragments. This is consistent with the behavior where we do not process fragments if the TLVs of the first fragment are empty. Of course, one could argue that lsp_purge() should still retain the TLV memory, freeing it and then reallocating it if needed. However, this is a debatable point because in some scenarios, it is permissible for the LSP to have empty TLVs. For example, after receiving an SNP (Sequence Number PDU) message, an empty LSP (with lsp->hdr.seqno = 0) might be created by calling lsp_new. If the corresponding LSP message is discarded due to domain or area authentication failure, the TLV memory wouldn't be allocated. Test scenario: In an LFA network, importing a sufficient number of static routes to cause LSP fragmentation, and then rolling back the imported static routes so that the LSP is no longer fragmented, can easily result in this issue. Signed-off-by: zhou-run --- isisd/isis_spf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 7aa9147e71c0..86302076f82d 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -873,6 +873,9 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree, || (mt_router_info && !mt_router_info->overload)); lspfragloop: + if (!lsp->tlvs) + return ISIS_OK; + if (lsp->hdr.seqno == 0) { zlog_warn("%s: lsp with 0 seq_num - ignore", __func__); return ISIS_WARNING; From 6ade526f7b14a725d61c98700d403dea050ccd85 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Thu, 11 Jul 2024 05:38:36 +0200 Subject: [PATCH 390/472] lib: add some quick explainers for path vars It's not immediately obvious what exactly the `frr_*dir` variables exported from lib/libfrr.c are for. Add a little text each to clarify. Signed-off-by: David Lamparter --- lib/libfrr.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/lib/libfrr.h b/lib/libfrr.h index db9cfbcb1f2b..8018672c1ae7 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -222,10 +222,39 @@ extern void frr_fini(void); extern char config_default[512]; extern char frr_zclientpath[512]; + +/* refer to lib/config_paths.h (generated during ./configure) for build config + * values of the following: + */ + +/* sysconfdir is generally /etc/frr/, some BSDs may use /usr/local/etc/frr/. + * Will NOT include "pathspace" (namespace) suffix from -N. (libfrr.c handles + * pathspace'ing config files.) Has a slash at the end for "historical" + * reasons. + */ extern const char frr_sysconfdir[]; + +/* runstatedir is *ephemeral* across reboots. It may either be a ramdisk, + * or be wiped during boot. Use only for pid files, sockets, and the like, + * not state. Commonly /run/frr or /var/run/frr. + * Will include "pathspace" (namespace) suffix from -N. + */ extern char frr_runstatedir[256]; + +/* libstatedir is *persistent*. It's the place to put state like sequence + * numbers or databases. Commonly /var/lib/frr. + * Will include "pathspace" (namespace) suffix from -N. + */ extern char frr_libstatedir[256]; + +/* moduledir is something along the lines of /usr/lib/frr/modules or + * /usr/lib/x86_64-linux-gnu/frr/modules. It is not guaranteed to be a + * subdirectory of the directory that the daemon binaries reside in. (e.g. + * the "x86_64-linux-gnu" component will be absent from daemon paths.) + */ extern const char frr_moduledir[]; + +/* scriptdir is for Lua scripts, generally ${frr_sysconfdir}/scripts */ extern const char frr_scriptdir[]; extern char frr_protoname[]; From 4e76df05476e728d3bdd53821c0f20e4139db1f8 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Fri, 22 Dec 2023 11:35:09 +0100 Subject: [PATCH 391/472] isis, lib: add isis srv6 end sid to ls_prefix According to draft-ietf-lsr-isis-srv6-extensions draft, the End SID should be available in link state prefix information. Add the SID information in the link state prefix, by getting the END SID from the locator TLV information. Signed-off-by: Philippe Guibert --- isisd/isis_lsp.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ isisd/isis_lsp.h | 2 ++ isisd/isis_te.c | 45 +++++++++++++++++++++++++++++++++++++++++-- isisd/isis_te.h | 1 + lib/link_state.c | 36 +++++++++++++++++++++++++++++++++- lib/link_state.h | 6 ++++++ 6 files changed, 137 insertions(+), 3 deletions(-) diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index bda7ed89a4c2..391d42fba156 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -2340,6 +2340,56 @@ static int lsp_handle_adj_state_change(struct isis_adjacency *adj) return 0; } +/* + * Iterate over all SRv6 locator TLVs + */ +int isis_lsp_iterate_srv6_locator(struct isis_lsp *lsp, uint16_t mtid, + lsp_ip_reach_iter_cb cb, void *arg) +{ + bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id); + struct isis_lsp *frag; + struct listnode *node; + + if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0) + return LSP_ITER_CONTINUE; + + /* Parse LSP */ + if (lsp->tlvs) { + if (!pseudo_lsp) { + struct isis_item_list *srv6_locator_reachs; + struct isis_srv6_locator_tlv *r; + + srv6_locator_reachs = + isis_lookup_mt_items(&lsp->tlvs->srv6_locator, + mtid); + + for (r = srv6_locator_reachs + ? (struct isis_srv6_locator_tlv *) + srv6_locator_reachs->head + : NULL; + r; r = r->next) { + if ((*cb)((struct prefix *)&r->prefix, + r->metric, false /* ignore */, + r->subtlvs, arg) == LSP_ITER_STOP) + return LSP_ITER_STOP; + } + } + } + + /* Parse LSP fragments if it is not a fragment itself */ + if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) + for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { + if (!frag->tlvs) + continue; + + if (isis_lsp_iterate_srv6_locator(frag, mtid, cb, + arg) == LSP_ITER_STOP) + return LSP_ITER_STOP; + } + + return LSP_ITER_CONTINUE; +} + /* * Iterate over all IP reachability TLVs in a LSP (all fragments) of the given * address-family and MT-ID. diff --git a/isisd/isis_lsp.h b/isisd/isis_lsp.h index 3839a9504c05..15db88b02f36 100644 --- a/isisd/isis_lsp.h +++ b/isisd/isis_lsp.h @@ -143,6 +143,8 @@ int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid, lsp_ip_reach_iter_cb cb, void *arg); int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid, lsp_is_reach_iter_cb cb, void *arg); +int isis_lsp_iterate_srv6_locator(struct isis_lsp *lsp, uint16_t mtid, + lsp_ip_reach_iter_cb cb, void *arg); #define lsp_flood(lsp, circuit) \ _lsp_flood((lsp), (circuit), __func__, __FILE__, __LINE__) diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 3683f7455821..bb73a4425774 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -1258,8 +1258,11 @@ static int lsp_to_subnet_cb(const struct prefix *prefix, uint32_t metric, if (!args || !prefix) return LSP_ITER_CONTINUE; - te_debug(" |- Process Extended %s Reachability %pFX", - prefix->family == AF_INET ? "IP" : "IPv6", prefix); + if (args->srv6_locator) + te_debug(" |- Process SRv6 Locator %pFX", prefix); + else + te_debug(" |- Process Extended %s Reachability %pFX", + prefix->family == AF_INET ? "IP" : "IPv6", prefix); vertex = args->vertex; @@ -1386,6 +1389,38 @@ static int lsp_to_subnet_cb(const struct prefix *prefix, uint32_t metric, } } + /* Update SRv6 SID and locator if any */ + if (subtlvs && subtlvs->srv6_end_sids.count != 0) { + struct isis_srv6_end_sid_subtlv *psid; + struct ls_srv6_sid sr = {}; + + psid = (struct isis_srv6_end_sid_subtlv *) + subtlvs->srv6_end_sids.head; + sr.behavior = psid->behavior; + sr.flags = psid->flags; + memcpy(&sr.sid, &psid->sid, sizeof(struct in6_addr)); + + if (!CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6) || + memcmp(&ls_pref->srv6, &sr, sizeof(struct ls_srv6_sid))) { + memcpy(&ls_pref->srv6, &sr, sizeof(struct ls_srv6_sid)); + SET_FLAG(ls_pref->flags, LS_PREF_SRV6); + if (subnet->status != NEW) + subnet->status = UPDATE; + } else { + if (subnet->status == ORPHAN) + subnet->status = SYNC; + } + } else { + if (CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6)) { + UNSET_FLAG(ls_pref->flags, LS_PREF_SRV6); + if (subnet->status != NEW) + subnet->status = UPDATE; + } else { + if (subnet->status == ORPHAN) + subnet->status = SYNC; + } + } + /* Update status and Export Link State Edge if needed */ if (subnet->status != SYNC) { if (args->export) @@ -1454,12 +1489,18 @@ static void isis_te_parse_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp) &args); /* Process all Extended IP (v4 & v6) in LSP (all fragments) */ + args.srv6_locator = false; isis_lsp_iterate_ip_reach(lsp, AF_INET, ISIS_MT_IPV4_UNICAST, lsp_to_subnet_cb, &args); isis_lsp_iterate_ip_reach(lsp, AF_INET6, ISIS_MT_IPV6_UNICAST, lsp_to_subnet_cb, &args); isis_lsp_iterate_ip_reach(lsp, AF_INET6, ISIS_MT_IPV4_UNICAST, lsp_to_subnet_cb, &args); + args.srv6_locator = true; + isis_lsp_iterate_srv6_locator(lsp, ISIS_MT_STANDARD, lsp_to_subnet_cb, + &args); + isis_lsp_iterate_srv6_locator(lsp, ISIS_MT_IPV6_UNICAST, + lsp_to_subnet_cb, &args); /* Clean remaining Orphan Edges or Subnets */ if (IS_EXPORT_TE(mta)) diff --git a/isisd/isis_te.h b/isisd/isis_te.h index bf1dc2b9bbbd..532a24e7e406 100644 --- a/isisd/isis_te.h +++ b/isisd/isis_te.h @@ -103,6 +103,7 @@ struct isis_te_args { struct ls_ted *ted; struct ls_vertex *vertex; bool export; + bool srv6_locator; }; enum lsp_event { LSP_UNKNOWN, LSP_ADD, LSP_UPD, LSP_DEL, LSP_INC, LSP_TICK }; diff --git a/lib/link_state.c b/lib/link_state.c index c758b7f57517..3d96c75f6d1e 100644 --- a/lib/link_state.c +++ b/lib/link_state.c @@ -414,6 +414,13 @@ int ls_prefix_same(struct ls_prefix *p1, struct ls_prefix *p2) || (p1->sr.sid_flag != p2->sr.sid_flag)) return 0; } + if (CHECK_FLAG(p1->flags, LS_PREF_SRV6)) { + if (memcmp(&p1->srv6.sid, &p2->srv6.sid, + sizeof(struct in6_addr)) || + (p1->srv6.flags != p2->srv6.flags) || + (p1->srv6.behavior != p2->srv6.behavior)) + return 0; + } /* OK, p1 & p2 are equal */ return 1; @@ -1388,6 +1395,11 @@ static struct ls_prefix *ls_parse_prefix(struct stream *s) STREAM_GETC(s, ls_pref->sr.sid_flag); STREAM_GETC(s, ls_pref->sr.algo); } + if (CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6)) { + STREAM_GET(&ls_pref->srv6.sid, s, sizeof(struct in6_addr)); + STREAM_GETW(s, ls_pref->srv6.behavior); + STREAM_GETC(s, ls_pref->srv6.flags); + } return ls_pref; @@ -1632,6 +1644,11 @@ static int ls_format_prefix(struct stream *s, struct ls_prefix *ls_pref) stream_putc(s, ls_pref->sr.sid_flag); stream_putc(s, ls_pref->sr.algo); } + if (CHECK_FLAG(ls_pref->flags, LS_PREF_SRV6)) { + stream_put(s, &ls_pref->srv6.sid, sizeof(struct in6_addr)); + stream_putw(s, ls_pref->srv6.behavior); + stream_putc(s, ls_pref->srv6.flags); + } return 0; } @@ -2748,6 +2765,13 @@ static void ls_show_subnet_vty(struct ls_subnet *subnet, struct vty *vty, sbuf_push(&sbuf, 4, "SID: %d\tAlgorithm: %d\tFlags: 0x%x\n", pref->sr.sid, pref->sr.algo, pref->sr.sid_flag); + if (CHECK_FLAG(pref->flags, LS_PREF_SRV6)) + sbuf_push(&sbuf, 4, + "SIDv6: %pI6\tEndpoint behavior: %s\tFlags: 0x%x\n", + &pref->srv6.sid, + seg6local_action2str(pref->srv6.behavior), + pref->srv6.flags); + end: vty_out(vty, "%s\n", sbuf_buf(&sbuf)); sbuf_free(&sbuf); @@ -2757,7 +2781,7 @@ static void ls_show_subnet_json(struct ls_subnet *subnet, struct json_object *json) { struct ls_prefix *pref; - json_object *jsr; + json_object *jsr, *jsrv6; char buf[INET6_BUFSIZ]; pref = subnet->ls_pref; @@ -2787,6 +2811,16 @@ static void ls_show_subnet_json(struct ls_subnet *subnet, snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->sr.sid_flag); json_object_string_add(jsr, "flags", buf); } + if (CHECK_FLAG(pref->flags, LS_PREF_SRV6)) { + jsrv6 = json_object_new_object(); + json_object_object_add(json, "segment-routing-ipv6", jsrv6); + snprintfrr(buf, INET6_BUFSIZ, "%pI6", &pref->srv6.sid); + json_object_string_add(jsrv6, "sid", buf); + json_object_string_add(jsrv6, "behavior", + seg6local_action2str(pref->srv6.behavior)); + snprintfrr(buf, INET6_BUFSIZ, "0x%x", pref->srv6.flags); + json_object_string_add(jsrv6, "flags", buf); + } } void ls_show_subnet(struct ls_subnet *subnet, struct vty *vty, diff --git a/lib/link_state.h b/lib/link_state.h index d819c20db763..c54e2ec6d904 100644 --- a/lib/link_state.h +++ b/lib/link_state.h @@ -243,6 +243,7 @@ struct ls_attributes { #define LS_PREF_EXTENDED_TAG 0x04 #define LS_PREF_METRIC 0x08 #define LS_PREF_SR 0x10 +#define LS_PREF_SRV6 0x20 /* Link State Prefix */ struct ls_prefix { @@ -258,6 +259,11 @@ struct ls_prefix { uint8_t sid_flag; /* Segment Routing Flags */ uint8_t algo; /* Algorithm for Segment Routing */ } sr; + struct ls_srv6_sid { + struct in6_addr sid; /* Segment Routing ID */ + uint16_t behavior; /* Endpoint behavior bound to the SID */ + uint8_t flags; /* Flags */ + } srv6; }; /** From 728f2942f96e258c1dfc101e228f0ccccd14292d Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Thu, 11 Jul 2024 22:31:22 +0530 Subject: [PATCH 392/472] yang: Added default value to leaf Added default value to yang Signed-off-by: y-bharath14 --- yang/frr-zebra.yang | 1 + 1 file changed, 1 insertion(+) diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang index 79c524a40a94..1c7d1c8ef4dc 100644 --- a/yang/frr-zebra.yang +++ b/yang/frr-zebra.yang @@ -626,6 +626,7 @@ module frr-zebra { leaf table-id { type uint32; + default "254"; description "Routing Table id (default id - 254)."; } From 4518d386f7683289b079708fcdb0c42ced4754d9 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Fri, 12 Jul 2024 17:03:03 +0800 Subject: [PATCH 393/472] zebra: fix missing static routes Use `vtysh` with this input file: ``` ip route A nh1 ip route A nh2 ip route B nh1 ip route B nh2 ``` When running "ip route B" with "nh1" and "nh2", the procedure maybe is: 1) Create the two nexthops: "nh1" and "nh2". 2) Register "nh1" with `static_zebra_nht_register()`, then the states of both "nh1" and "nht2" are set to "STATIC_SENT_TO_ZEBRA". 3) Register "nh2" with `static_zebra_nht_register()`, then only the routes with nexthop of "STATIC_START" will be sent to zebra. So, send the routes with the nexthop of "STATIC_SENT_TO_ZEBRA" to zebra. Signed-off-by: anlan_cs --- staticd/static_zebra.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index c4efc14a9d55..420ed7903bbc 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -341,7 +341,8 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg) /* refresh with existing data */ afi_t afi = prefix_afi(&lookup.nh); - if (nh->state == STATIC_NOT_INSTALLED) + if (nh->state == STATIC_NOT_INSTALLED || + nh->state == STATIC_SENT_TO_ZEBRA) nh->state = STATIC_START; static_nht_update(&rn->p, &nhtd->nh, nhtd->nh_num, afi, si->safi, nh->nh_vrf_id); From ad7a1f9487edc75fbfaf932e929a008c8bcbc4f9 Mon Sep 17 00:00:00 2001 From: Jafar Al-Gharaibeh Date: Wed, 10 Jul 2024 14:18:51 -0500 Subject: [PATCH 394/472] tests: tweak timers to avoid frequent failures on slow CI hardware Signed-off-by: Jafar Al-Gharaibeh --- .../ospf_metric_propagation/r1/frr.conf | 6 +++--- .../r1/show_ip_route-1.json | 19 +------------------ .../r1/show_ip_route-2.json | 19 +------------------ .../r1/show_ip_route-3.json | 19 +------------------ .../r1/show_ip_route-4.json | 19 +------------------ .../r1/show_ip_route-5.json | 19 +------------------ .../r1/show_ip_route-6.json | 19 +------------------ .../ospf_metric_propagation/r2/frr.conf | 6 +++--- .../ospf_metric_propagation/r3/frr.conf | 6 +++--- .../ospf_metric_propagation/r4/frr.conf | 6 +++--- .../ospf_metric_propagation/ra/frr.conf | 6 +++--- .../ospf_metric_propagation/rb/frr.conf | 6 +++--- .../ospf_metric_propagation/rc/frr.conf | 4 ++-- .../test_ospf_metric_propagation.py | 12 ++++++------ 14 files changed, 32 insertions(+), 134 deletions(-) diff --git a/tests/topotests/ospf_metric_propagation/r1/frr.conf b/tests/topotests/ospf_metric_propagation/r1/frr.conf index 85230494dd15..4966e6a9da1b 100644 --- a/tests/topotests/ospf_metric_propagation/r1/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r1/frr.conf @@ -8,18 +8,18 @@ interface r1-eth0 ip address 10.0.1.1/24 ip ospf cost 100 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface r1-eth1 vrf blue ip address 10.0.10.1/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! ! interface r1-eth2 vrf green ip address 10.0.91.1/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! ! router ospf diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json index 4f1ced81fb7b..2392b40fa985 100644 --- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json +++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-1.json @@ -2,32 +2,15 @@ "10.0.94.0/24":[ { "prefix":"10.0.94.0/24", - "prefixLen":24, "protocol":"bgp", "vrfName":"green", - "selected":true, - "destSelected":true, - "distance":20, "metric":34, "installed":true, - "table":12, - "internalStatus":16, - "internalFlags":8, - "internalNextHopNum":1, - "internalNextHopActiveNum":1, - "nexthopGroupId":"*", - "installedNexthopGroupId":"*", - "uptime":"*", "nexthops":[ { - "flags":3, - "fib":true, "ip":"10.0.10.5", - "afi":"ipv4", "interfaceName":"r1-eth1", - "vrf":"blue", - "active":true, - "weight":1 + "vrf":"blue" } ] } diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json index 882d3ca4f09b..9a3d3d87b75f 100644 --- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json +++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-2.json @@ -2,32 +2,15 @@ "10.0.94.0/24":[ { "prefix":"10.0.94.0/24", - "prefixLen":24, "protocol":"bgp", "vrfName":"green", - "selected":true, - "destSelected":true, - "distance":20, "metric":136, "installed":true, - "table":12, - "internalStatus":16, - "internalFlags":8, - "internalNextHopNum":1, - "internalNextHopActiveNum":1, - "nexthopGroupId":"*", - "installedNexthopGroupId":"*", - "uptime":"*", "nexthops":[ { - "flags":3, - "fib":true, "ip":"10.0.1.2", - "afi":"ipv4", "interfaceName":"r1-eth0", - "vrf":"default", - "active":true, - "weight":1 + "vrf":"default" } ] } diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json index cd528459ab23..5f0331f3cd5b 100644 --- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json +++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-3.json @@ -2,32 +2,15 @@ "10.0.94.0/24":[ { "prefix":"10.0.94.0/24", - "prefixLen":24, "protocol":"bgp", "vrfName":"green", - "selected":true, - "destSelected":true, - "distance":20, "metric":1138, "installed":true, - "table":12, - "internalStatus":16, - "internalFlags":8, - "internalNextHopNum":1, - "internalNextHopActiveNum":1, - "nexthopGroupId":"*", - "installedNexthopGroupId":"*", - "uptime":"*", "nexthops":[ { - "flags":3, - "fib":true, "ip":"10.0.1.2", - "afi":"ipv4", "interfaceName":"r1-eth0", - "vrf":"default", - "active":true, - "weight":1 + "vrf":"default" } ] } diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json index 133f37549e16..f312291e8627 100644 --- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json +++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-4.json @@ -2,32 +2,15 @@ "10.0.94.0/24":[ { "prefix":"10.0.94.0/24", - "prefixLen":24, "protocol":"bgp", "vrfName":"green", - "selected":true, - "destSelected":true, - "distance":20, "metric":1218, "installed":true, - "table":12, - "internalStatus":16, - "internalFlags":8, - "internalNextHopNum":1, - "internalNextHopActiveNum":1, - "nexthopGroupId":"*", - "installedNexthopGroupId":"*", - "uptime":"*", "nexthops":[ { - "flags":3, - "fib":true, "ip":"10.0.1.2", - "afi":"ipv4", "interfaceName":"r1-eth0", - "vrf":"default", - "active":true, - "weight":1 + "vrf":"default" } ] } diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json index 5d8050902144..e88c0371743c 100644 --- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json +++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-5.json @@ -2,32 +2,15 @@ "10.0.94.0/24":[ { "prefix":"10.0.94.0/24", - "prefixLen":24, "protocol":"bgp", "vrfName":"green", - "selected":true, - "destSelected":true, - "distance":20, "metric":238, "installed":true, - "table":12, - "internalStatus":16, - "internalFlags":8, - "internalNextHopNum":1, - "internalNextHopActiveNum":1, - "nexthopGroupId":"*", - "installedNexthopGroupId":"*", - "uptime":"*", "nexthops":[ { - "flags":3, - "fib":true, "ip":"10.0.1.2", - "afi":"ipv4", "interfaceName":"r1-eth0", - "vrf":"default", - "active":true, - "weight":1 + "vrf":"default" } ] } diff --git a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json index 1b59707b98f2..f1fec860a9d3 100644 --- a/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json +++ b/tests/topotests/ospf_metric_propagation/r1/show_ip_route-6.json @@ -2,32 +2,15 @@ "10.0.94.0/24":[ { "prefix":"10.0.94.0/24", - "prefixLen":24, "protocol":"bgp", "vrfName":"green", - "selected":true, - "destSelected":true, - "distance":20, "metric":136, "installed":true, - "table":12, - "internalStatus":16, - "internalFlags":8, - "internalNextHopNum":1, - "internalNextHopActiveNum":1, - "nexthopGroupId":"*", - "installedNexthopGroupId":"*", - "uptime":"*", "nexthops":[ { - "flags":3, - "fib":true, "ip":"10.0.10.5", - "afi":"ipv4", "interfaceName":"r1-eth1", - "vrf":"blue", - "active":true, - "weight":1 + "vrf":"blue" } ] } diff --git a/tests/topotests/ospf_metric_propagation/r2/frr.conf b/tests/topotests/ospf_metric_propagation/r2/frr.conf index e67a374ff552..0ac5001b1b99 100644 --- a/tests/topotests/ospf_metric_propagation/r2/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r2/frr.conf @@ -8,18 +8,18 @@ interface r2-eth0 ip address 10.0.1.2/24 ip ospf cost 100 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface r2-eth1 vrf blue ip address 10.0.20.2/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface r2-eth2 vrf green ip address 10.0.70.2/24 ip ospf cost 1000 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! router ospf ospf router-id 10.0.255.2 diff --git a/tests/topotests/ospf_metric_propagation/r3/frr.conf b/tests/topotests/ospf_metric_propagation/r3/frr.conf index 175851d42763..0859173f7971 100644 --- a/tests/topotests/ospf_metric_propagation/r3/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r3/frr.conf @@ -8,18 +8,18 @@ interface r3-eth0 ip address 10.0.3.3/24 ip ospf cost 100 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface r3-eth1 vrf blue ip address 10.0.30.3/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface r3-eth2 vrf green ip address 10.0.80.3/24 ip ospf cost 1000 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! router ospf ospf router-id 10.0.255.3 diff --git a/tests/topotests/ospf_metric_propagation/r4/frr.conf b/tests/topotests/ospf_metric_propagation/r4/frr.conf index 70a47e34fa67..743da272727f 100644 --- a/tests/topotests/ospf_metric_propagation/r4/frr.conf +++ b/tests/topotests/ospf_metric_propagation/r4/frr.conf @@ -8,17 +8,17 @@ interface r4-eth0 ip address 10.0.3.4/24 ip ospf cost 100 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface r4-eth1 vrf blue ip address 10.0.40.4/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface r4-eth2 vrf green ip address 10.0.94.4/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! router ospf ospf router-id 10.0.255.4 diff --git a/tests/topotests/ospf_metric_propagation/ra/frr.conf b/tests/topotests/ospf_metric_propagation/ra/frr.conf index 7be9e5c33e90..2434faeabc97 100644 --- a/tests/topotests/ospf_metric_propagation/ra/frr.conf +++ b/tests/topotests/ospf_metric_propagation/ra/frr.conf @@ -7,17 +7,17 @@ ip forwarding interface ra-eth0 ip address 10.0.50.5/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface ra-eth1 ip address 10.0.10.5/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface ra-eth2 ip address 10.0.20.5/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! router ospf ospf router-id 10.0.255.5 diff --git a/tests/topotests/ospf_metric_propagation/rb/frr.conf b/tests/topotests/ospf_metric_propagation/rb/frr.conf index a7dbf82278ce..b83532a8405a 100644 --- a/tests/topotests/ospf_metric_propagation/rb/frr.conf +++ b/tests/topotests/ospf_metric_propagation/rb/frr.conf @@ -7,17 +7,17 @@ ip forwarding interface rb-eth0 ip address 10.0.50.6/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface rb-eth1 ip address 10.0.30.6/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface rb-eth2 ip address 10.0.40.6/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! router ospf ospf router-id 10.0.255.6 diff --git a/tests/topotests/ospf_metric_propagation/rc/frr.conf b/tests/topotests/ospf_metric_propagation/rc/frr.conf index f5a2ed7c4f17..dd8077c3949f 100644 --- a/tests/topotests/ospf_metric_propagation/rc/frr.conf +++ b/tests/topotests/ospf_metric_propagation/rc/frr.conf @@ -7,12 +7,12 @@ ip forwarding interface rc-eth0 ip address 10.0.70.7/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! interface rc-eth1 ip address 10.0.80.7/24 ip ospf hello-interval 1 - ip ospf dead-interval 30 + ip ospf dead-interval 40 ! router ospf ospf router-id 10.0.255.7 diff --git a/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py b/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py index b9c63622f019..b97b86bff9a3 100644 --- a/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py +++ b/tests/topotests/ospf_metric_propagation/test_ospf_metric_propagation.py @@ -282,7 +282,7 @@ def test_link_1_2_3_4_down(): assert result is None, assertmsg -def test_link_1_2_4_down(): +def test_link_1_2_4_down_3_up(): "Test path R1 -> R2 -> Rc -> R3 -> R4" tgen = get_topogen() @@ -304,7 +304,7 @@ def test_link_1_2_4_down(): assert result is None, assertmsg -def test_link_1_4_down(): +def test_link_1_4_down_2_up(): "Test path R1 -> R2 -> Ra -> Rb -> R3 -> R4" tgen = get_topogen() @@ -320,13 +320,13 @@ def test_link_1_4_down(): test_func = partial( topotest.router_json_cmp, r1, "show ip route vrf green 10.0.94.2 json", expected ) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=2) assertmsg = "r1 JSON output mismatches" assert result is None, assertmsg -def test_link_4_down(): +def test_link_4_down_1_up(): "Test path R1 -> Ra -> Rb -> R3 -> R4" tgen = get_topogen() @@ -342,7 +342,7 @@ def test_link_4_down(): test_func = partial( topotest.router_json_cmp, r1, "show ip route vrf green 10.0.94.2 json", expected ) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=2) assertmsg = "r1 JSON output mismatches" assert result is None, assertmsg @@ -364,7 +364,7 @@ def test_link_1_2_3_4_up(): test_func = partial( topotest.router_json_cmp, r1, "show ip route vrf green 10.0.94.2 json", expected ) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=2) assertmsg = "r1 JSON output mismatches" assert result is None, assertmsg From c77e15710d6a3a9be71f41a9ce608f06b2795dfb Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Fri, 5 Jul 2024 16:02:12 -0700 Subject: [PATCH 395/472] zebra: Fix to avoid two Vrfs with same table ids During internal testing, when the following sequence is followed, two non default vrfs end up pointing to the same table-id - Initially vrf201 has table id 1002 - ip link add dev vrf202 type vrf table 1002 - ip link set dev vrf202 up - ip link set dev master vrf202 This will ideally lead to zebra exit since this is a misconfiguration as expected. However if we perform a restart frr.service at this point, we end up having two vrfs pointing to same table-id and bad things can happen. This is because in the interface_vrf_change, we incorrectly check for vrf_lookup_by_id() to evaluate if there is a misconfig. This works well for a non restart case but not for the startup case. root@mlx-3700-20:mgmt:/var/log/frr# sudo vtysh -c "sh vrf" vrf mgmt id 37 table 1001 vrf vrf201 id 46 table 1002 vrf vrf202 id 59 table 1002 >>>> Fix: in all cases of misconfiguration, exit zebra as expected. Ticket :#3970414 Signed-off-by: Donald Sharp Signed-off-by: Rajasekar Raja --- zebra/interface.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/zebra/interface.c b/zebra/interface.c index f1f24cc29f16..b3adc4483ee9 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1483,23 +1483,27 @@ static void interface_vrf_change(enum dplane_op_e op, ifindex_t ifindex, "DPLANE_OP_INTF_UPDATE for VRF %s(%u) table %u", name, ifindex, tableid); - if (!vrf_lookup_by_id((vrf_id_t)ifindex)) { - vrf_id_t exist_id; - - exist_id = zebra_vrf_lookup_by_table(tableid, ns_id); - if (exist_id != VRF_DEFAULT) { - vrf = vrf_lookup_by_id(exist_id); - - if (vrf) - flog_err(EC_ZEBRA_VRF_MISCONFIGURED, - "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting", - name, ifindex, vrf->name, - vrf->vrf_id); - else - flog_err(EC_ZEBRA_VRF_NOT_FOUND, - "VRF %s id %u does not exist", - name, ifindex); + /* + * For a given tableid, if there already exists a vrf and it + * is different from the current vrf to be operated, then there + * is a misconfiguration and zebra will exit. + */ + vrf_id_t exist_id = zebra_vrf_lookup_by_table(tableid, ns_id); + + if (exist_id != VRF_DEFAULT) { + vrf = vrf_lookup_by_id(exist_id); + + if (!vrf_lookup_by_id((vrf_id_t)ifindex) && !vrf) { + flog_err(EC_ZEBRA_VRF_NOT_FOUND, + "VRF %s id %u does not exist", name, + ifindex); + exit(-1); + } + if (vrf && strcmp(name, vrf->name)) { + flog_err(EC_ZEBRA_VRF_MISCONFIGURED, + "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting", + name, ifindex, vrf->name, vrf->vrf_id); exit(-1); } } From 5b06a17715c63f7639640a97be338ace8fc76f79 Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Wed, 19 Jun 2024 12:51:05 +0530 Subject: [PATCH 396/472] tests: Refactoring FRR test suites Signed-off-by: y-bharath14 --- .../test_all_protocol_startup.py | 2 -- .../topotests/babel_topo1/test_babel_topo1.py | 2 -- .../bfd_ospf_topo1/test_bfd_ospf_topo1.py | 1 - .../test_bgp_6vpe_ebgp_topo1.py | 1 - .../test_bgp_addpath_paths_limit.py | 2 +- tests/topotests/bgp_aigp/test_bgp_aigp.py | 1 - .../bgp_as_allow_in/test_bgp_as_allow_in.py | 3 +-- tests/topotests/bgp_auth/bgp_auth_common.py | 13 +++------- tests/topotests/bgp_auth/test_bgp_auth1.py | 4 +--- tests/topotests/bgp_auth/test_bgp_auth2.py | 4 +--- tests/topotests/bgp_auth/test_bgp_auth3.py | 4 +--- tests/topotests/bgp_auth/test_bgp_auth4.py | 4 +--- tests/topotests/bgp_bmp/test_bgp_bmp.py | 1 - .../test_bgp_color_extcommunities.py | 1 - .../test_bgp_communities_topo2.py | 1 - ..._conditional_advertisement_static_route.py | 3 +-- .../test_bgp_dampening_per_peer.py | 1 - .../test_bgp_default_originate_2links.py | 6 +---- .../test_bgp_default_originate_topo1_1.py | 16 ------------- .../test_bgp_default_originate_topo1_2.py | 12 ---------- .../test_default_orginate_vrf.py | 18 -------------- ..._default_originate_conditional_routemap.py | 1 - .../test_bgp_admin_dist.py | 9 ------- .../test_bgp_dynamic_capability_addpath.py | 3 +-- .../test_bgp_dynamic_capability_fqdn.py | 3 +-- ...bgp_dynamic_capability_graceful_restart.py | 3 +-- .../test_bgp_dynamic_capability_orf.py | 3 +-- .../test_bgp_dynamic_capability_role.py | 3 +-- ...bgp_dynamic_capability_software_version.py | 2 +- .../bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py | 5 +--- .../test_bgp_evpn_maximum_prefix.py | 3 +-- tests/topotests/bgp_evpn_mh/test_evpn_mh.py | 2 +- .../test_bgp_evpn_overlay_index_gateway.py | 2 +- .../test_bgp_evpn_route_map_match.py | 4 +--- .../test_bgp_extcomm-list_delete.py | 1 - .../test_bgp_extended_link_bandwidth.py | 3 +-- .../bgp_features/test_bgp_features.py | 1 - .../test_bgp_gr_functionality_topo1-1.py | 1 - .../test_bgp_gr_functionality_topo1-2.py | 2 -- .../test_bgp_gr_functionality_topo1-3.py | 1 - .../test_bgp_gr_functionality_topo1-4.py | 3 --- .../test_bgp_gr_functionality_topo2-1.py | 5 +--- .../test_bgp_gr_functionality_topo2-2.py | 4 +--- .../test_bgp_gr_functionality_topo2-3.py | 5 +--- .../test_bgp_gr_functionality_topo2-4.py | 7 +----- .../test_bgp_gr_functionality_topo3.py | 24 ++----------------- ...p_gr_per_neighbor_restart_retain_routes.py | 2 +- .../test_bgp_gr_restart_retain_routes.py | 2 +- .../test_rfc5549_ebgp_unnumbered_nbr.py | 2 +- .../test_bgp_l3vpn_label_export.py | 2 +- ...t_bgp_labeled_unicast_default_originate.py | 1 - tests/topotests/bgp_llgr/test_bgp_llgr.py | 1 - .../bgp_local_asn/test_bgp_local_asn_agg.py | 1 - .../bgp_local_asn/test_bgp_local_asn_ecmp.py | 2 -- .../bgp_local_asn/test_bgp_local_asn_topo1.py | 1 - .../bgp_local_asn/test_bgp_local_asn_topo2.py | 1 - .../test_bgp_local_asn_vrf_topo1.py | 1 - .../test_bgp_local_asn_vrf_topo2.py | 1 - .../test_bgp_local_asn_dot_agg.py | 1 - .../test_bgp_local_asn_dot_ecmp.py | 2 -- .../test_bgp_local_asn_dot_topo1.py | 1 - .../test_bgp_multi_vrf_topo2.py | 6 ++--- .../test_nexthop_mp_ipv4_6.py | 1 - .../test_bgp_node_target_extcommunities.py | 2 +- tests/topotests/bgp_oad/test_bgp_oad.py | 4 +--- .../test_bgp_path_attribute_discard.py | 2 +- .../bgp_prefix_sid2/test_bgp_prefix_sid2.py | 2 +- .../test_bgp_redistribute_table.py | 2 +- .../test_bgp_remove_private_as.py | 1 - .../test_bgp_remove_private_as_route_map.py | 3 +-- .../test_bgp_roles_capability.py | 17 ++++--------- .../test_bgp_roles_filtering.py | 11 +++------ .../test_bgp_aggregation.py | 2 +- ...est_bgp_route_map_match_source_protocol.py | 2 +- .../test_bgp_route_map_match_tag_untagged.py | 2 +- .../test_bgp_route_map_vpn_import.py | 1 - .../test_bgp_route_origin_parser.py | 1 - .../bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py | 1 - .../test_bgp_snmp_mplsvpn.py | 1 - .../test_bgp_srv6_sid_reachability.py | 5 ---- .../test_bgp_srv6l3vpn_over_ipv6.py | 5 ---- .../test_bgp_srv6l3vpn_route_leak.py | 3 --- .../test_bgp_srv6l3vpn_sid.py | 1 - .../test_bgp_srv6l3vpn_to_bgp_vrf2.py | 1 - .../bgp_suppress_fib/test_bgp_suppress_fib.py | 1 - .../bgp_tcp_mss/test_bgp_vrf_tcp_mss.py | 23 +----------------- .../test_bgp_tcp_mss_passive.py | 2 +- .../bgp_unnumbered/test_bgp_unnumbered.py | 1 - .../test_bgp_vpn_5549_route_map.py | 1 - .../bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py | 2 +- .../test_bgp_vpnv4_noretain.py | 4 ++-- .../test_bgp_vpnv4_per_nexthop_label.py | 4 ++-- .../test_bgp_vpnv6_per_nexthop_label.py | 6 ++--- .../test_bgp_vrf_dynamic_route_leak_topo2.py | 3 +-- .../test_bgp_vrf_dynamic_route_leak_topo3.py | 2 -- ...test_bgp_vrf_dynamic_route_leak_topo4-1.py | 6 ----- ...test_bgp_vrf_dynamic_route_leak_topo4-2.py | 6 ----- ...test_bgp_vrf_dynamic_route_leak_topo4-3.py | 6 ----- .../test_bgp_vrf_leaking.py | 3 --- .../test_bgp_vrf_lite_best_path_topo1.py | 2 -- .../test_bgp_vrf_lite_best_path_topo2.py | 1 - 101 files changed, 64 insertions(+), 306 deletions(-) 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 b4bc1e14ad6a..902343ce4223 100644 --- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py +++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py @@ -38,7 +38,6 @@ required_linux_kernel_version, ) -from lib.topolog import logger import json fatal_error = "" @@ -153,7 +152,6 @@ def test_error_messages_vtysh(): print("\n\n** Check for error messages on VTYSH") print("******************************************\n") - failures = 0 for i in range(1, 2): # # First checking Standard Output diff --git a/tests/topotests/babel_topo1/test_babel_topo1.py b/tests/topotests/babel_topo1/test_babel_topo1.py index decf0c2a6faf..13bbe5bd4eb8 100644 --- a/tests/topotests/babel_topo1/test_babel_topo1.py +++ b/tests/topotests/babel_topo1/test_babel_topo1.py @@ -15,7 +15,6 @@ """ import os -import re import sys import pytest import json @@ -130,7 +129,6 @@ def test_zebra_ipv4_routingTable(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - failures = 0 router_list = tgen.routers().values() for router in router_list: assertmsg = "Zebra IPv4 Routing Table verification failed for router {}".format( diff --git a/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py b/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py index b9e8b73c1d02..6919371ac521 100755 --- a/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py +++ b/tests/topotests/bfd_ospf_topo1/test_bfd_ospf_topo1.py @@ -59,7 +59,6 @@ import sys import pytest import json -from time import sleep from functools import partial # Save the Current Working Directory to find configuration files. diff --git a/tests/topotests/bgp_6vpe_ebgp_topo1/test_bgp_6vpe_ebgp_topo1.py b/tests/topotests/bgp_6vpe_ebgp_topo1/test_bgp_6vpe_ebgp_topo1.py index cbed8f089654..477cfa206bf3 100644 --- a/tests/topotests/bgp_6vpe_ebgp_topo1/test_bgp_6vpe_ebgp_topo1.py +++ b/tests/topotests/bgp_6vpe_ebgp_topo1/test_bgp_6vpe_ebgp_topo1.py @@ -12,7 +12,6 @@ import os import sys import json -import functools from functools import partial import pytest diff --git a/tests/topotests/bgp_addpath_paths_limit/test_bgp_addpath_paths_limit.py b/tests/topotests/bgp_addpath_paths_limit/test_bgp_addpath_paths_limit.py index b7a1cfbb2774..fb863e454f14 100644 --- a/tests/topotests/bgp_addpath_paths_limit/test_bgp_addpath_paths_limit.py +++ b/tests/topotests/bgp_addpath_paths_limit/test_bgp_addpath_paths_limit.py @@ -20,7 +20,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_aigp/test_bgp_aigp.py b/tests/topotests/bgp_aigp/test_bgp_aigp.py index e3b32da16476..b81c5432972d 100644 --- a/tests/topotests/bgp_aigp/test_bgp_aigp.py +++ b/tests/topotests/bgp_aigp/test_bgp_aigp.py @@ -29,7 +29,6 @@ # pylint: disable=C0413 from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py index c49a2e5384d5..537ccc9df6d0 100644 --- a/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py +++ b/tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py @@ -28,7 +28,6 @@ import os import sys import time -import json import pytest # Save the Current Working Directory to find configuration files. @@ -59,7 +58,7 @@ create_router_bgp, verify_bgp_rib, ) -from lib.topojson import build_topo_from_json, build_config_from_json +from lib.topojson import build_config_from_json pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] diff --git a/tests/topotests/bgp_auth/bgp_auth_common.py b/tests/topotests/bgp_auth/bgp_auth_common.py index 824498ef90ae..7ba3169cafb7 100644 --- a/tests/topotests/bgp_auth/bgp_auth_common.py +++ b/tests/topotests/bgp_auth/bgp_auth_common.py @@ -34,16 +34,9 @@ import json import os -import platform -import sys -from time import sleep - -from lib import common_config, topotest -from lib.common_config import ( - save_initial_config_on_routers, - reset_with_new_configs, -) -from lib.topogen import Topogen, TopoRouter, get_topogen + +from lib import common_config +from lib.topogen import get_topogen CWD = os.path.dirname(os.path.realpath(__file__)) diff --git a/tests/topotests/bgp_auth/test_bgp_auth1.py b/tests/topotests/bgp_auth/test_bgp_auth1.py index c19a740a92b7..b0389474d425 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth1.py +++ b/tests/topotests/bgp_auth/test_bgp_auth1.py @@ -32,14 +32,12 @@ """ # pylint: disable=C0413 -import json import os import platform import sys -from time import sleep import pytest -from lib import common_config, topotest +from lib import topotest from lib.common_config import ( save_initial_config_on_routers, reset_with_new_configs, diff --git a/tests/topotests/bgp_auth/test_bgp_auth2.py b/tests/topotests/bgp_auth/test_bgp_auth2.py index 2551c1c35b7f..2b8f4673ea53 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth2.py +++ b/tests/topotests/bgp_auth/test_bgp_auth2.py @@ -32,14 +32,12 @@ """ # pylint: disable=C0413 -import json import os import platform import sys -from time import sleep import pytest -from lib import common_config, topotest +from lib import topotest from lib.common_config import ( save_initial_config_on_routers, reset_with_new_configs, diff --git a/tests/topotests/bgp_auth/test_bgp_auth3.py b/tests/topotests/bgp_auth/test_bgp_auth3.py index dc4f61d3c99d..d103d8075d7e 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth3.py +++ b/tests/topotests/bgp_auth/test_bgp_auth3.py @@ -32,14 +32,12 @@ """ # pylint: disable=C0413 -import json import os import platform import sys -from time import sleep import pytest -from lib import common_config, topotest +from lib import topotest from lib.common_config import ( save_initial_config_on_routers, reset_with_new_configs, diff --git a/tests/topotests/bgp_auth/test_bgp_auth4.py b/tests/topotests/bgp_auth/test_bgp_auth4.py index afe4441e13ed..792aa80d50d7 100644 --- a/tests/topotests/bgp_auth/test_bgp_auth4.py +++ b/tests/topotests/bgp_auth/test_bgp_auth4.py @@ -32,14 +32,12 @@ """ # pylint: disable=C0413 -import json import os import platform import sys -from time import sleep import pytest -from lib import common_config, topotest +from lib import topotest from lib.common_config import ( save_initial_config_on_routers, reset_with_new_configs, diff --git a/tests/topotests/bgp_bmp/test_bgp_bmp.py b/tests/topotests/bgp_bmp/test_bgp_bmp.py index 02de805068c4..80e291b2bdb6 100644 --- a/tests/topotests/bgp_bmp/test_bgp_bmp.py +++ b/tests/topotests/bgp_bmp/test_bgp_bmp.py @@ -26,7 +26,6 @@ from ipaddress import ip_network import json import os -import platform import pytest import sys diff --git a/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py b/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py index e0c1b4953e08..09091198a8c5 100644 --- a/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py +++ b/tests/topotests/bgp_color_extcommunities/test_bgp_color_extcommunities.py @@ -16,7 +16,6 @@ import sys import json import functools -from functools import partial import pytest # Save the Current Working Directory to find configuration files. diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py index 324f53f3a6d1..82a67a0b84cf 100644 --- a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py +++ b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py @@ -171,7 +171,6 @@ def test_bgp_no_export_local_as_communities_p0(request): ) for comm_type in ["no-export", "local-AS"]: - step("Create a route-map on R1 to set community as {}".format(comm_type)) seq_id = 10 diff --git a/tests/topotests/bgp_conditional_advertisement_static_route/test_bgp_conditional_advertisement_static_route.py b/tests/topotests/bgp_conditional_advertisement_static_route/test_bgp_conditional_advertisement_static_route.py index e9114bdbabdc..ea0f53cc9787 100644 --- a/tests/topotests/bgp_conditional_advertisement_static_route/test_bgp_conditional_advertisement_static_route.py +++ b/tests/topotests/bgp_conditional_advertisement_static_route/test_bgp_conditional_advertisement_static_route.py @@ -11,7 +11,6 @@ """ import os -import re import sys import json import pytest @@ -24,7 +23,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step diff --git a/tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py b/tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py index 2066d848d349..f8916e1c4dd8 100644 --- a/tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py +++ b/tests/topotests/bgp_dampening_per_peer/test_bgp_dampening_per_peer.py @@ -6,7 +6,6 @@ # import os -import re import sys import json import pytest diff --git a/tests/topotests/bgp_default_originate/test_bgp_default_originate_2links.py b/tests/topotests/bgp_default_originate/test_bgp_default_originate_2links.py index 75e66566b75b..f4f874f94221 100644 --- a/tests/topotests/bgp_default_originate/test_bgp_default_originate_2links.py +++ b/tests/topotests/bgp_default_originate/test_bgp_default_originate_2links.py @@ -17,7 +17,6 @@ import time import pytest import datetime -from copy import deepcopy from lib.topolog import logger from time import sleep @@ -214,7 +213,6 @@ def get_rib_route_uptime(tgen, addr_type, dut, input_dict): logger.info("Entering lib API: get_rib_route_uptime()") route_time = [] - out_route_dict = {} router_list = tgen.routers() for routerInput in input_dict.keys(): for router, rnode in router_list.items(): @@ -234,7 +232,6 @@ def get_rib_route_uptime(tgen, addr_type, dut, input_dict): for static_route in static_routes: if "vrf" in static_route and static_route["vrf"] is not None: - logger.info( "[DUT: {}]: Verifying routes for VRF:" " {}".format(router, static_route["vrf"]) @@ -307,7 +304,6 @@ def get_best_path_route_in_FIB(tgen, topo, dut, network): on failure : return error message with boolean False """ is_ipv4_best_path_found = False - is_ipv6_best_path_found = False rnode = tgen.routers()[dut] ipv4_show_bgp_json = run_frr_cmd(rnode, "sh ip bgp json ", isjson=True) ipv6_show_bgp_json = run_frr_cmd( @@ -1575,7 +1571,7 @@ def ping_router(): ipv_dict = get_best_path_route_in_FIB(tgen, topo, dut="r2", network=network) dut_links = topo["routers"]["r1"]["links"] active_interface = None - for key, values in dut_links.items(): + for key, _ in dut_links.items(): ipv4_address = dut_links[key]["ipv4"].split("/")[0] ipv6_address = dut_links[key]["ipv6"].split("/")[0] if ipv_dict["ipv4"] == ipv4_address and ipv_dict["ipv6"] == ipv6_address: diff --git a/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_1.py b/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_1.py index 50a1938ae3fd..142b3e430f11 100644 --- a/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_1.py +++ b/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_1.py @@ -18,8 +18,6 @@ import sys import time import pytest -from time import sleep -from copy import deepcopy from lib.topolog import logger # pylint: disable=C0413 @@ -30,32 +28,18 @@ from lib.bgp import ( verify_bgp_convergence, - verify_graceful_restart, create_router_bgp, - verify_router_id, modify_as_number, - verify_as_numbers, - clear_bgp_and_verify, - clear_bgp, verify_bgp_rib, get_prefix_count_route, get_dut_as_number, verify_rib_default_route, - verify_fib_default_route, - verify_bgp_advertised_routes_from_neighbor, - verify_bgp_received_routes_from_neighbor, ) from lib.common_config import ( - interface_status, verify_prefix_lists, verify_fib_routes, - kill_router_daemons, - start_router_daemons, - shutdown_bringup_interface, step, required_linux_kernel_version, - stop_router, - start_router, create_route_maps, create_prefix_lists, get_frr_ipv6_linklocal, diff --git a/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_2.py b/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_2.py index 4e8bda55cf10..a6918916df23 100644 --- a/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_2.py +++ b/tests/topotests/bgp_default_originate/test_bgp_default_originate_topo1_2.py @@ -17,8 +17,6 @@ import sys import time import pytest -from time import sleep -from copy import deepcopy from lib.topolog import logger # pylint: disable=C0413 @@ -31,13 +29,8 @@ verify_bgp_convergence, verify_graceful_restart, create_router_bgp, - verify_router_id, modify_as_number, - verify_as_numbers, - clear_bgp_and_verify, - clear_bgp, verify_bgp_rib, - get_prefix_count_route, get_dut_as_number, verify_rib_default_route, verify_fib_default_route, @@ -45,16 +38,12 @@ verify_bgp_received_routes_from_neighbor, ) from lib.common_config import ( - interface_status, verify_prefix_lists, verify_fib_routes, kill_router_daemons, start_router_daemons, - shutdown_bringup_interface, step, required_linux_kernel_version, - stop_router, - start_router, create_route_maps, create_prefix_lists, get_frr_ipv6_linklocal, @@ -65,7 +54,6 @@ reset_config_on_routers, create_static_routes, check_router_status, - delete_route_maps, ) diff --git a/tests/topotests/bgp_default_originate/test_default_orginate_vrf.py b/tests/topotests/bgp_default_originate/test_default_orginate_vrf.py index 4dedac5535d8..1506b02e5d40 100644 --- a/tests/topotests/bgp_default_originate/test_default_orginate_vrf.py +++ b/tests/topotests/bgp_default_originate/test_default_orginate_vrf.py @@ -10,8 +10,6 @@ import sys import time import pytest -from time import sleep -from copy import deepcopy from lib.topolog import logger # pylint: disable=C0413 @@ -22,32 +20,17 @@ from lib.bgp import ( verify_bgp_convergence, - verify_graceful_restart, create_router_bgp, - verify_router_id, modify_as_number, - verify_as_numbers, - clear_bgp_and_verify, - clear_bgp, verify_bgp_rib, get_prefix_count_route, get_dut_as_number, - verify_rib_default_route, - verify_fib_default_route, - verify_bgp_advertised_routes_from_neighbor, - verify_bgp_received_routes_from_neighbor, ) from lib.common_config import ( - interface_status, verify_prefix_lists, verify_rib, - kill_router_daemons, - start_router_daemons, - shutdown_bringup_interface, step, required_linux_kernel_version, - stop_router, - start_router, create_route_maps, create_prefix_lists, get_frr_ipv6_linklocal, @@ -58,7 +41,6 @@ reset_config_on_routers, create_static_routes, check_router_status, - delete_route_maps, ) pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] diff --git a/tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py b/tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py index f67a431c7e26..97a7e62e7c70 100644 --- a/tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py +++ b/tests/topotests/bgp_default_originate/test_default_originate_conditional_routemap.py @@ -19,7 +19,6 @@ import sys import time import pytest -from copy import deepcopy from lib.topolog import logger # pylint: disable=C0413 diff --git a/tests/topotests/bgp_distance_change/test_bgp_admin_dist.py b/tests/topotests/bgp_distance_change/test_bgp_admin_dist.py index 0bd3d2814bb0..0307ee2f4edf 100755 --- a/tests/topotests/bgp_distance_change/test_bgp_admin_dist.py +++ b/tests/topotests/bgp_distance_change/test_bgp_admin_dist.py @@ -215,7 +215,6 @@ def test_bgp_admin_distance_ebgp_ecmp_p0(): step("Configure static route in R4 and R5, redistribute in bgp") for addr_type in ADDR_TYPES: - input_dict = { "r4": { "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}] @@ -228,7 +227,6 @@ def test_bgp_admin_distance_ebgp_ecmp_p0(): ) for addr_type in ADDR_TYPES: - input_dict = { "r5": { "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}] @@ -268,7 +266,6 @@ def test_bgp_admin_distance_ebgp_ecmp_p0(): step("Configure the static route in R3 (Dut).") for addr_type in ADDR_TYPES: - input_dict = { "r3": { "static_routes": [ @@ -305,7 +302,6 @@ def test_bgp_admin_distance_ebgp_ecmp_p0(): step(" Configure the admin distance of 254 to static route in R3.") for addr_type in ADDR_TYPES: - input_dict = { "r3": { "static_routes": [ @@ -571,7 +567,6 @@ def test_bgp_admin_distance_ebgp_ecmp_p0(): step("Reconfigure the static route without admin distance") for addr_type in ADDR_TYPES: - input_dict = { "r3": { "static_routes": [ @@ -993,7 +988,6 @@ def test_bgp_admin_distance_ibgp_p0(): step("Configure static route Without any admin distance") for addr_type in ADDR_TYPES: - input_dict = { "r3": { "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}] @@ -1009,7 +1003,6 @@ def test_bgp_admin_distance_ibgp_p0(): protocol = "static" for addr_type in ADDR_TYPES: - input_dict = { "r3": { "static_routes": [{"network": NETWORK[addr_type], "next_hop": "Null0"}] @@ -1023,7 +1016,6 @@ def test_bgp_admin_distance_ibgp_p0(): step("Configure static route with admin distance of 253") for addr_type in ADDR_TYPES: - input_dict = { "r3": { "static_routes": [ @@ -1086,7 +1078,6 @@ def test_bgp_admin_distance_ibgp_p0(): step("Delete the static route.") for addr_type in ADDR_TYPES: - input_dict = { "r3": { "static_routes": [ diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py index 4d7d46c3e81d..91df89b1b526 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_addpath.py @@ -14,7 +14,6 @@ """ import os -import re import sys import json import pytest @@ -27,7 +26,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen def setup_module(mod): diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py index 26fae17c5e86..bf05ce8edd78 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_fqdn.py @@ -10,7 +10,6 @@ """ import os -import re import sys import json import pytest @@ -23,7 +22,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py index d67bfea45e68..514b29cd705c 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_graceful_restart.py @@ -12,7 +12,6 @@ """ import os -import re import sys import json import pytest @@ -25,7 +24,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py index 9e1f26f21e0b..39e7ded1e60a 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_orf.py @@ -10,7 +10,6 @@ """ import os -import re import sys import json import pytest @@ -23,7 +22,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py index f6c1e25fd650..7d36634728b9 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_role.py @@ -10,7 +10,6 @@ """ import os -import re import sys import json import pytest @@ -23,7 +22,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step diff --git a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py index 128283bbc3b4..591fc5a81782 100644 --- a/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py +++ b/tests/topotests/bgp_dynamic_capability/test_bgp_dynamic_capability_software_version.py @@ -23,7 +23,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step diff --git a/tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py b/tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py index b347042dcf32..5991f2e7ca17 100644 --- a/tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py +++ b/tests/topotests/bgp_ecmp_topo2/test_ibgp_ecmp_topo2.py @@ -106,7 +106,7 @@ def setup_module(mod): # Api call verify whether BGP is converged ADDR_TYPES = check_address_types() - for addr_type in ADDR_TYPES: + for _ in ADDR_TYPES: BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format( BGP_CONVERGENCE @@ -153,7 +153,6 @@ def teardown_module(): def static_or_nw(tgen, topo, tc_name, test_type, dut): - if test_type == "redist_static": input_dict_static = { dut: { @@ -363,7 +362,6 @@ def test_ecmp_remove_redistribute_static(request): reset_config_on_routers(tgen) static_or_nw(tgen, topo, tc_name, "redist_static", "r2") for addr_type in ADDR_TYPES: - # Verifying RIB routes dut = "r3" protocol = "bgp" @@ -406,7 +404,6 @@ def test_ecmp_remove_redistribute_static(request): assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) for addr_type in ADDR_TYPES: - # Verifying RIB routes dut = "r3" protocol = "bgp" diff --git a/tests/topotests/bgp_evpn_maximum_prefix/test_bgp_evpn_maximum_prefix.py b/tests/topotests/bgp_evpn_maximum_prefix/test_bgp_evpn_maximum_prefix.py index 5469eff144f2..876c205f1926 100644 --- a/tests/topotests/bgp_evpn_maximum_prefix/test_bgp_evpn_maximum_prefix.py +++ b/tests/topotests/bgp_evpn_maximum_prefix/test_bgp_evpn_maximum_prefix.py @@ -6,7 +6,6 @@ # import os -import re import sys import json import pytest @@ -17,7 +16,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py index b033e9c2eb10..ba2fb62661d2 100644 --- a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py +++ b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py @@ -455,7 +455,7 @@ def check_remote_es(esi, vtep_ips, dut_name, down_vteps): else: tor_ips_rack = tor_ips_rack_1 - for tor_name, tor_ip in tor_ips_rack.items(): + for _, tor_ip in tor_ips_rack.items(): remote_ips.append(tor_ip) # remove down VTEPs from the remote check list diff --git a/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py b/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py index 603f069fe3ac..d441a256fda4 100755 --- a/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py +++ b/tests/topotests/bgp_evpn_overlay_index_gateway/test_bgp_evpn_overlay_index_gateway.py @@ -241,7 +241,7 @@ def evpn_gateway_ip_show_op_check(trigger=" "): expected_op = json.loads(open(expected_op_file).read()) test_func = partial(topotest.router_json_cmp, pe, command, expected_op) - ret, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) assertmsg = '"{0}" JSON output mismatch for {1}'.format(name, command) if result is not None: return result, assertmsg diff --git a/tests/topotests/bgp_evpn_route_map_match/test_bgp_evpn_route_map_match.py b/tests/topotests/bgp_evpn_route_map_match/test_bgp_evpn_route_map_match.py index 2df0fd0e6cae..36c79d6b2b36 100644 --- a/tests/topotests/bgp_evpn_route_map_match/test_bgp_evpn_route_map_match.py +++ b/tests/topotests/bgp_evpn_route_map_match/test_bgp_evpn_route_map_match.py @@ -10,7 +10,6 @@ """ import os -import re import sys import json import pytest @@ -23,8 +22,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step +from lib.topogen import Topogen, get_topogen def setup_module(mod): diff --git a/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py b/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py index 5f6eb1726103..e4d330e13c0d 100644 --- a/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py +++ b/tests/topotests/bgp_extcomm_list_delete/test_bgp_extcomm-list_delete.py @@ -25,7 +25,6 @@ # pylint: disable=C0413 from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger from lib import topotest diff --git a/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py b/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py index e7058f539279..e9006b81c930 100644 --- a/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py +++ b/tests/topotests/bgp_extended_link_bandwidth/test_bgp_extended_link_bandwidth.py @@ -6,7 +6,6 @@ # import os -import re import sys import json import pytest @@ -17,7 +16,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_features/test_bgp_features.py b/tests/topotests/bgp_features/test_bgp_features.py index 43f4905d4186..0f5d9dea4285 100644 --- a/tests/topotests/bgp_features/test_bgp_features.py +++ b/tests/topotests/bgp_features/test_bgp_features.py @@ -18,7 +18,6 @@ import os import sys import pytest -import re import time # Save the Current Working Directory to find configuration files. diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py index 5e2b2f37b234..2e2c8119a251 100644 --- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py +++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-1.py @@ -102,7 +102,6 @@ verify_graceful_restart, create_router_bgp, verify_r_bit, - verify_f_bit, verify_bgp_convergence, verify_bgp_convergence_from_running_config, ) diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py index 13c5ba538c4a..9f79c52e3a6b 100644 --- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py +++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-2.py @@ -117,8 +117,6 @@ check_address_types, write_test_footer, check_router_status, - shutdown_bringup_interface, - step, get_frr_ipv6_linklocal, required_linux_kernel_version, ) diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py index 1a8f8302ffef..0873c24b7fcf 100644 --- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py +++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-3.py @@ -117,7 +117,6 @@ check_address_types, write_test_footer, check_router_status, - shutdown_bringup_interface, step, get_frr_ipv6_linklocal, required_linux_kernel_version, diff --git a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py index de4b94032c06..710514b056ee 100644 --- a/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py +++ b/tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1-4.py @@ -104,8 +104,6 @@ verify_bgp_rib, verify_graceful_restart, create_router_bgp, - verify_r_bit, - verify_f_bit, verify_bgp_convergence, verify_bgp_convergence_from_running_config, ) @@ -120,7 +118,6 @@ check_address_types, write_test_footer, check_router_status, - shutdown_bringup_interface, step, get_frr_ipv6_linklocal, required_linux_kernel_version, diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py index cb6bf56967b0..01ab10b82ff1 100644 --- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py +++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-1.py @@ -94,13 +94,10 @@ verify_bgp_rib, verify_graceful_restart, create_router_bgp, - verify_r_bit, verify_eor, - verify_f_bit, verify_bgp_convergence, verify_gr_address_family, modify_bgp_config_when_bgpd_down, - verify_graceful_restart_timers, verify_bgp_convergence_from_running_config, ) @@ -169,7 +166,7 @@ def setup_module(mod): # Api call verify whether BGP is converged ADDR_TYPES = check_address_types() - for addr_type in ADDR_TYPES: + for _ in ADDR_TYPES: BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format( BGP_CONVERGENCE diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py index cf9a474a8125..989d2d554a10 100644 --- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py +++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-2.py @@ -95,7 +95,6 @@ verify_graceful_restart, create_router_bgp, verify_r_bit, - verify_eor, verify_f_bit, verify_bgp_convergence, verify_gr_address_family, @@ -114,7 +113,6 @@ check_address_types, write_test_footer, check_router_status, - step, get_frr_ipv6_linklocal, required_linux_kernel_version, ) @@ -169,7 +167,7 @@ def setup_module(mod): # Api call verify whether BGP is converged ADDR_TYPES = check_address_types() - for addr_type in ADDR_TYPES: + for _ in ADDR_TYPES: BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format( BGP_CONVERGENCE diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py index 4746d71a323f..05fb8bf79655 100644 --- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py +++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-3.py @@ -98,9 +98,7 @@ verify_eor, verify_f_bit, verify_bgp_convergence, - verify_gr_address_family, modify_bgp_config_when_bgpd_down, - verify_graceful_restart_timers, verify_bgp_convergence_from_running_config, ) @@ -114,7 +112,6 @@ check_address_types, write_test_footer, check_router_status, - step, get_frr_ipv6_linklocal, required_linux_kernel_version, ) @@ -169,7 +166,7 @@ def setup_module(mod): # Api call verify whether BGP is converged ADDR_TYPES = check_address_types() - for addr_type in ADDR_TYPES: + for _ in ADDR_TYPES: BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format( BGP_CONVERGENCE diff --git a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py index 1c41df98e163..950733c3afc4 100644 --- a/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py +++ b/tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2-4.py @@ -96,13 +96,9 @@ verify_bgp_rib, verify_graceful_restart, create_router_bgp, - verify_r_bit, verify_eor, - verify_f_bit, verify_bgp_convergence, - verify_gr_address_family, modify_bgp_config_when_bgpd_down, - verify_graceful_restart_timers, verify_bgp_convergence_from_running_config, ) @@ -116,7 +112,6 @@ check_address_types, write_test_footer, check_router_status, - step, get_frr_ipv6_linklocal, required_linux_kernel_version, ) @@ -171,7 +166,7 @@ def setup_module(mod): # Api call verify whether BGP is converged ADDR_TYPES = check_address_types() - for addr_type in ADDR_TYPES: + for _ in ADDR_TYPES: BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format( BGP_CONVERGENCE diff --git a/tests/topotests/bgp_gr_functionality_topo3/test_bgp_gr_functionality_topo3.py b/tests/topotests/bgp_gr_functionality_topo3/test_bgp_gr_functionality_topo3.py index 593a8d64179e..e24f31d8624a 100644 --- a/tests/topotests/bgp_gr_functionality_topo3/test_bgp_gr_functionality_topo3.py +++ b/tests/topotests/bgp_gr_functionality_topo3/test_bgp_gr_functionality_topo3.py @@ -12,7 +12,6 @@ import pytest from time import sleep -import traceback import ipaddress # Save the Current Working Directory to find configuration files. @@ -34,37 +33,21 @@ verify_bgp_rib, verify_graceful_restart, create_router_bgp, - verify_r_bit, - verify_eor, - verify_f_bit, verify_bgp_convergence, - verify_gr_address_family, - modify_bgp_config_when_bgpd_down, - verify_graceful_restart_timers, verify_bgp_convergence_from_running_config, ) # Import common_config to use commomnly used APIs from lib.common_config import ( - create_common_configuration, - InvalidCLIError, - retry, generate_ips, - FRRCFG_FILE, - find_interface_with_greater_ip, check_address_types, validate_ip_address, run_frr_cmd, - get_frr_ipv6_linklocal, ) from lib.common_config import ( write_test_header, - reset_config_on_routers, start_topology, - kill_router_daemons, - start_router_daemons, - verify_rib, check_address_types, write_test_footer, check_router_status, @@ -154,9 +137,6 @@ def verify_stale_routes_list(tgen, addr_type, dut, input_dict): """ logger.debug("Entering lib API: verify_stale_routes_list()") router_list = tgen.routers() - additional_nexthops_in_required_nhs = [] - list1 = [] - list2 = [] found_hops = [] for routerInput in input_dict.keys(): for router, rnode in router_list.items(): @@ -266,7 +246,7 @@ def setup_module(mod): # Api call verify whether BGP is converged ADDR_TYPES = check_address_types() - for addr_type in ADDR_TYPES: + for _ in ADDR_TYPES: BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error:" " {}".format( BGP_CONVERGENCE @@ -442,7 +422,7 @@ def test_bgp_gr_stale_routes(request): ) assert result is True, "Testcase {} :Failed \n Error {}".format(tc_name, result) - for iteration in range(5): + for _ in range(5): step("graceful-restart-disable:True at R3") input_dict = { "r3": { diff --git a/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_per_neighbor_restart_retain_routes.py b/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_per_neighbor_restart_retain_routes.py index 2354c0cd3dc0..e61efefa5aab 100644 --- a/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_per_neighbor_restart_retain_routes.py +++ b/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_per_neighbor_restart_retain_routes.py @@ -22,7 +22,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step, stop_router pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_restart_retain_routes.py b/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_restart_retain_routes.py index abf737ff342b..d7ae43338a03 100644 --- a/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_restart_retain_routes.py +++ b/tests/topotests/bgp_gr_restart_retain_routes/test_bgp_gr_restart_retain_routes.py @@ -21,7 +21,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step, stop_router pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py index 395ef2d91946..803b51c04327 100644 --- a/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py +++ b/tests/topotests/bgp_ipv4_over_ipv6/test_rfc5549_ebgp_unnumbered_nbr.py @@ -23,7 +23,7 @@ from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import ( write_test_header, diff --git a/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py b/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py index 84a9c8b72353..a0871a492235 100644 --- a/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py +++ b/tests/topotests/bgp_l3vpn_label_export/test_bgp_l3vpn_label_export.py @@ -146,7 +146,7 @@ def check_mpls_table(label, protocol): if label == "auto" and protocol: output_copy = deepcopy(output) - for key, data in output_copy.items(): + for _, data in output_copy.items(): for nexthop in data.get("nexthops", []): if nexthop.get("type", None) != protocol: continue diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py index d1d384182c0f..009b39eef0ca 100644 --- a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py +++ b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py @@ -22,7 +22,6 @@ # pylint: disable=C0413 from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_llgr/test_bgp_llgr.py b/tests/topotests/bgp_llgr/test_bgp_llgr.py index 2a3753e26cbf..547c998c2b19 100644 --- a/tests/topotests/bgp_llgr/test_bgp_llgr.py +++ b/tests/topotests/bgp_llgr/test_bgp_llgr.py @@ -32,7 +32,6 @@ from lib.common_config import ( kill_router_daemons, - start_router_daemons, step, ) diff --git a/tests/topotests/bgp_local_asn/test_bgp_local_asn_agg.py b/tests/topotests/bgp_local_asn/test_bgp_local_asn_agg.py index c84fce6a9d17..214b24eed862 100644 --- a/tests/topotests/bgp_local_asn/test_bgp_local_asn_agg.py +++ b/tests/topotests/bgp_local_asn/test_bgp_local_asn_agg.py @@ -25,7 +25,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn/test_bgp_local_asn_ecmp.py b/tests/topotests/bgp_local_asn/test_bgp_local_asn_ecmp.py index 8a1157052e5b..ce448329eb85 100644 --- a/tests/topotests/bgp_local_asn/test_bgp_local_asn_ecmp.py +++ b/tests/topotests/bgp_local_asn/test_bgp_local_asn_ecmp.py @@ -21,7 +21,6 @@ import sys import time import pytest -import platform # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -31,7 +30,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo1.py b/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo1.py index 25c9bee93c85..ff1a81472df0 100644 --- a/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo1.py +++ b/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo1.py @@ -39,7 +39,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo2.py b/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo2.py index 0c10c6409f18..5d290ce42721 100644 --- a/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo2.py +++ b/tests/topotests/bgp_local_asn/test_bgp_local_asn_topo2.py @@ -31,7 +31,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo1.py b/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo1.py index ea6ab59b3f0f..0c7e7cf5c18d 100644 --- a/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo1.py +++ b/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo1.py @@ -26,7 +26,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo2.py b/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo2.py index b1204bf58366..5a0f34132a2c 100644 --- a/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo2.py +++ b/tests/topotests/bgp_local_asn/test_bgp_local_asn_vrf_topo2.py @@ -24,7 +24,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_agg.py b/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_agg.py index cfaab9bbe219..453f05822371 100644 --- a/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_agg.py +++ b/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_agg.py @@ -38,7 +38,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_ecmp.py b/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_ecmp.py index 6937a61c338a..d52ed4c3342c 100644 --- a/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_ecmp.py +++ b/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_ecmp.py @@ -34,7 +34,6 @@ import sys import time import pytest -import platform # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -44,7 +43,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_topo1.py b/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_topo1.py index bacef476646e..4ee112ebbf2e 100644 --- a/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_topo1.py +++ b/tests/topotests/bgp_local_asn_dot/test_bgp_local_asn_dot_topo1.py @@ -52,7 +52,6 @@ # pylint: disable=C0413 # Import topogen and topotest helpers from lib.topogen import Topogen, get_topogen -from lib.topotest import version_cmp from lib.common_config import ( start_topology, diff --git a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py index 40a28fbcf492..012b643dded9 100644 --- a/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py +++ b/tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py @@ -1845,7 +1845,7 @@ def test_vrf_vlan_routing_table_p1(request): dut = "r3" vrf = "RED_A" - for c_link, c_data in topo["routers"][dut]["links"].items(): + for _, c_data in topo["routers"][dut]["links"].items(): if c_data["vrf"] != vrf: continue @@ -2634,7 +2634,7 @@ def test_delete_and_re_add_vrf_p1(request): vrfs = ["RED_A", "BLUE_A"] for vrf in vrfs: - for c_link, c_data in topo["routers"][dut]["links"].items(): + for _, c_data in topo["routers"][dut]["links"].items(): if c_data["vrf"] != vrf: continue @@ -3584,7 +3584,7 @@ def test_vrf_name_significance_p1(request): vrfs = ["GREY_A", "PINK_A"] for vrf in vrfs: - for c_link, c_data in topo_modify["routers"][dut]["links"].items(): + for _, c_data in topo_modify["routers"][dut]["links"].items(): if c_data["vrf"] != vrf: continue diff --git a/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py index 911a6d757f8a..e1c28084de21 100644 --- a/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py +++ b/tests/topotests/bgp_nexthop_mp_ipv4_6/test_nexthop_mp_ipv4_6.py @@ -12,7 +12,6 @@ import os import sys import json -import functools from functools import partial import pytest diff --git a/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py b/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py index b53673ad0f2f..32f78c44f9f0 100644 --- a/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py +++ b/tests/topotests/bgp_node_target_extcommunities/test_bgp_node_target_extcommunities.py @@ -24,7 +24,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_oad/test_bgp_oad.py b/tests/topotests/bgp_oad/test_bgp_oad.py index bb779462db27..6dd46fbdaadc 100644 --- a/tests/topotests/bgp_oad/test_bgp_oad.py +++ b/tests/topotests/bgp_oad/test_bgp_oad.py @@ -11,7 +11,6 @@ """ import os -import re import sys import json import pytest @@ -24,8 +23,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step +from lib.topogen import Topogen, get_topogen def setup_module(mod): diff --git a/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py index bd8cd8e18a94..adc92f59fe4b 100644 --- a/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py +++ b/tests/topotests/bgp_path_attribute_discard/test_bgp_path_attribute_discard.py @@ -23,7 +23,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.common_config import step pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_prefix_sid2/test_bgp_prefix_sid2.py b/tests/topotests/bgp_prefix_sid2/test_bgp_prefix_sid2.py index d6b94329e411..cf0c9fea2eb1 100755 --- a/tests/topotests/bgp_prefix_sid2/test_bgp_prefix_sid2.py +++ b/tests/topotests/bgp_prefix_sid2/test_bgp_prefix_sid2.py @@ -90,7 +90,7 @@ def check(name, cmd, expected_file): logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file)) tgen = get_topogen() func = functools.partial(_check, name, cmd, expected_file) - success, result = topotest.run_and_expect(func, None, count=10, wait=0.5) + _, result = topotest.run_and_expect(func, None, count=10, wait=0.5) assert result is None, "Failed" check("r1", "show bgp ipv6 vpn 2001:1::/64 json", "r1/vpnv6_rib_entry1.json") diff --git a/tests/topotests/bgp_redistribute_table/test_bgp_redistribute_table.py b/tests/topotests/bgp_redistribute_table/test_bgp_redistribute_table.py index 08b70ae0daee..614610ccd64e 100644 --- a/tests/topotests/bgp_redistribute_table/test_bgp_redistribute_table.py +++ b/tests/topotests/bgp_redistribute_table/test_bgp_redistribute_table.py @@ -86,7 +86,7 @@ def _router_json_cmp_exact_filter(router, cmd, expected): json_output = json.loads(output) # filter out tableVersion, version, nhVrfId and vrfId - for route, attrs in json_output.items(): + for _, attrs in json_output.items(): for attr in attrs: if "table" in attr: attr.pop("table") diff --git a/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py b/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py index 2d8864c34ae1..8b965a161454 100644 --- a/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py +++ b/tests/topotests/bgp_remove_private_as/test_bgp_remove_private_as.py @@ -32,7 +32,6 @@ import os import sys import json -import time import pytest CWD = os.path.dirname(os.path.realpath(__file__)) diff --git a/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py b/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py index e3e4567aeb03..10896e2b2202 100644 --- a/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py +++ b/tests/topotests/bgp_remove_private_as_route_map/test_bgp_remove_private_as_route_map.py @@ -10,7 +10,6 @@ """ import os -import re import sys import json import pytest @@ -23,7 +22,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen def build_topo(tgen): diff --git a/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py b/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py index 29ff1065fd69..9223cbd7590d 100644 --- a/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py +++ b/tests/topotests/bgp_roles_capability/test_bgp_roles_capability.py @@ -24,8 +24,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger +from lib.topogen import Topogen, TopoRouter pytestmark = [pytest.mark.bgpd] @@ -38,7 +37,7 @@ def tgen(request): tgen = Topogen(topodef, request.module.__name__) tgen.start_topology() router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") router.load_config(TopoRouter.RD_BGP, "bgpd.conf") tgen.start_router() @@ -82,9 +81,7 @@ def test_correct_pair(tgen): check_r2_established = functools.partial( check_session_established, router, neighbor_ip ) - success, _ = topotest.run_and_expect( - check_r2_established, True, count=20, wait=3 - ) + success, _ = topotest.run_and_expect(check_r2_established, True, count=20, wait=3) assert success, "Session with r2 is not Established" neighbor_status = find_neighbor_status(router, neighbor_ip) @@ -111,9 +108,7 @@ def test_single_role_advertising(tgen): check_r4_established = functools.partial( check_session_established, router, neighbor_ip ) - success, _ = topotest.run_and_expect( - check_r4_established, True, count=20, wait=3 - ) + success, _ = topotest.run_and_expect(check_r4_established, True, count=20, wait=3) assert success, "Session with r4 is not Established" neighbor_status = find_neighbor_status(router, neighbor_ip) @@ -129,9 +124,7 @@ def test_single_role_receiving(tgen): check_r1_established = functools.partial( check_session_established, router, neighbor_ip ) - success, _ = topotest.run_and_expect( - check_r1_established, True, count=20, wait=3 - ) + success, _ = topotest.run_and_expect(check_r1_established, True, count=20, wait=3) assert success, "Session with r1 is not Established" neighbor_status = find_neighbor_status(router, neighbor_ip) diff --git a/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py b/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py index a43518bc8a7d..ffbf454ded62 100644 --- a/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py +++ b/tests/topotests/bgp_roles_filtering/test_bgp_roles_filtering.py @@ -16,7 +16,6 @@ import json import os import sys -import functools import pytest CWD = os.path.dirname(os.path.realpath(__file__)) @@ -24,9 +23,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.bgp import verify_bgp_convergence_from_running_config -from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger +from lib.topogen import Topogen, TopoRouter pytestmark = [pytest.mark.bgpd] @@ -39,7 +36,7 @@ def tgen(request): tgen = Topogen(topodef, request.module.__name__) tgen.start_topology() router_list = tgen.routers() - for rname, router in router_list.items(): + for _, router in router_list.items(): router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") router.load_config(TopoRouter.RD_BGP, "bgpd.conf") tgen.start_router() @@ -69,9 +66,7 @@ def _routes_half_converged(): ] return output == expected - success, _ = topotest.run_and_expect( - _routes_half_converged, True, count=20, wait=3 - ) + success, _ = topotest.run_and_expect(_routes_half_converged, True, count=20, wait=3) assert success, "Routes did not converged" routes_with_otc = list() diff --git a/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py b/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py index d50d67b60e10..94bf092c76bf 100644 --- a/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py +++ b/tests/topotests/bgp_route_aggregation/test_bgp_aggregation.py @@ -119,7 +119,7 @@ def setup_module(mod): # Api call verify whether BGP is converged ADDR_TYPES = check_address_types() - for addr_type in ADDR_TYPES: + for _ in ADDR_TYPES: BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo) assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format( BGP_CONVERGENCE diff --git a/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py b/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py index c766f5c1a815..7116deaea46a 100644 --- a/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py +++ b/tests/topotests/bgp_route_map_match_source_protocol/test_bgp_route_map_match_source_protocol.py @@ -22,7 +22,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py b/tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py index 7dd63fdac0b9..6ffa078f0ca0 100644 --- a/tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py +++ b/tests/topotests/bgp_route_map_match_tag_untagged/test_bgp_route_map_match_tag_untagged.py @@ -17,7 +17,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py b/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py index 5ce8b17f249a..a6641348f7f1 100644 --- a/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py +++ b/tests/topotests/bgp_route_map_vpn_import/test_bgp_route_map_vpn_import.py @@ -24,7 +24,6 @@ # pylint: disable=C0413 from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_route_origin_parser/test_bgp_route_origin_parser.py b/tests/topotests/bgp_route_origin_parser/test_bgp_route_origin_parser.py index 673efc2c7332..16afda8bcc96 100644 --- a/tests/topotests/bgp_route_origin_parser/test_bgp_route_origin_parser.py +++ b/tests/topotests/bgp_route_origin_parser/test_bgp_route_origin_parser.py @@ -11,7 +11,6 @@ import os import sys -import json import pytest import functools diff --git a/tests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py b/tests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py index 9984abaa8561..5022a4a4a34f 100644 --- a/tests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py +++ b/tests/topotests/bgp_rr_ibgp/test_bgp_rr_ibgp_topo1.py @@ -132,7 +132,6 @@ def test_zebra_ipv4_routingTable(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) - failures = 0 router_list = tgen.routers().values() for router in router_list: output = router.vtysh_cmd("show ip route json", isjson=True) diff --git a/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py b/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py index 0131e12579b3..09eef51338d9 100755 --- a/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py +++ b/tests/topotests/bgp_snmp_mplsl3vpn/test_bgp_snmp_mplsvpn.py @@ -325,7 +325,6 @@ def router_interface_get_ifindex(router, interface): def generate_vrf_ifindex_oid(vrf, ifindex): - intoid = snmp_uint32_to_oid(int(ifindex)) vrfoid = snmp_str_to_oid(vrf) oid = "{}.{}".format(vrfoid, intoid) diff --git a/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py b/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py index 92315bce04c7..f8385401c5ad 100755 --- a/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py +++ b/tests/topotests/bgp_srv6_sid_reachability/test_bgp_srv6_sid_reachability.py @@ -8,10 +8,7 @@ # import os -import re import sys -import json -import functools import pytest CWD = os.path.dirname(os.path.realpath(__file__)) @@ -19,9 +16,7 @@ # pylint: disable=C0413 # Import topogen and topotest helpers -from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger from lib.common_config import required_linux_kernel_version from lib.checkping import check_ping diff --git a/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py b/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py index 14b9ba84988c..0b52c87d2770 100755 --- a/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py +++ b/tests/topotests/bgp_srv6l3vpn_over_ipv6/test_bgp_srv6l3vpn_over_ipv6.py @@ -9,10 +9,7 @@ # import os -import re import sys -import json -import functools import pytest CWD = os.path.dirname(os.path.realpath(__file__)) @@ -20,9 +17,7 @@ # pylint: disable=C0413 # Import topogen and topotest helpers -from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.topolog import logger from lib.common_config import required_linux_kernel_version from lib.checkping import check_ping diff --git a/tests/topotests/bgp_srv6l3vpn_route_leak/test_bgp_srv6l3vpn_route_leak.py b/tests/topotests/bgp_srv6l3vpn_route_leak/test_bgp_srv6l3vpn_route_leak.py index f0c914424846..4bd5fdf16535 100755 --- a/tests/topotests/bgp_srv6l3vpn_route_leak/test_bgp_srv6l3vpn_route_leak.py +++ b/tests/topotests/bgp_srv6l3vpn_route_leak/test_bgp_srv6l3vpn_route_leak.py @@ -6,10 +6,8 @@ # import os -import re import sys import json -import functools import pytest CWD = os.path.dirname(os.path.realpath(__file__)) @@ -20,7 +18,6 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger -from lib.common_config import required_linux_kernel_version pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py b/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py index 787707cc0f62..8d303a774b23 100755 --- a/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py +++ b/tests/topotests/bgp_srv6l3vpn_sid/test_bgp_srv6l3vpn_sid.py @@ -20,7 +20,6 @@ # import os -import re import sys import json import functools diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py index 38baf434426d..b75d0d875133 100755 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py @@ -9,7 +9,6 @@ # import os -import re import sys import json import functools diff --git a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py index fa8a88297f3f..f7ac827e2633 100644 --- a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py +++ b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py @@ -15,7 +15,6 @@ import json import pytest from functools import partial -from time import sleep from lib.topolog import logger CWD = os.path.dirname(os.path.realpath(__file__)) diff --git a/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py b/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py index aeb9bf529dff..4a03cb0a6d6b 100644 --- a/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py +++ b/tests/topotests/bgp_tcp_mss/test_bgp_vrf_tcp_mss.py @@ -17,12 +17,7 @@ import os import sys -import json import pytest -import functools -import platform -import socket -import subprocess # add after imports, before defining classes or functions: pytestmark = [pytest.mark.bgpd] @@ -31,43 +26,27 @@ sys.path.append(os.path.join(CWD, "../")) # pylint: disable=C0413 -from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen from lib.topojson import build_config_from_json -from lib.topolog import logger import time from lib.bgp import ( clear_bgp, - clear_bgp_and_verify, create_router_bgp, - modify_as_number, - verify_as_numbers, verify_bgp_convergence, verify_bgp_rib, - verify_bgp_timers_and_functionality, - verify_router_id, verify_tcp_mss, ) from lib.common_config import ( kill_router_daemons, start_router_daemons, - addKernelRoute, apply_raw_config, check_address_types, check_router_status, - create_prefix_lists, - create_route_maps, create_static_routes, required_linux_kernel_version, - reset_config_on_routers, start_topology, step, - verify_admin_distance_for_static_routes, - verify_bgp_community, - verify_fib_routes, - verify_rib, write_test_footer, - write_test_header, ) # Global variables diff --git a/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py b/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py index a2eacc7ab272..44336efed2a9 100644 --- a/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py +++ b/tests/topotests/bgp_tcp_mss_passive/test_bgp_tcp_mss_passive.py @@ -21,7 +21,7 @@ # pylint: disable=C0413 from lib import topotest -from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topogen import Topogen, get_topogen pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py b/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py index 4d4e29b2f875..09b13e6a2f8b 100644 --- a/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py +++ b/tests/topotests/bgp_unnumbered/test_bgp_unnumbered.py @@ -27,7 +27,6 @@ def build_topo(tgen): - tgen.add_router("r1") tgen.add_router("r2") diff --git a/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py b/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py index 695cfc3d25d6..08d6e140a141 100644 --- a/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py +++ b/tests/topotests/bgp_vpn_5549_route_map/test_bgp_vpn_5549_route_map.py @@ -22,7 +22,6 @@ # pylint: disable=C0413 from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen -from lib.common_config import step pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py index 8e2e4017df8d..5467cf4d841b 100644 --- a/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py +++ b/tests/topotests/bgp_vpnv4_asbr/test_bgp_vpnv4_asbr.py @@ -312,7 +312,7 @@ def _check_nexthop_available(router, prefix): return "{0}, {1}, route distinguisher not present".format( router.name, prefix ) - for rd, pathes in dump.items(): + for _, pathes in dump.items(): for path in pathes["paths"]: if "remoteLabel" not in path.keys(): return "{0}, {1}, remoteLabel not present".format( diff --git a/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py b/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py index 037dd4039085..6237decfc328 100644 --- a/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py +++ b/tests/topotests/bgp_vpnv4_noretain/test_bgp_vpnv4_noretain.py @@ -141,7 +141,7 @@ def router_json_cmp_exact_filter(router, cmd, expected): # filter out tableVersion, version and nhVrfID json_output.pop("tableVersion") for rd, data in json_output["routes"]["routeDistinguishers"].items(): - for prefix, attrs in data.items(): + for _, attrs in data.items(): for attr in attrs: if "nhVrfId" in attr: attr.pop("nhVrfId") @@ -171,7 +171,7 @@ def router_vrf_json_cmp_exact_filter(router, cmd, expected): data.pop("tableVersion") if "routes" not in data: continue - for route, attrs in data["routes"].items(): + for _, attrs in data["routes"].items(): for attr in attrs: if "nhVrfId" in attr: attr.pop("nhVrfId") diff --git a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py index b0178805456b..cf1d3cb2b8d8 100644 --- a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py @@ -183,7 +183,7 @@ def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=N assert dump, "{0}, {1}, route distinguisher not present".format( router.name, prefix ) - for rd, pathes in dump.items(): + for _, pathes in dump.items(): for path in pathes["paths"]: assert ( "remoteLabel" in path.keys() @@ -305,7 +305,7 @@ def mpls_table_check(router, blacklist=None, label_list=None, whitelist=None): test_func = functools.partial( check_show_mpls_table, router, blacklist, label_list, whitelist ) - success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, MPLS labels check fail: {}".format(router.name, result) diff --git a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py index 3879687aac8e..f8d26427ebbb 100644 --- a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py @@ -179,7 +179,7 @@ def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=N ) dump = router.vtysh_cmd("show bgp ipv6 vpn {} json".format(prefix), isjson=True) - for rd, pathes in dump.items(): + for _, pathes in dump.items(): for path in pathes["paths"]: assert ( "remoteLabel" in path.keys() @@ -300,7 +300,7 @@ def mpls_table_check(router, blacklist=None, label_list=None, whitelist=None): test_func = functools.partial( check_show_mpls_table, router, blacklist, label_list, whitelist ) - success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, MPLS labels check fail: {}".format(router.name, result) @@ -798,7 +798,7 @@ def test_reconfigure_allocation_mode_nexthop(): test_func = functools.partial( check_show_mpls_table_entry_label_not_found, router, 17 ) - success, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5) + success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "r1, mpls entry with label 17 still present" # Check vpnv6 routes from r1 diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py index 32643c27b8bd..8d73e5f8ac12 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py @@ -18,7 +18,6 @@ import os import sys -import json import time import pytest import platform @@ -58,7 +57,7 @@ verify_best_path_as_per_bgp_attribute, verify_bgp_rib, ) -from lib.topojson import build_topo_from_json, build_config_from_json +from lib.topojson import build_config_from_json pytestmark = [pytest.mark.bgpd, pytest.mark.staticd] diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py index 726afcb6aeb9..25a73b58c709 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo3/test_bgp_vrf_dynamic_route_leak_topo3.py @@ -23,7 +23,6 @@ import time import pytest import platform -from time import sleep # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -49,7 +48,6 @@ create_static_routes, create_prefix_lists, create_bgp_community_lists, - get_frr_ipv6_linklocal, ) from lib.topolog import logger diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py index 45d7b0309ebc..53f0239c4dea 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-1.py @@ -24,7 +24,6 @@ import time import pytest import platform -from time import sleep # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -46,18 +45,13 @@ reset_config_on_routers, verify_rib, step, - create_route_maps, create_static_routes, - create_prefix_lists, - create_bgp_community_lists, - get_frr_ipv6_linklocal, ) from lib.topolog import logger from lib.bgp import ( verify_bgp_convergence, create_router_bgp, - verify_bgp_community, verify_bgp_rib, ) from lib.topojson import build_config_from_json diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py index d29edf59b879..7b0eac3f7441 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-2.py @@ -24,7 +24,6 @@ import time import pytest import platform -from time import sleep # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -46,18 +45,13 @@ reset_config_on_routers, verify_rib, step, - create_route_maps, create_static_routes, - create_prefix_lists, - create_bgp_community_lists, - get_frr_ipv6_linklocal, ) from lib.topolog import logger from lib.bgp import ( verify_bgp_convergence, create_router_bgp, - verify_bgp_community, verify_bgp_rib, ) from lib.topojson import build_config_from_json diff --git a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py index c118ffc090f3..ec7b25c7cc17 100644 --- a/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py +++ b/tests/topotests/bgp_vrf_dynamic_route_leak_topo4/test_bgp_vrf_dynamic_route_leak_topo4-3.py @@ -24,7 +24,6 @@ import time import pytest import platform -from time import sleep # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) @@ -46,18 +45,13 @@ reset_config_on_routers, verify_rib, step, - create_route_maps, create_static_routes, - create_prefix_lists, - create_bgp_community_lists, - get_frr_ipv6_linklocal, ) from lib.topolog import logger from lib.bgp import ( verify_bgp_convergence, create_router_bgp, - verify_bgp_community, verify_bgp_rib, ) from lib.topojson import build_config_from_json diff --git a/tests/topotests/bgp_vrf_leaking_5549_routes/test_bgp_vrf_leaking.py b/tests/topotests/bgp_vrf_leaking_5549_routes/test_bgp_vrf_leaking.py index b20819264d13..3539d06ac313 100755 --- a/tests/topotests/bgp_vrf_leaking_5549_routes/test_bgp_vrf_leaking.py +++ b/tests/topotests/bgp_vrf_leaking_5549_routes/test_bgp_vrf_leaking.py @@ -6,10 +6,8 @@ # import os -import re import sys import json -import functools import pytest CWD = os.path.dirname(os.path.realpath(__file__)) @@ -20,7 +18,6 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger -from lib.common_config import required_linux_kernel_version pytestmark = [pytest.mark.bgpd] diff --git a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py index f3521969d3f4..3790446dc985 100644 --- a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py +++ b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo1.py @@ -49,9 +49,7 @@ from lib.bgp import ( verify_bgp_convergence, create_router_bgp, - verify_bgp_community, verify_bgp_rib, - clear_bgp, verify_best_path_as_per_bgp_attribute, ) from lib.topojson import build_config_from_json diff --git a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py index 3cb31809fe71..262cacd1474a 100644 --- a/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py +++ b/tests/topotests/bgp_vrf_lite_best_path_test/test_bgp_vrf_lite_best_path_topo2.py @@ -19,7 +19,6 @@ import time import pytest import platform -from time import sleep # Save the Current Working Directory to find configuration files. CWD = os.path.dirname(os.path.realpath(__file__)) From 80a4f87c9a38d5e893f7e24da11cc0c885db682e Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 12 Jul 2024 17:09:16 +0300 Subject: [PATCH 397/472] bgpd: Mark VRF instance as auto created if import vrf is configured for this instance If we create a new BGP instance (in this case VRF instance), it MUST be marked as auto created, to avoid bgpd changing VRF instance's ASN to the default VRF's. That's because of the ordering when FRR reload is happening. Signed-off-by: Donatas Abraitis --- bgpd/bgp_vty.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0ef135183540..624edff0afbb 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10567,12 +10567,20 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd, vrf_bgp = bgp_lookup_by_name(import_name); if (!vrf_bgp) { - if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) + if (strcmp(import_name, VRF_DEFAULT_NAME) == 0) { vrf_bgp = bgp_default; - else + } else { /* Auto-create assuming the same AS */ ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type, NULL, ASNOTATION_UNDEFINED); + + /* Auto created VRF instances should be marked + * properly, otherwise we have a state after bgpd + * restart where VRF instance has default VRF's ASN. + */ + SET_FLAG(vrf_bgp->vrf_flags, BGP_VRF_AUTO); + } + if (ret) { vty_out(vty, "VRF %s is not configured as a bgp instance\n", From 7540364e58b08da7442927c1a9ffbd535d94fc46 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sat, 13 Jul 2024 12:43:31 +0300 Subject: [PATCH 398/472] tests: Check if multiple VRF instances can have different ASNs Signed-off-by: Donatas Abraitis --- .../bgp_vrf_different_asn/__init__.py | 0 .../bgp_vrf_different_asn/r1/frr.conf | 18 ++++ .../test_bgp_vrf_different_asn.py | 89 +++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 tests/topotests/bgp_vrf_different_asn/__init__.py create mode 100644 tests/topotests/bgp_vrf_different_asn/r1/frr.conf create mode 100644 tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py diff --git a/tests/topotests/bgp_vrf_different_asn/__init__.py b/tests/topotests/bgp_vrf_different_asn/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/tests/topotests/bgp_vrf_different_asn/r1/frr.conf b/tests/topotests/bgp_vrf_different_asn/r1/frr.conf new file mode 100644 index 000000000000..b325dfb7f096 --- /dev/null +++ b/tests/topotests/bgp_vrf_different_asn/r1/frr.conf @@ -0,0 +1,18 @@ +! +vrf vrf100 + vni 10100 +exit-vrf +! +interface r1-eth0 vrf vrf100 + ip address 192.168.1.1/24 +! +router bgp 65000 + address-family ipv4 unicast + import vrf vrf100 + exit-address-family +! +router bgp 65100 vrf vrf100 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py b/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py new file mode 100644 index 000000000000..7334305ae4c5 --- /dev/null +++ b/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# Copyright (c) 2024 by +# Donatas Abraitis +# + +import os +import sys +import json +import pytest +import functools + +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen + +pytestmark = [pytest.mark.bgpd] + + +def build_topo(tgen): + for routern in range(1, 2): + tgen.add_router("r{}".format(routern)) + + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + + +def setup_module(mod): + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + r1 = tgen.gears["r1"] + r1.run("ip link add vrf100 type vrf table 1001") + r1.run("ip link set up dev vrf100") + r1.run("ip link set r1-eth0 master vrf100") + + router_list = tgen.routers() + + for _, (rname, router) in enumerate(router_list.items(), 1): + router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname))) + + tgen.start_router() + + +def teardown_module(mod): + tgen = get_topogen() + tgen.stop_topology() + + +def test_bgp_vrf_different_asn(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + def _bgp_check_imported_route(): + output = json.loads( + tgen.gears["r1"].vtysh_cmd("show ip route 192.168.1.0/24 json") + ) + expected = { + "192.168.1.0/24": [ + { + "installed": True, + "selected": True, + "nexthops": [ + { + "interfaceName": "vrf100", + "vrf": "vrf100", + "active": True, + } + ], + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_imported_route) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see 192.168.1.0/24 being imported into a default VRF" + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From 03c086866bdee9daf55420b88593345b9eb6be15 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sat, 13 Jul 2024 23:19:57 +0300 Subject: [PATCH 399/472] bgpd: Skip automatically created BGP instances for show CMDs When using e.g. `adverise-all-vni`, and/or `import vrf ...`, the VRF instance is created with a default's VRF ASN and tagged as AUTO_VRF. We MUST skip them here also. Signed-off-by: Donatas Abraitis --- bgpd/bgp_vty.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 624edff0afbb..0d50a239024e 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -12753,6 +12753,9 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi, vty_out(vty, "{\n"); for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + continue; + nbr_output = true; if (use_json) { if (!is_first) @@ -16138,6 +16141,9 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty, vty_out(vty, "{\n"); for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + continue; + nbr_output = true; if (use_json) { if (!(json = json_object_new_object())) { @@ -16697,6 +16703,9 @@ static int bgp_show_all_instance_route_leak_vty(struct vty *vty, afi_t afi, if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT) vrf_name = bgp->name; + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + continue; + if (use_json) { json_vrf = json_object_new_object(); } else { @@ -16787,6 +16796,9 @@ static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi, struct bgp *bgp; for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) { + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + continue; + if (!uj) vty_out(vty, "\nInstance %s:\n", (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) From c6c0403c61c157a9507781c332e152a2b220da52 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sat, 13 Jul 2024 13:14:33 +0300 Subject: [PATCH 400/472] tests: Check if VRF instance has a different ASN than a default VRF Signed-off-by: Donatas Abraitis --- .../test_bgp_vrf_different_asn.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py b/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py index 7334305ae4c5..9a1a9ec7667a 100644 --- a/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py +++ b/tests/topotests/bgp_vrf_different_asn/test_bgp_vrf_different_asn.py @@ -58,6 +58,24 @@ def test_bgp_vrf_different_asn(): if tgen.routers_have_failure(): pytest.skip(tgen.errors) + def _bgp_check_instances(): + output = json.loads(tgen.gears["r1"].vtysh_cmd("show bgp vrf all json")) + expected = { + "default": { + "vrfName": "default", + "localAS": 65000, + }, + "vrf100": { + "vrfName": "vrf100", + "localAS": 65100, + }, + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_instances) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert result is None, "Can't see vrf100 to be under 65100 ASN" + def _bgp_check_imported_route(): output = json.loads( tgen.gears["r1"].vtysh_cmd("show ip route 192.168.1.0/24 json") From bfedb38110e8d3e5471718a0f9abe8836ffc7143 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Mon, 15 Jul 2024 16:20:31 +0300 Subject: [PATCH 401/472] bgpd: Skip empty (auto created) VRF instances when deleting a default BGP instance Auto created VRF instances does not have any config, so it's not relevant depending on them. Signed-off-by: Donatas Abraitis --- bgpd/bgp_vty.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 0d50a239024e..bce820237792 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1701,6 +1701,10 @@ DEFUN (no_router_bgp, for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, tmp_bgp)) { if (tmp_bgp->inst_type != BGP_INSTANCE_TYPE_VRF) continue; + + if (CHECK_FLAG(tmp_bgp->vrf_flags, BGP_VRF_AUTO)) + continue; + if (CHECK_FLAG( tmp_bgp->af_flags[AFI_IP] [SAFI_UNICAST], From c2f2dde5c1b13aeccf0c9532bba32136abe33c0d Mon Sep 17 00:00:00 2001 From: sri-mohan1 Date: Sun, 19 May 2024 14:40:55 +0530 Subject: [PATCH 402/472] zebra: changes for code maintainability these changes are for improving the code maintainability and readability Signed-off-by: sri-mohan1 --- zebra/zebra_vxlan_if.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/zebra/zebra_vxlan_if.c b/zebra/zebra_vxlan_if.c index f4b859b861f3..17ab05c1f3f5 100644 --- a/zebra/zebra_vxlan_if.c +++ b/zebra/zebra_vxlan_if.c @@ -208,13 +208,13 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, chgflags); /* Removed from bridge? Cleanup and return */ - if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) && + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_MASTER_CHANGE) && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { zebra_vxlan_process_l3vni_oper_down(zl3vni); return 0; } - if ((chgflags & ZEBRA_VXLIF_MASTER_MAC_CHANGE) && + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_MASTER_MAC_CHANGE) && if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) { zebra_vxlan_process_l3vni_oper_down(zl3vni); zebra_vxlan_process_l3vni_oper_up(zl3vni); @@ -224,7 +224,7 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, /* access-vlan change - process oper down, associate with new * svi_if and then process oper up again */ - if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_VLAN_CHANGE)) { if (if_is_operative(ifp)) { zebra_vxlan_process_l3vni_oper_down(zl3vni); zl3vni->svi_if = NULL; @@ -242,7 +242,7 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, * local-ip change - process oper down, associate with new * local-ip and then process oper up again */ - if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) { + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_LOCAL_IP_CHANGE)) { if (if_is_operative(ifp)) { zebra_vxlan_process_l3vni_oper_down(zl3vni); zl3vni->local_vtep_ip = vxl->vtep_ip; @@ -262,7 +262,7 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, zl3vni_bridge_if_set(zl3vni, br_if, true /* set */); /* if we have a valid new master, process l3-vni oper up */ - if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) { + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_MASTER_CHANGE)) { if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) zebra_vxlan_process_l3vni_oper_up(zl3vni); } @@ -285,7 +285,7 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, chgflags); /* Removed from bridge? Cleanup and return */ - if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE) && + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_MASTER_CHANGE) && (zif->brslave_info.bridge_ifindex == IFINDEX_INTERNAL)) { /* Delete from client, remove all remote VTEPs */ /* Also, free up all MACs and neighbors. */ @@ -298,7 +298,7 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, } /* Handle other changes. */ - if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_VLAN_CHANGE)) { /* Remove all existing local neigh and MACs for this VNI * (including from BGP) */ @@ -341,9 +341,10 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, return 0; /* Inform BGP, if there is a change of interest. */ - if (chgflags & - (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE | - ZEBRA_VXLIF_MCAST_GRP_CHANGE | ZEBRA_VXLIF_VLAN_CHANGE)) + if (CHECK_FLAG(chgflags, (ZEBRA_VXLIF_MASTER_CHANGE | + ZEBRA_VXLIF_LOCAL_IP_CHANGE | + ZEBRA_VXLIF_MCAST_GRP_CHANGE | + ZEBRA_VXLIF_VLAN_CHANGE))) zebra_evpn_send_add_to_client(zevpn); /* If there is a valid new master or a VLAN mapping change, @@ -351,9 +352,9 @@ static int zebra_vxlan_if_update_vni(struct interface *ifp, * Also, reinstall any remote MACs and neighbors * for this VNI (based on new VLAN). */ - if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) + if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_MASTER_CHANGE)) zebra_evpn_read_mac_neigh(zevpn, ifp); - else if (chgflags & ZEBRA_VXLIF_VLAN_CHANGE) { + else if (CHECK_FLAG(chgflags, ZEBRA_VXLIF_VLAN_CHANGE)) { struct neigh_walk_ctx n_wctx; zebra_evpn_read_mac_neigh(zevpn, ifp); From 4395fcd8e120958a91d3a11f918e9071b1cb5619 Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Wed, 10 Jul 2024 16:46:29 -0700 Subject: [PATCH 403/472] bgpd: backpressure - fix to properly remove dest for bgp under deletion In case of imported routes (L3vni/vrf leaks), when a bgp instance is being deleted, the peer->bgp comparision with the incoming bgp to remove the dest from the pending fifo is wrong. This can lead to the fifo having stale entries resulting in crash. Two changes are done here. - Instead of pop/push items in list if the struct bgp doesnt match, simply iterate the list and remove the expected ones. - Corrected the way bgp is fetched from dest rather than relying on path_info->peer so that it works for all kinds of routes. Ticket :#3980988 Signed-off-by: Chirag Shah Signed-off-by: Rajasekar Raja --- bgpd/bgp_evpn.c | 12 ++++++------ bgpd/bgpd.c | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 75a7d85e88fc..baf1d4ca6de7 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -6333,16 +6333,16 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) { struct bgp_dest *dest = NULL; - uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head); + struct bgp_dest *dest_next = NULL; - while (ann_count) { - dest = zebra_announce_pop(&bm->zebra_announce_head); - ann_count--; + for (dest = zebra_announce_first(&bm->zebra_announce_head); dest; + dest = dest_next) { + dest_next = zebra_announce_next(&bm->zebra_announce_head, dest); if (dest->za_vpn == vpn) { bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); - } else - zebra_announce_add_tail(&bm->zebra_announce_head, dest); + zebra_announce_del(&bm->zebra_announce_head, dest); + } } bgp_evpn_remote_ip_hash_destroy(vpn); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 3810413adcf0..b6f7e29db298 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3936,19 +3936,25 @@ int bgp_delete(struct bgp *bgp) safi_t safi; int i; struct bgp_dest *dest = NULL; + struct bgp_dest *dest_next = NULL; + struct bgp_table *dest_table = NULL; struct graceful_restart_info *gr_info; - uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head); assert(bgp); - while (ann_count) { - dest = zebra_announce_pop(&bm->zebra_announce_head); - ann_count--; - if (dest->za_bgp_pi->peer->bgp == bgp) { + /* + * Iterate the pending dest list and remove all the dest pertaininig to + * the bgp under delete. + */ + for (dest = zebra_announce_first(&bm->zebra_announce_head); dest; + dest = dest_next) { + dest_next = zebra_announce_next(&bm->zebra_announce_head, dest); + dest_table = bgp_dest_table(dest); + if (dest_table->bgp == bgp) { bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); - } else - zebra_announce_add_tail(&bm->zebra_announce_head, dest); + zebra_announce_del(&bm->zebra_announce_head, dest); + } } bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL); From 186db96c06e4f44b4450fcba88f0fa680ee0b92d Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Wed, 10 Jul 2024 20:17:14 -0700 Subject: [PATCH 404/472] bgpd: backpressure - Improve debuggability Improve debuggability in backpressure code. Ticket :#3980988 Signed-off-by: Rajasekar Raja --- bgpd/bgpd.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index b6f7e29db298..476a01b8ef08 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3939,6 +3939,7 @@ int bgp_delete(struct bgp *bgp) struct bgp_dest *dest_next = NULL; struct bgp_table *dest_table = NULL; struct graceful_restart_info *gr_info; + uint32_t cnt_before, cnt_after; assert(bgp); @@ -3946,6 +3947,7 @@ int bgp_delete(struct bgp *bgp) * Iterate the pending dest list and remove all the dest pertaininig to * the bgp under delete. */ + cnt_before = zebra_announce_count(&bm->zebra_announce_head); for (dest = zebra_announce_first(&bm->zebra_announce_head); dest; dest = dest_next) { dest_next = zebra_announce_next(&bm->zebra_announce_head, dest); @@ -3957,6 +3959,11 @@ int bgp_delete(struct bgp *bgp) } } + cnt_after = zebra_announce_count(&bm->zebra_announce_head); + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Zebra Announce Fifo cleanup count before %u and after %u during BGP %s deletion", + cnt_before, cnt_after, bgp->name_pretty); + bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL); /* make sure we withdraw any exported routes */ From d9e51c6399a655acd408224f044acd62765bcefe Mon Sep 17 00:00:00 2001 From: sri-mohan1 Date: Tue, 16 Jul 2024 15:23:52 +0530 Subject: [PATCH 405/472] bfdd: changes for code maintainability these changes are for improving the code maintainability and readability Signed-off-by: sri-mohan1 --- bfdd/bfd.c | 4 ++-- bfdd/bfd.h | 25 +++++++++++++------------ bfdd/bfd_packet.c | 4 ++-- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 3096f47d5c2b..b6b437a7919c 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -410,8 +410,8 @@ static uint32_t ptm_bfd_gen_ID(void) * random session identification numbers. */ do { - session_id = ((frr_weak_random() << 16) & 0xFFFF0000) - | (frr_weak_random() & 0x0000FFFF); + session_id = CHECK_FLAG((frr_weak_random() << 16), 0xFFFF0000) | + CHECK_FLAG(frr_weak_random(), 0x0000FFFF); } while (session_id == 0 || bfd_id_lookup(session_id) != NULL); return session_id; diff --git a/bfdd/bfd.h b/bfdd/bfd.h index f4ff884e0072..be04e655abf0 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -97,8 +97,9 @@ struct bfd_echo_pkt { /* Macros for manipulating control packets */ #define BFD_VERMASK 0x07 #define BFD_DIAGMASK 0x1F -#define BFD_GETVER(diag) ((diag >> 5) & BFD_VERMASK) -#define BFD_SETVER(diag, val) ((diag) |= (val & BFD_VERMASK) << 5) +#define BFD_GETVER(diag) (CHECK_FLAG((diag >> 5), BFD_VERMASK)) +#define BFD_SETVER(diag, val) \ + SET_FLAG((diag), CHECK_FLAG(val, BFD_VERMASK) << 5) #define BFD_VERSION 1 #define BFD_PBIT 0x20 #define BFD_FBIT 0x10 @@ -106,36 +107,36 @@ struct bfd_echo_pkt { #define BFD_ABIT 0x04 #define BFD_DEMANDBIT 0x02 #define BFD_MBIT 0x01 -#define BFD_GETMBIT(flags) (flags & BFD_MBIT) +#define BFD_GETMBIT(flags) (CHECK_FLAG(flags, BFD_MBIT)) #define BFD_SETDEMANDBIT(flags, val) \ { \ if ((val)) \ - flags |= BFD_DEMANDBIT; \ + SET_FLAG(flags, BFD_DEMANDBIT); \ } #define BFD_SETPBIT(flags, val) \ { \ if ((val)) \ - flags |= BFD_PBIT; \ + SET_FLAG(flags, BFD_PBIT); \ } -#define BFD_GETPBIT(flags) (flags & BFD_PBIT) +#define BFD_GETPBIT(flags) (CHECK_FLAG(flags, BFD_PBIT)) #define BFD_SETFBIT(flags, val) \ { \ if ((val)) \ - flags |= BFD_FBIT; \ + SET_FLAG(flags, BFD_FBIT); \ } -#define BFD_GETFBIT(flags) (flags & BFD_FBIT) +#define BFD_GETFBIT(flags) (CHECK_FLAG(flags, BFD_FBIT)) #define BFD_SETSTATE(flags, val) \ { \ if ((val)) \ - flags |= (val & 0x3) << 6; \ + SET_FLAG(flags, (CHECK_FLAG(val, 0x3) << 6)); \ } -#define BFD_GETSTATE(flags) ((flags >> 6) & 0x3) +#define BFD_GETSTATE(flags) (CHECK_FLAG((flags >> 6), 0x3)) #define BFD_SETCBIT(flags, val) \ { \ if ((val)) \ - flags |= val; \ + SET_FLAG(flags, val); \ } -#define BFD_GETCBIT(flags) (flags & BFD_CBIT) +#define BFD_GETCBIT(flags) (CHECK_FLAG(flags, BFD_CBIT)) #define BFD_ECHO_VERSION 1 #define BFD_ECHO_PKT_LEN sizeof(struct bfd_echo_pkt) diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 8110f434c21f..f9397fa128db 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -982,7 +982,7 @@ void bfd_recv_cb(struct event *t) } /* Save remote diagnostics before state switch. */ - bfd->remote_diag = cp->diag & BFD_DIAGMASK; + bfd->remote_diag = CHECK_FLAG(cp->diag, BFD_DIAGMASK); /* Update remote timers settings. */ bfd->remote_timers.desired_min_tx = ntohl(cp->timers.desired_min_tx); @@ -1738,7 +1738,7 @@ void bfd_peer_mac_set(int sd, struct bfd_session *bfd, if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_MAC_SET)) return; - if (ifp->flags & IFF_NOARP) + if (CHECK_FLAG(ifp->flags, IFF_NOARP)) return; if (peer->sa_sin.sin_family == AF_INET) { From 895e97c8da89f182781583f1de3816d604e91059 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Tue, 16 Jul 2024 13:35:14 +0200 Subject: [PATCH 406/472] build: display local state dir configuration Configure is displaying the run state directory but not the local state directory. > FRRouting configuration > ------------------------------ > state file directory : /usr/var/run/frr > config file directory : /etc/frr Display the local state directory as well. > local state file dir : /usr/var/lib/frr > run state file dir : /usr/var/run/frr > config file directory : /etc/frr Signed-off-by: Louis Scalbert --- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ec409aaf1d60..59636194f770 100644 --- a/configure.ac +++ b/configure.ac @@ -2913,7 +2913,8 @@ compiler : ${CC} compiler flags : ${CFLAGS} ${WERROR} ${AC_CFLAGS} ${SAN_FLAGS} make : ${MAKE-make} linker flags : ${LDFLAGS} ${SAN_FLAGS} ${LIBS} ${LIBCAP} ${LIBREADLINE} ${LIBM} -state file directory : ${e_frr_runstatedir} +local state file dir : ${e_frr_libstatedir} +run state file dir : ${e_frr_runstatedir} config file directory : ${e_frr_sysconfdir} module directory : ${e_moduledir} script directory : ${e_scriptdir} From fd8edc3dfbd41ff1ba8c21ea258276f3dab71e4b Mon Sep 17 00:00:00 2001 From: Nathan Bahr Date: Wed, 12 Jun 2024 16:26:48 +0000 Subject: [PATCH 407/472] pimd, lib, vtysh: Added new 'router pim[6] [vrf NAME]' config node Moved all existing global/vrf PIM config to the new subnode. Existing configuration updated to be hidden and deprecated. Both versions of configuration still work together. Signed-off-by: Nathan Bahr --- lib/command.h | 2 + pimd/pim6_cmd.c | 1127 ++++++++++++++-- pimd/pim_addr.h | 2 + pimd/pim_cmd.c | 2845 +++++++++++++++++++++++++++++++++-------- pimd/pim_cmd_common.c | 188 +-- pimd/pim_cmd_common.h | 2 + pimd/pim_instance.c | 21 +- pimd/pim_msdp.c | 18 +- pimd/pim_msdp.h | 11 +- pimd/pim_nb.h | 4 - pimd/pim_rp.c | 13 +- pimd/pim_rp.h | 3 +- pimd/pim_vty.c | 68 +- vtysh/vtysh.c | 89 ++ vtysh/vtysh_config.c | 5 + 15 files changed, 3523 insertions(+), 875 deletions(-) diff --git a/lib/command.h b/lib/command.h index 6f819c7e3693..57e3b9cda0b7 100644 --- a/lib/command.h +++ b/lib/command.h @@ -182,6 +182,8 @@ enum node_type { ISIS_SRV6_NODE_MSD_NODE, /* ISIS SRv6 Node MSDs node */ MGMTD_NODE, /* MGMTD node. */ RPKI_VRF_NODE, /* RPKI node for VRF */ + PIM_NODE, /* PIM protocol mode */ + PIM6_NODE, /* PIM protocol for IPv6 mode */ NODE_TYPE_MAX, /* maximum */ }; /* clang-format on */ diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c index ec912700d193..99f1474712b5 100644 --- a/pimd/pim6_cmd.c +++ b/pimd/pim6_cmd.c @@ -41,45 +41,207 @@ static struct cmd_node debug_node = { .config_write = pim_debug_config_write, }; -DEFPY (ipv6_pim_joinprune_time, - ipv6_pim_joinprune_time_cmd, - "ipv6 pim join-prune-interval (1-65535)$jpi", - IPV6_STR - PIM_STR +DEFPY_NOSH (router_pim6, + router_pim6_cmd, + "router pim6 [vrf NAME]", + "Enable a routing process\n" + "Start PIM6 configuration\n" + VRF_CMD_HELP_STR) +{ + char xpath[XPATH_MAXLEN]; + const char *vrf_name; + + if (vrf) + vrf_name = vrf; + else + vrf_name = VRF_DEFAULT_NAME; + + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", + vrf_name, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) != CMD_SUCCESS) + return CMD_WARNING_CONFIG_FAILED; + + VTY_PUSH_XPATH(PIM6_NODE, xpath); + + return CMD_SUCCESS; +} + +DEFPY (no_router_pim6, + no_router_pim6_cmd, + "no router pim6 [vrf NAME]", + NO_STR + "Enable a routing process\n" + "Start PIM6 configuration\n" + VRF_CMD_HELP_STR) +{ + char xpath[XPATH_MAXLEN]; + const char *vrf_name; + + if (vrf) + vrf_name = vrf; + else + vrf_name = VRF_DEFAULT_NAME; + + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", + vrf_name, FRR_PIM_AF_XPATH_VAL); + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY (pim6_joinprune_time, + pim6_joinprune_time_cmd, + "join-prune-interval (1-65535)$jpi", "Join Prune Send Interval\n" "Seconds\n") { return pim_process_join_prune_cmd(vty, jpi_str); } +DEFPY_ATTR(ipv6_joinprune_time, + ipv6_pim_joinprune_time_cmd, + "ipv6 pim join-prune-interval (1-65535)$jpi", + IPV6_STR PIM_STR + "Join Prune Send Interval\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_join_prune_cmd(vty, jpi_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_joinprune_time, - no_ipv6_pim_joinprune_time_cmd, - "no ipv6 pim join-prune-interval [(1-65535)]", +DEFPY (no_pim6_joinprune_time, + no_pim6_joinprune_time_cmd, + "no join-prune-interval [(1-65535)]", NO_STR - IPV6_STR - PIM_STR "Join Prune Send Interval\n" IGNORED_IN_NO_STR) { return pim_process_no_join_prune_cmd(vty); } +DEFPY_ATTR(no_ipv6_pim_joinprune_time, + no_ipv6_pim_joinprune_time_cmd, + "no ipv6 pim join-prune-interval [(1-65535)]", + NO_STR + IPV6_STR + PIM_STR + "Join Prune Send Interval\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_join_prune_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (ipv6_pim_spt_switchover_infinity, - ipv6_pim_spt_switchover_infinity_cmd, - "ipv6 pim spt-switchover infinity-and-beyond", - IPV6_STR - PIM_STR +DEFPY (pim6_spt_switchover_infinity, + pim6_spt_switchover_infinity_cmd, + "spt-switchover infinity-and-beyond", "SPT-Switchover\n" "Never switch to SPT Tree\n") { return pim_process_spt_switchover_infinity_cmd(vty); } +DEFPY_ATTR(ipv6_spt_switchover_infinity, + ipv6_pim_spt_switchover_infinity_cmd, + "ipv6 pim spt-switchover infinity-and-beyond", + IPV6_STR + PIM_STR + "SPT-Switchover\n" + "Never switch to SPT Tree\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_spt_switchover_infinity_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (ipv6_pim_spt_switchover_infinity_plist, - ipv6_pim_spt_switchover_infinity_plist_cmd, - "ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist", - IPV6_STR - PIM_STR +DEFPY (pim6_spt_switchover_infinity_plist, + pim6_spt_switchover_infinity_plist_cmd, + "spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist", "SPT-Switchover\n" "Never switch to SPT Tree\n" "Prefix-List to control which groups to switch\n" @@ -87,25 +249,104 @@ DEFPY (ipv6_pim_spt_switchover_infinity_plist, { return pim_process_spt_switchover_prefixlist_cmd(vty, plist); } +DEFPY_ATTR(ipv6_spt_switchover_infinity_plist, + ipv6_pim_spt_switchover_infinity_plist_cmd, + "ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist", + IPV6_STR + PIM_STR + "SPT-Switchover\n" + "Never switch to SPT Tree\n" + "Prefix-List to control which groups to switch\n" + "Prefix-List name\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_spt_switchover_prefixlist_cmd(vty, plist); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_spt_switchover_infinity, - no_ipv6_pim_spt_switchover_infinity_cmd, - "no ipv6 pim spt-switchover infinity-and-beyond", +DEFPY (no_pim6_spt_switchover_infinity, + no_pim6_spt_switchover_infinity_cmd, + "no spt-switchover infinity-and-beyond", NO_STR - IPV6_STR - PIM_STR "SPT_Switchover\n" "Never switch to SPT Tree\n") { return pim_process_no_spt_switchover_cmd(vty); } +DEFPY_ATTR(no_ipv6_pim_spt_switchover_infinity, + no_ipv6_pim_spt_switchover_infinity_cmd, + "no ipv6 pim spt-switchover infinity-and-beyond", + NO_STR + IPV6_STR + PIM_STR + "SPT_Switchover\n" + "Never switch to SPT Tree\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_spt_switchover_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_spt_switchover_infinity_plist, - no_ipv6_pim_spt_switchover_infinity_plist_cmd, - "no ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME", +DEFPY (no_pim6_spt_switchover_infinity_plist, + no_pim6_spt_switchover_infinity_plist_cmd, + "no spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME", NO_STR - IPV6_STR - PIM_STR "SPT_Switchover\n" "Never switch to SPT Tree\n" "Prefix-List to control which groups to switch\n" @@ -113,100 +354,453 @@ DEFPY (no_ipv6_pim_spt_switchover_infinity_plist, { return pim_process_no_spt_switchover_cmd(vty); } +DEFPY_ATTR(no_ipv6_pim_spt_switchover_infinity_plist, + no_ipv6_pim_spt_switchover_infinity_plist_cmd, + "no ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME", + NO_STR + IPV6_STR + PIM_STR + "SPT_Switchover\n" + "Never switch to SPT Tree\n" + "Prefix-List to control which groups to switch\n" + "Prefix-List name\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_spt_switchover_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (ipv6_pim_packets, - ipv6_pim_packets_cmd, - "ipv6 pim packets (1-255)", - IPV6_STR - PIM_STR +DEFPY (pim6_packets, + pim6_packets_cmd, + "packets (1-255)", "packets to process at one time per fd\n" "Number of packets\n") { return pim_process_pim_packet_cmd(vty, packets_str); } +DEFPY_ATTR(ipv6_pim_packets, + ipv6_pim_packets_cmd, + "ipv6 pim packets (1-255)", + IPV6_STR + PIM_STR + "packets to process at one time per fd\n" + "Number of packets\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_pim_packet_cmd(vty, packets_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_packets, - no_ipv6_pim_packets_cmd, - "no ipv6 pim packets [(1-255)]", +DEFPY (no_pim6_packets, + no_pim6_packets_cmd, + "no packets [(1-255)]", NO_STR - IPV6_STR - PIM_STR "packets to process at one time per fd\n" IGNORED_IN_NO_STR) { return pim_process_no_pim_packet_cmd(vty); } +DEFPY_ATTR(no_ipv6_pim_packets, + no_ipv6_pim_packets_cmd, + "no ipv6 pim packets [(1-255)]", + NO_STR + IPV6_STR + PIM_STR + "packets to process at one time per fd\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } -DEFPY (ipv6_pim_keep_alive, - ipv6_pim_keep_alive_cmd, - "ipv6 pim keep-alive-timer (1-65535)$kat", - IPV6_STR - PIM_STR + ret = pim_process_no_pim_packet_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim6_keep_alive, + pim6_keep_alive_cmd, + "keep-alive-timer (1-65535)$kat", "Keep alive Timer\n" "Seconds\n") { return pim_process_keepalivetimer_cmd(vty, kat_str); } +DEFPY_ATTR(ipv6_pim_keep_alive, + ipv6_pim_keep_alive_cmd, + "ipv6 pim keep-alive-timer (1-65535)$kat", + IPV6_STR + PIM_STR + "Keep alive Timer\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_keepalivetimer_cmd(vty, kat_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_keep_alive, - no_ipv6_pim_keep_alive_cmd, - "no ipv6 pim keep-alive-timer [(1-65535)]", +DEFPY (no_pim6_keep_alive, + no_pim6_keep_alive_cmd, + "no keep-alive-timer [(1-65535)]", NO_STR - IPV6_STR - PIM_STR "Keep alive Timer\n" IGNORED_IN_NO_STR) { return pim_process_no_keepalivetimer_cmd(vty); } +DEFPY_ATTR(no_ipv6_pim_keep_alive, + no_ipv6_pim_keep_alive_cmd, + "no ipv6 pim keep-alive-timer [(1-65535)]", + NO_STR + IPV6_STR + PIM_STR + "Keep alive Timer\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_keepalivetimer_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (ipv6_pim_rp_keep_alive, - ipv6_pim_rp_keep_alive_cmd, - "ipv6 pim rp keep-alive-timer (1-65535)$kat", - IPV6_STR - PIM_STR +DEFPY (pim6_rp_keep_alive, + pim6_rp_keep_alive_cmd, + "rp keep-alive-timer (1-65535)$kat", "Rendezvous Point\n" "Keep alive Timer\n" "Seconds\n") { return pim_process_rp_kat_cmd(vty, kat_str); } +DEFPY_ATTR(ipv6_pim_rp_keep_alive, + ipv6_pim_rp_keep_alive_cmd, + "ipv6 pim rp keep-alive-timer (1-65535)$kat", + IPV6_STR + PIM_STR + "Rendezvous Point\n" + "Keep alive Timer\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_rp_kat_cmd(vty, kat_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_rp_keep_alive, - no_ipv6_pim_rp_keep_alive_cmd, - "no ipv6 pim rp keep-alive-timer [(1-65535)]", +DEFPY (no_pim6_rp_keep_alive, + no_pim6_rp_keep_alive_cmd, + "no rp keep-alive-timer [(1-65535)]", NO_STR - IPV6_STR - PIM_STR "Rendezvous Point\n" "Keep alive Timer\n" IGNORED_IN_NO_STR) { return pim_process_no_rp_kat_cmd(vty); } +DEFPY_ATTR(no_ipv6_pim_rp_keep_alive, + no_ipv6_pim_rp_keep_alive_cmd, + "no ipv6 pim rp keep-alive-timer [(1-65535)]", + NO_STR + IPV6_STR + PIM_STR + "Rendezvous Point\n" + "Keep alive Timer\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } -DEFPY (ipv6_pim_register_suppress, - ipv6_pim_register_suppress_cmd, - "ipv6 pim register-suppress-time (1-65535)$rst", - IPV6_STR - PIM_STR + ret = pim_process_no_rp_kat_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim6_register_suppress, + pim6_register_suppress_cmd, + "register-suppress-time (1-65535)$rst", "Register Suppress Timer\n" "Seconds\n") { return pim_process_register_suppress_cmd(vty, rst_str); } +DEFPY_ATTR(ipv6_pim_register_suppress, + ipv6_pim_register_suppress_cmd, + "ipv6 pim register-suppress-time (1-65535)$rst", + IPV6_STR + PIM_STR + "Register Suppress Timer\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_register_suppress_cmd(vty, rst_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_register_suppress, - no_ipv6_pim_register_suppress_cmd, - "no ipv6 pim register-suppress-time [(1-65535)]", +DEFPY (no_pim6_register_suppress, + no_pim6_register_suppress_cmd, + "no register-suppress-time [(1-65535)]", NO_STR - IPV6_STR - PIM_STR "Register Suppress Timer\n" IGNORED_IN_NO_STR) { return pim_process_no_register_suppress_cmd(vty); } +DEFPY_ATTR(no_ipv6_pim_register_suppress, + no_ipv6_pim_register_suppress_cmd, + "no ipv6 pim register-suppress-time [(1-65535)]", + NO_STR + IPV6_STR + PIM_STR + "Register Suppress Timer\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_register_suppress_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} DEFPY (interface_ipv6_pim, interface_ipv6_pim_cmd, @@ -405,11 +999,9 @@ DEFPY (interface_no_ipv6_mroute, source_str); } -DEFPY (ipv6_pim_rp, - ipv6_pim_rp_cmd, - "ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp", - IPV6_STR - PIM_STR +DEFPY (pim6_rp, + pim6_rp_cmd, + "rp X:X::X:X$rp [X:X::X:X/M]$gp", "Rendezvous Point\n" "ipv6 address of RP\n" "Group Address range to cover\n") @@ -418,13 +1010,53 @@ DEFPY (ipv6_pim_rp, return pim_process_rp_cmd(vty, rp_str, group_str); } +DEFPY_ATTR(ipv6_pim_rp, + ipv6_pim_rp_cmd, + "ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp", + IPV6_STR + PIM_STR + "Rendezvous Point\n" + "ipv6 address of RP\n" + "Group Address range to cover\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *group_str = (gp_str) ? gp_str : "FF00::0/8"; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_rp_cmd(vty, rp_str, group_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_rp, - no_ipv6_pim_rp_cmd, - "no ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp", +DEFPY (no_pim6_rp, + no_pim6_rp_cmd, + "no rp X:X::X:X$rp [X:X::X:X/M]$gp", NO_STR - IPV6_STR - PIM_STR "Rendezvous Point\n" "ipv6 address of RP\n" "Group Address range to cover\n") @@ -433,12 +1065,53 @@ DEFPY (no_ipv6_pim_rp, return pim_process_no_rp_cmd(vty, rp_str, group_str); } +DEFPY_ATTR(no_ipv6_pim_rp, + no_ipv6_pim_rp_cmd, + "no ipv6 pim rp X:X::X:X$rp [X:X::X:X/M]$gp", + NO_STR + IPV6_STR + PIM_STR + "Rendezvous Point\n" + "ipv6 address of RP\n" + "Group Address range to cover\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *group_str = (gp_str) ? gp_str : "FF00::0/8"; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } -DEFPY (ipv6_pim_rp_prefix_list, - ipv6_pim_rp_prefix_list_cmd, - "ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", - IPV6_STR - PIM_STR + ret = pim_process_no_rp_cmd(vty, rp_str, group_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim6_rp_prefix_list, + pim6_rp_prefix_list_cmd, + "rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", "Rendezvous Point\n" "ipv6 address of RP\n" "group prefix-list filter\n" @@ -446,13 +1119,53 @@ DEFPY (ipv6_pim_rp_prefix_list, { return pim_process_rp_plist_cmd(vty, rp_str, plist); } +DEFPY_ATTR(ipv6_pim_rp_prefix_list, + ipv6_pim_rp_prefix_list_cmd, + "ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", + IPV6_STR + PIM_STR + "Rendezvous Point\n" + "ipv6 address of RP\n" + "group prefix-list filter\n" + "Name of a prefix-list\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_rp_plist_cmd(vty, rp_str, plist); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ipv6_pim_rp_prefix_list, - no_ipv6_pim_rp_prefix_list_cmd, - "no ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", +DEFPY (no_pim6_rp_prefix_list, + no_pim6_rp_prefix_list_cmd, + "no rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", NO_STR - IPV6_STR - PIM_STR "Rendezvous Point\n" "ipv6 address of RP\n" "group prefix-list filter\n" @@ -460,6 +1173,49 @@ DEFPY (no_ipv6_pim_rp_prefix_list, { return pim_process_no_rp_plist_cmd(vty, rp_str, plist); } +DEFPY_ATTR(no_ipv6_pim_rp_prefix_list, + no_ipv6_pim_rp_prefix_list_cmd, + "no ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist", + NO_STR + IPV6_STR + PIM_STR + "Rendezvous Point\n" + "ipv6 address of RP\n" + "group prefix-list filter\n" + "Name of a prefix-list\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_rp_plist_cmd(vty, rp_str, plist); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} DEFPY (ipv6_pim_bsm, ipv6_pim_bsm_cmd, @@ -503,10 +1259,9 @@ DEFPY (no_ipv6_pim_ucast_bsm, return pim_process_no_unicast_bsm_cmd(vty); } -DEFPY (ipv6_ssmpingd, - ipv6_ssmpingd_cmd, - "ipv6 ssmpingd [X:X::X:X]$source", - IPV6_STR +DEFPY (pim6_ssmpingd, + pim6_ssmpingd_cmd, + "ssmpingd [X:X::X:X]$source", CONF_SSMPINGD_STR "Source address\n") { @@ -514,20 +1269,99 @@ DEFPY (ipv6_ssmpingd, return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str); } +DEFPY_ATTR(ipv6_ssmpingd, + ipv6_ssmpingd_cmd, + "ipv6 ssmpingd [X:X::X:X]$source", + IPV6_STR + CONF_SSMPINGD_STR + "Source address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *src_str = (source_str) ? source_str : "::"; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + ret = pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str); -DEFPY (no_ipv6_ssmpingd, - no_ipv6_ssmpingd_cmd, - "no ipv6 ssmpingd [X:X::X:X]$source", - NO_STR - IPV6_STR - CONF_SSMPINGD_STR - "Source address\n") + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (no_pim6_ssmpingd, + no_pim6_ssmpingd_cmd, + "no ssmpingd [X:X::X:X]$source", + NO_STR + CONF_SSMPINGD_STR + "Source address\n") { const char *src_str = (source_str) ? source_str : "::"; return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str); } +DEFPY_ATTR(no_ipv6_ssmpingd, + no_ipv6_ssmpingd_cmd, + "no ipv6 ssmpingd [X:X::X:X]$source", + NO_STR + IPV6_STR + CONF_SSMPINGD_STR + "Source address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *src_str = (source_str) ? source_str : "::"; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM6_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} DEFPY (interface_ipv6_mld_join, interface_ipv6_mld_join_cmd, @@ -1733,12 +2567,16 @@ DEFPY (debug_pimv6_bsm, return CMD_SUCCESS; } -void pim_cmd_init(void) -{ - if_cmd_init(pim_interface_config_write); - - install_node(&debug_node); +struct cmd_node pim6_node = { + .name = "pim6", + .node = PIM6_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pim6)# ", + .config_write = pim_router_config_write, +}; +static void pim_install_deprecated(void) +{ install_element(CONFIG_NODE, &ipv6_pim_joinprune_time_cmd); install_element(CONFIG_NODE, &no_ipv6_pim_joinprune_time_cmd); install_element(CONFIG_NODE, &ipv6_pim_spt_switchover_infinity_cmd); @@ -1753,6 +2591,60 @@ void pim_cmd_init(void) install_element(CONFIG_NODE, &no_ipv6_pim_rp_keep_alive_cmd); install_element(CONFIG_NODE, &ipv6_pim_register_suppress_cmd); install_element(CONFIG_NODE, &no_ipv6_pim_register_suppress_cmd); + install_element(CONFIG_NODE, &ipv6_pim_rp_cmd); + install_element(VRF_NODE, &ipv6_pim_rp_cmd); + install_element(CONFIG_NODE, &no_ipv6_pim_rp_cmd); + install_element(VRF_NODE, &no_ipv6_pim_rp_cmd); + install_element(CONFIG_NODE, &ipv6_pim_rp_prefix_list_cmd); + install_element(VRF_NODE, &ipv6_pim_rp_prefix_list_cmd); + install_element(CONFIG_NODE, &no_ipv6_pim_rp_prefix_list_cmd); + install_element(VRF_NODE, &no_ipv6_pim_rp_prefix_list_cmd); + install_element(CONFIG_NODE, &ipv6_ssmpingd_cmd); + install_element(VRF_NODE, &ipv6_ssmpingd_cmd); + install_element(CONFIG_NODE, &no_ipv6_ssmpingd_cmd); + install_element(VRF_NODE, &no_ipv6_ssmpingd_cmd); +} + +void pim_cmd_init(void) +{ + if_cmd_init(pim_interface_config_write); + + install_node(&debug_node); + + pim_install_deprecated(); + + install_element(CONFIG_NODE, &router_pim6_cmd); + install_element(CONFIG_NODE, &no_router_pim6_cmd); + + install_node(&pim6_node); + install_default(PIM6_NODE); + + install_element(PIM6_NODE, &pim6_joinprune_time_cmd); + install_element(PIM6_NODE, &no_pim6_joinprune_time_cmd); + install_element(PIM6_NODE, &pim6_spt_switchover_infinity_cmd); + install_element(PIM6_NODE, &pim6_spt_switchover_infinity_plist_cmd); + install_element(PIM6_NODE, &no_pim6_spt_switchover_infinity_cmd); + install_element(PIM6_NODE, &no_pim6_spt_switchover_infinity_plist_cmd); + install_element(PIM6_NODE, &pim6_packets_cmd); + install_element(PIM6_NODE, &no_pim6_packets_cmd); + install_element(PIM6_NODE, &pim6_keep_alive_cmd); + install_element(PIM6_NODE, &no_pim6_keep_alive_cmd); + install_element(PIM6_NODE, &pim6_rp_keep_alive_cmd); + install_element(PIM6_NODE, &no_pim6_rp_keep_alive_cmd); + install_element(PIM6_NODE, &pim6_register_suppress_cmd); + install_element(PIM6_NODE, &no_pim6_register_suppress_cmd); + install_element(PIM6_NODE, &pim6_rp_cmd); + install_element(PIM6_NODE, &no_pim6_rp_cmd); + install_element(PIM6_NODE, &pim6_rp_prefix_list_cmd); + install_element(PIM6_NODE, &no_pim6_rp_prefix_list_cmd); + install_element(PIM6_NODE, &pim6_ssmpingd_cmd); + install_element(PIM6_NODE, &no_pim6_ssmpingd_cmd); + + install_element(CONFIG_NODE, &ipv6_mld_group_watermark_cmd); + install_element(VRF_NODE, &ipv6_mld_group_watermark_cmd); + install_element(CONFIG_NODE, &no_ipv6_mld_group_watermark_cmd); + install_element(VRF_NODE, &no_ipv6_mld_group_watermark_cmd); + install_element(INTERFACE_NODE, &interface_ipv6_pim_cmd); install_element(INTERFACE_NODE, &interface_no_ipv6_pim_cmd); install_element(INTERFACE_NODE, &interface_ipv6_pim_drprio_cmd); @@ -1764,10 +2656,8 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &interface_no_ipv6_pim_ssm_cmd); install_element(INTERFACE_NODE, &interface_ipv6_pim_sm_cmd); install_element(INTERFACE_NODE, &interface_no_ipv6_pim_sm_cmd); - install_element(INTERFACE_NODE, - &interface_ipv6_pim_boundary_oil_cmd); - install_element(INTERFACE_NODE, - &interface_no_ipv6_pim_boundary_oil_cmd); + install_element(INTERFACE_NODE, &interface_ipv6_pim_boundary_oil_cmd); + install_element(INTERFACE_NODE, &interface_no_ipv6_pim_boundary_oil_cmd); install_element(INTERFACE_NODE, &interface_ipv6_mroute_cmd); install_element(INTERFACE_NODE, &interface_no_ipv6_mroute_cmd); /* Install BSM command */ @@ -1775,18 +2665,7 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &no_ipv6_pim_bsm_cmd); install_element(INTERFACE_NODE, &ipv6_pim_ucast_bsm_cmd); install_element(INTERFACE_NODE, &no_ipv6_pim_ucast_bsm_cmd); - install_element(CONFIG_NODE, &ipv6_pim_rp_cmd); - install_element(VRF_NODE, &ipv6_pim_rp_cmd); - install_element(CONFIG_NODE, &no_ipv6_pim_rp_cmd); - install_element(VRF_NODE, &no_ipv6_pim_rp_cmd); - install_element(CONFIG_NODE, &ipv6_pim_rp_prefix_list_cmd); - install_element(VRF_NODE, &ipv6_pim_rp_prefix_list_cmd); - install_element(CONFIG_NODE, &no_ipv6_pim_rp_prefix_list_cmd); - install_element(VRF_NODE, &no_ipv6_pim_rp_prefix_list_cmd); - install_element(CONFIG_NODE, &ipv6_ssmpingd_cmd); - install_element(VRF_NODE, &ipv6_ssmpingd_cmd); - install_element(CONFIG_NODE, &no_ipv6_ssmpingd_cmd); - install_element(VRF_NODE, &no_ipv6_ssmpingd_cmd); + install_element(INTERFACE_NODE, &interface_ipv6_mld_cmd); install_element(INTERFACE_NODE, &interface_no_ipv6_mld_cmd); install_element(INTERFACE_NODE, &interface_ipv6_mld_join_cmd); @@ -1796,10 +2675,6 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &interface_ipv6_mld_query_interval_cmd); install_element(INTERFACE_NODE, &interface_no_ipv6_mld_query_interval_cmd); - install_element(CONFIG_NODE, &ipv6_mld_group_watermark_cmd); - install_element(VRF_NODE, &ipv6_mld_group_watermark_cmd); - install_element(CONFIG_NODE, &no_ipv6_mld_group_watermark_cmd); - install_element(VRF_NODE, &no_ipv6_mld_group_watermark_cmd); install_element(INTERFACE_NODE, &interface_ipv6_mld_query_max_response_time_cmd); install_element(INTERFACE_NODE, diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h index 7b0c3f0350e2..c1416e1dd0f6 100644 --- a/pimd/pim_addr.h +++ b/pimd/pim_addr.h @@ -26,6 +26,7 @@ typedef struct prefix_ipv4 prefix_pim; #define PIM_MAX_BITLEN IPV4_MAX_BITLEN #define PIM_AF_NAME "ip" #define PIM_AF_DBG "pim" +#define PIM_AF_ROUTER "pim" #define GM_AF_DBG "igmp" #define PIM_MROUTE_DBG "mroute" #define PIMREG "pimreg" @@ -58,6 +59,7 @@ typedef struct prefix_ipv6 prefix_pim; #define PIM_MAX_BITLEN IPV6_MAX_BITLEN #define PIM_AF_NAME "ipv6" #define PIM_AF_DBG "pimv6" +#define PIM_AF_ROUTER "pim6" #define GM_AF_DBG "mld" #define PIM_MROUTE_DBG "mroute6" #define PIMREG "pim6reg" diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index a2d756a96a20..2b8d3e56e521 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1457,19 +1457,13 @@ static void clear_interfaces(struct pim_instance *pim) static void pim_cli_legacy_mesh_group_behavior(struct vty *vty, const char *gname) { - const char *vrfname; char xpath_value[XPATH_MAXLEN]; char xpath_member_value[XPATH_MAXLEN]; const struct lyd_node *member_dnode; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return; - /* Get mesh group base XPath. */ snprintf(xpath_value, sizeof(xpath_value), - FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']", - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname); + "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname); /* Group must exists, otherwise just quit. */ if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) return; @@ -1477,8 +1471,7 @@ static void pim_cli_legacy_mesh_group_behavior(struct vty *vty, /* Group members check: */ strlcpy(xpath_member_value, xpath_value, sizeof(xpath_member_value)); strlcat(xpath_member_value, "/members", sizeof(xpath_member_value)); - if (yang_dnode_exists(vty->candidate_config->dnode, - xpath_member_value)) { + if (yang_dnode_exists(vty->candidate_config->dnode, xpath_member_value)) { member_dnode = yang_dnode_get(vty->candidate_config->dnode, xpath_member_value); if (!member_dnode || !yang_is_last_list_dnode(member_dnode)) @@ -2989,22 +2982,108 @@ DEFUN (show_ip_ssmpingd, return CMD_SUCCESS; } -DEFUN (ip_pim_spt_switchover_infinity, - ip_pim_spt_switchover_infinity_cmd, - "ip pim spt-switchover infinity-and-beyond", - IP_STR - PIM_STR +DEFPY_NOSH (router_pim, + router_pim_cmd, + "router pim [vrf NAME]", + "Enable a routing process\n" + "Start PIM configuration\n" + VRF_CMD_HELP_STR) +{ + char xpath[XPATH_MAXLEN]; + const char *vrf_name; + + if (vrf) + vrf_name = vrf; + else + vrf_name = VRF_DEFAULT_NAME; + + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", + vrf_name, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) != CMD_SUCCESS) + return CMD_WARNING_CONFIG_FAILED; + + VTY_PUSH_XPATH(PIM_NODE, xpath); + return CMD_SUCCESS; +} + +DEFPY (no_router_pim, + no_router_pim_cmd, + "no router pim [vrf NAME]", + NO_STR + "Enable a routing process\n" + "Start PIM configuration\n" + VRF_CMD_HELP_STR) +{ + char xpath[XPATH_MAXLEN]; + const char *vrf_name; + + if (vrf) + vrf_name = vrf; + else + vrf_name = VRF_DEFAULT_NAME; + + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", + vrf_name, FRR_PIM_AF_XPATH_VAL); + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + + +DEFPY (pim_spt_switchover_infinity, + pim_spt_switchover_infinity_cmd, + "spt-switchover infinity-and-beyond", "SPT-Switchover\n" "Never switch to SPT Tree\n") { return pim_process_spt_switchover_infinity_cmd(vty); } +DEFPY_ATTR(ip_pim_spt_switchover_infinity, + ip_pim_spt_switchover_infinity_cmd, + "ip pim spt-switchover infinity-and-beyond", + IP_STR + PIM_STR + "SPT-Switchover\n" + "Never switch to SPT Tree\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_spt_switchover_infinity_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (ip_pim_spt_switchover_infinity_plist, - ip_pim_spt_switchover_infinity_plist_cmd, - "ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist", - IP_STR - PIM_STR +DEFPY (pim_spt_switchover_infinity_plist, + pim_spt_switchover_infinity_plist_cmd, + "spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist", "SPT-Switchover\n" "Never switch to SPT Tree\n" "Prefix-List to control which groups to switch\n" @@ -3012,25 +3091,104 @@ DEFPY (ip_pim_spt_switchover_infinity_plist, { return pim_process_spt_switchover_prefixlist_cmd(vty, plist); } +DEFPY_ATTR(ip_pim_spt_switchover_infinity_plist, + ip_pim_spt_switchover_infinity_plist_cmd, + "ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist", + IP_STR + PIM_STR + "SPT-Switchover\n" + "Never switch to SPT Tree\n" + "Prefix-List to control which groups to switch\n" + "Prefix-List name\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_spt_switchover_prefixlist_cmd(vty, plist); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFUN (no_ip_pim_spt_switchover_infinity, - no_ip_pim_spt_switchover_infinity_cmd, - "no ip pim spt-switchover infinity-and-beyond", +DEFPY (no_pim_spt_switchover_infinity, + no_pim_spt_switchover_infinity_cmd, + "no spt-switchover infinity-and-beyond", NO_STR - IP_STR - PIM_STR "SPT_Switchover\n" "Never switch to SPT Tree\n") { return pim_process_no_spt_switchover_cmd(vty); } +DEFPY_ATTR(no_ip_pim_spt_switchover_infinity, + no_ip_pim_spt_switchover_infinity_cmd, + "no ip pim spt-switchover infinity-and-beyond", + NO_STR + IP_STR + PIM_STR + "SPT_Switchover\n" + "Never switch to SPT Tree\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_spt_switchover_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFUN (no_ip_pim_spt_switchover_infinity_plist, - no_ip_pim_spt_switchover_infinity_plist_cmd, - "no ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME", +DEFPY (no_pim_spt_switchover_infinity_plist, + no_pim_spt_switchover_infinity_plist_cmd, + "no spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME", NO_STR - IP_STR - PIM_STR "SPT_Switchover\n" "Never switch to SPT Tree\n" "Prefix-List to control which groups to switch\n" @@ -3038,28 +3196,61 @@ DEFUN (no_ip_pim_spt_switchover_infinity_plist, { return pim_process_no_spt_switchover_cmd(vty); } +DEFPY_ATTR(no_ip_pim_spt_switchover_infinity_plist, + no_ip_pim_spt_switchover_infinity_plist_cmd, + "no ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME", + NO_STR + IP_STR + PIM_STR + "SPT_Switchover\n" + "Never switch to SPT Tree\n" + "Prefix-List to control which groups to switch\n" + "Prefix-List name\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_spt_switchover_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} DEFPY (pim_register_accept_list, pim_register_accept_list_cmd, - "[no] ip pim register-accept-list PREFIXLIST4_NAME$word", + "[no] register-accept-list PREFIXLIST4_NAME$word", NO_STR - IP_STR - PIM_STR "Only accept registers from a specific source prefix list\n" "Prefix-List name\n") { - const char *vrfname; char reg_alist_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - snprintf(reg_alist_xpath, sizeof(reg_alist_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - "frr-routing:ipv4"); - strlcat(reg_alist_xpath, "/register-accept-list", - sizeof(reg_alist_xpath)); + "./register-accept-list"); if (no) nb_cli_enqueue_change(vty, reg_alist_xpath, @@ -3070,123 +3261,560 @@ DEFPY (pim_register_accept_list, return nb_cli_apply_changes(vty, NULL); } +DEFPY_ATTR(ip_pim_register_accept_list, + ip_pim_register_accept_list_cmd, + "[no] ip pim register-accept-list PREFIXLIST4_NAME$word", + NO_STR + IP_STR + PIM_STR + "Only accept registers from a specific source prefix list\n" + "Prefix-List name\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char reg_alist_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -DEFPY (ip_pim_joinprune_time, - ip_pim_joinprune_time_cmd, - "ip pim join-prune-interval (1-65535)$jpi", - IP_STR - "pim multicast routing\n" + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(reg_alist_xpath, sizeof(reg_alist_xpath), + "./register-accept-list"); + + if (no) + nb_cli_enqueue_change(vty, reg_alist_xpath, NB_OP_DESTROY, NULL); + else + nb_cli_enqueue_change(vty, reg_alist_xpath, NB_OP_MODIFY, word); + + ret = nb_cli_apply_changes(vty, NULL); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim_joinprune_time, + pim_joinprune_time_cmd, + "join-prune-interval (1-65535)$jpi", "Join Prune Send Interval\n" "Seconds\n") { return pim_process_join_prune_cmd(vty, jpi_str); } +DEFPY_ATTR(ip_pim_joinprune_time, + ip_pim_joinprune_time_cmd, + "ip pim join-prune-interval (1-65535)$jpi", + IP_STR + PIM_STR + "Join Prune Send Interval\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_join_prune_cmd(vty, jpi_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFUN (no_ip_pim_joinprune_time, - no_ip_pim_joinprune_time_cmd, - "no ip pim join-prune-interval [(1-65535)]", +DEFPY (no_pim_joinprune_time, + no_pim_joinprune_time_cmd, + "no join-prune-interval [(1-65535)]", NO_STR - IP_STR - "pim multicast routing\n" "Join Prune Send Interval\n" IGNORED_IN_NO_STR) { return pim_process_no_join_prune_cmd(vty); } +DEFPY_ATTR(no_ip_pim_joinprune_time, + no_ip_pim_joinprune_time_cmd, + "no ip pim join-prune-interval [(1-65535)]", + NO_STR + IP_STR + PIM_STR + "Join Prune Send Interval\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -DEFPY (ip_pim_register_suppress, - ip_pim_register_suppress_cmd, - "ip pim register-suppress-time (1-65535)$rst", - IP_STR - "pim multicast routing\n" + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_join_prune_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim_register_suppress, + pim_register_suppress_cmd, + "register-suppress-time (1-65535)$rst", "Register Suppress Timer\n" "Seconds\n") { return pim_process_register_suppress_cmd(vty, rst_str); } +DEFPY_ATTR(ip_pim_register_suppress, + ip_pim_register_suppress_cmd, + "ip pim register-suppress-time (1-65535)$rst", + IP_STR + PIM_STR + "Register Suppress Timer\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_register_suppress_cmd(vty, rst_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFUN (no_ip_pim_register_suppress, - no_ip_pim_register_suppress_cmd, - "no ip pim register-suppress-time [(1-65535)]", +DEFPY (no_pim_register_suppress, + no_pim_register_suppress_cmd, + "no register-suppress-time [(1-65535)]", NO_STR - IP_STR - "pim multicast routing\n" "Register Suppress Timer\n" IGNORED_IN_NO_STR) { return pim_process_no_register_suppress_cmd(vty); } +DEFPY_ATTR(no_ip_pim_register_suppress, + no_ip_pim_register_suppress_cmd, + "no ip pim register-suppress-time [(1-65535)]", + NO_STR + IP_STR + PIM_STR + "Register Suppress Timer\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_register_suppress_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (ip_pim_rp_keep_alive, - ip_pim_rp_keep_alive_cmd, - "ip pim rp keep-alive-timer (1-65535)$kat", - IP_STR - "pim multicast routing\n" +DEFPY (pim_rp_keep_alive, + pim_rp_keep_alive_cmd, + "rp keep-alive-timer (1-65535)$kat", "Rendezvous Point\n" "Keep alive Timer\n" "Seconds\n") { return pim_process_rp_kat_cmd(vty, kat_str); } +DEFPY_ATTR(ip_pim_rp_keep_alive, + ip_pim_rp_keep_alive_cmd, + "ip pim rp keep-alive-timer (1-65535)$kat", + IP_STR + PIM_STR + "Rendezvous Point\n" + "Keep alive Timer\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_rp_kat_cmd(vty, kat_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFUN (no_ip_pim_rp_keep_alive, - no_ip_pim_rp_keep_alive_cmd, - "no ip pim rp keep-alive-timer [(1-65535)]", +DEFPY (no_pim_rp_keep_alive, + no_pim_rp_keep_alive_cmd, + "no rp keep-alive-timer [(1-65535)]", NO_STR - IP_STR - "pim multicast routing\n" "Rendezvous Point\n" "Keep alive Timer\n" IGNORED_IN_NO_STR) { return pim_process_no_rp_kat_cmd(vty); } +DEFPY_ATTR(no_ip_pim_rp_keep_alive, + no_ip_pim_rp_keep_alive_cmd, + "no ip pim rp keep-alive-timer [(1-65535)]", + NO_STR + IP_STR + PIM_STR + "Rendezvous Point\n" + "Keep alive Timer\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -DEFPY (ip_pim_keep_alive, - ip_pim_keep_alive_cmd, - "ip pim keep-alive-timer (1-65535)$kat", - IP_STR - "pim multicast routing\n" + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_rp_kat_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim_keep_alive, + pim_keep_alive_cmd, + "keep-alive-timer (1-65535)$kat", "Keep alive Timer\n" "Seconds\n") { return pim_process_keepalivetimer_cmd(vty, kat_str); } - -DEFUN (no_ip_pim_keep_alive, - no_ip_pim_keep_alive_cmd, - "no ip pim keep-alive-timer [(1-65535)]", - NO_STR - IP_STR - "pim multicast routing\n" - "Keep alive Timer\n" - IGNORED_IN_NO_STR) +DEFPY_ATTR(ip_pim_keep_alive, + ip_pim_keep_alive_cmd, + "ip pim keep-alive-timer (1-65535)$kat", + IP_STR + PIM_STR + "Keep alive Timer\n" + "Seconds\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) { - return pim_process_no_keepalivetimer_cmd(vty); -} + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -DEFPY (ip_pim_packets, - ip_pim_packets_cmd, - "ip pim packets (1-255)", - IP_STR - "pim multicast routing\n" - "packets to process at one time per fd\n" - "Number of packets\n") + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_keepalivetimer_cmd(vty, kat_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (no_pim_keep_alive, + no_pim_keep_alive_cmd, + "no keep-alive-timer [(1-65535)]", + NO_STR + "Keep alive Timer\n" + IGNORED_IN_NO_STR) +{ + return pim_process_no_keepalivetimer_cmd(vty); +} +DEFPY_ATTR(no_ip_pim_keep_alive, + no_ip_pim_keep_alive_cmd, + "no ip pim keep-alive-timer [(1-65535)]", + NO_STR + IP_STR + PIM_STR + "Keep alive Timer\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_keepalivetimer_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim_packets, + pim_packets_cmd, + "packets (1-255)", + "packets to process at one time per fd\n" + "Number of packets\n") { return pim_process_pim_packet_cmd(vty, packets_str); } +DEFPY_ATTR(ip_pim_packets, + ip_pim_packets_cmd, + "ip pim packets (1-255)", + IP_STR + PIM_STR + "packets to process at one time per fd\n" + "Number of packets\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_pim_packet_cmd(vty, packets_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } -DEFUN (no_ip_pim_packets, - no_ip_pim_packets_cmd, - "no ip pim packets [(1-255)]", + return ret; +} + +DEFPY (no_pim_packets, + no_pim_packets_cmd, + "no packets [(1-255)]", NO_STR - IP_STR - "pim multicast routing\n" "packets to process at one time per fd\n" IGNORED_IN_NO_STR) { return pim_process_no_pim_packet_cmd(vty); } +DEFPY_ATTR(no_ip_pim_packets, + no_ip_pim_packets_cmd, + "no ip pim packets [(1-255)]", + NO_STR + IP_STR + PIM_STR + "packets to process at one time per fd\n" + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_pim_packet_cmd(vty); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} DEFPY (ip_igmp_group_watermark, ip_igmp_group_watermark_cmd, @@ -3217,64 +3845,131 @@ DEFPY (no_ip_igmp_group_watermark, return CMD_SUCCESS; } -DEFUN (ip_pim_v6_secondary, - ip_pim_v6_secondary_cmd, - "ip pim send-v6-secondary", - IP_STR - "pim multicast routing\n" +DEFPY (pim_v6_secondary, + pim_v6_secondary_cmd, + "send-v6-secondary", "Send v6 secondary addresses\n") { - const char *vrfname; char send_v6_secondary_xpath[XPATH_MAXLEN]; + snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath), + "./send-v6-secondary"); + + nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY, + "true"); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(ip_pim_v6_secondary, + ip_pim_v6_secondary_cmd, + "ip pim send-v6-secondary", + IP_STR + PIM_STR + "Send v6 secondary addresses\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char send_v6_secondary_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(send_v6_secondary_xpath, "/send-v6-secondary", - sizeof(send_v6_secondary_xpath)); - + "./send-v6-secondary"); nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY, "true"); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFUN (no_ip_pim_v6_secondary, - no_ip_pim_v6_secondary_cmd, - "no ip pim send-v6-secondary", +DEFPY (no_pim_v6_secondary, + no_pim_v6_secondary_cmd, + "no send-v6-secondary", NO_STR - IP_STR - "pim multicast routing\n" "Send v6 secondary addresses\n") { - const char *vrfname; char send_v6_secondary_xpath[XPATH_MAXLEN]; + snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath), + "./send-v6-secondary"); + + nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY, + "false"); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(no_ip_pim_v6_secondary, + no_ip_pim_v6_secondary_cmd, + "no ip pim send-v6-secondary", + NO_STR + IP_STR + PIM_STR + "Send v6 secondary addresses\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char send_v6_secondary_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } snprintf(send_v6_secondary_xpath, sizeof(send_v6_secondary_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(send_v6_secondary_xpath, "/send-v6-secondary", - sizeof(send_v6_secondary_xpath)); - + "./send-v6-secondary"); nb_cli_enqueue_change(vty, send_v6_secondary_xpath, NB_OP_MODIFY, "false"); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFPY (ip_pim_rp, - ip_pim_rp_cmd, - "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp", - IP_STR - "pim multicast routing\n" +DEFPY (pim_rp, + pim_rp_cmd, + "rp A.B.C.D$rp [A.B.C.D/M]$gp", "Rendezvous Point\n" "ip address of RP\n" "Group Address range to cover\n") @@ -3283,12 +3978,52 @@ DEFPY (ip_pim_rp, return pim_process_rp_cmd(vty, rp_str, group_str); } +DEFPY_ATTR(ip_pim_rp, + ip_pim_rp_cmd, + "ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp", + IP_STR + PIM_STR + "Rendezvous Point\n" + "ip address of RP\n" + "Group Address range to cover\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4"; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -DEFPY (ip_pim_rp_prefix_list, - ip_pim_rp_prefix_list_cmd, - "ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", - IP_STR - "pim multicast routing\n" + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_rp_cmd(vty, rp_str, group_str); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim_rp_prefix_list, + pim_rp_prefix_list_cmd, + "rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", "Rendezvous Point\n" "ip address of RP\n" "group prefix-list filter\n" @@ -3296,13 +4031,53 @@ DEFPY (ip_pim_rp_prefix_list, { return pim_process_rp_plist_cmd(vty, rp_str, plist); } +DEFPY_ATTR(ip_pim_rp_prefix_list, + ip_pim_rp_prefix_list_cmd, + "ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", + IP_STR + PIM_STR + "Rendezvous Point\n" + "ip address of RP\n" + "group prefix-list filter\n" + "Name of a prefix-list\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_rp_plist_cmd(vty, rp_str, plist); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} -DEFPY (no_ip_pim_rp, - no_ip_pim_rp_cmd, - "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp", +DEFPY (no_pim_rp, + no_pim_rp_cmd, + "no rp A.B.C.D$rp [A.B.C.D/M]$gp", NO_STR - IP_STR - "pim multicast routing\n" "Rendezvous Point\n" "ip address of RP\n" "Group Address range to cover\n") @@ -3311,13 +4086,54 @@ DEFPY (no_ip_pim_rp, return pim_process_no_rp_cmd(vty, rp_str, group_str); } +DEFPY_ATTR(no_ip_pim_rp, + no_ip_pim_rp_cmd, + "no ip pim rp A.B.C.D$rp [A.B.C.D/M]$gp", + NO_STR + IP_STR + PIM_STR + "Rendezvous Point\n" + "ip address of RP\n" + "Group Address range to cover\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + const char *group_str = (gp_str) ? gp_str : "224.0.0.0/4"; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_rp_cmd(vty, rp_str, group_str); -DEFPY (no_ip_pim_rp_prefix_list, - no_ip_pim_rp_prefix_list_cmd, - "no ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (no_pim_rp_prefix_list, + no_pim_rp_prefix_list_cmd, + "no rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", NO_STR - IP_STR - "pim multicast routing\n" "Rendezvous Point\n" "ip address of RP\n" "group prefix-list filter\n" @@ -3325,104 +4141,264 @@ DEFPY (no_ip_pim_rp_prefix_list, { return pim_process_no_rp_plist_cmd(vty, rp_str, plist); } +DEFPY_ATTR(no_ip_pim_rp_prefix_list, + no_ip_pim_rp_prefix_list_cmd, + "no ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist", + NO_STR + IP_STR + PIM_STR + "Rendezvous Point\n" + "ip address of RP\n" + "group prefix-list filter\n" + "Name of a prefix-list\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -DEFUN (ip_pim_ssm_prefix_list, - ip_pim_ssm_prefix_list_cmd, - "ip pim ssm prefix-list PREFIXLIST4_NAME", - IP_STR - "pim multicast routing\n" + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + ret = pim_process_no_rp_plist_cmd(vty, rp_str, plist); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY (pim_ssm_prefix_list, + pim_ssm_prefix_list_cmd, + "ssm prefix-list PREFIXLIST4_NAME$plist", "Source Specific Multicast\n" "group range prefix-list filter\n" "Name of a prefix-list\n") { - const char *vrfname; char ssm_plist_xpath[XPATH_MAXLEN]; + snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list"); + + nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, plist); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(ip_pim_ssm_prefix_list, + ip_pim_ssm_prefix_list_cmd, + "ip pim ssm prefix-list PREFIXLIST4_NAME$plist", + IP_STR + PIM_STR + "Source Specific Multicast\n" + "group range prefix-list filter\n" + "Name of a prefix-list\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char ssm_plist_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } - snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath)); + snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list"); + nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, plist); + ret = nb_cli_apply_changes(vty, NULL); - nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_MODIFY, argv[4]->arg); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } - return nb_cli_apply_changes(vty, NULL); + return ret; } -DEFUN (no_ip_pim_ssm_prefix_list, - no_ip_pim_ssm_prefix_list_cmd, - "no ip pim ssm prefix-list", +DEFPY (no_pim_ssm_prefix_list, + no_pim_ssm_prefix_list_cmd, + "no ssm prefix-list", NO_STR - IP_STR - "pim multicast routing\n" "Source Specific Multicast\n" "group range prefix-list filter\n") { - const char *vrfname; char ssm_plist_xpath[XPATH_MAXLEN]; + snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list"); + + nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(no_ip_pim_ssm_prefix_list, + no_ip_pim_ssm_prefix_list_cmd, + "no ip pim ssm prefix-list", + NO_STR + IP_STR + PIM_STR + "Source Specific Multicast\n" + "group range prefix-list filter\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char ssm_plist_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } - snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath)); - + snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "./ssm-prefix-list"); nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFUN (no_ip_pim_ssm_prefix_list_name, - no_ip_pim_ssm_prefix_list_name_cmd, - "no ip pim ssm prefix-list PREFIXLIST4_NAME", +DEFPY (no_pim_ssm_prefix_list_name, + no_pim_ssm_prefix_list_name_cmd, + "no ssm prefix-list PREFIXLIST4_NAME$plist", NO_STR - IP_STR - "pim multicast routing\n" "Source Specific Multicast\n" "group range prefix-list filter\n" "Name of a prefix-list\n") { - const char *vrfname; const struct lyd_node *ssm_plist_dnode; char ssm_plist_xpath[XPATH_MAXLEN]; const char *ssm_plist_name; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - - snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ssm_plist_xpath, "/ssm-prefix-list", sizeof(ssm_plist_xpath)); + snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "%s/ssm-prefix-list", + VTY_CURR_XPATH); ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode, ssm_plist_xpath); if (!ssm_plist_dnode) { - vty_out(vty, - "%% pim ssm prefix-list %s doesn't exist\n", - argv[5]->arg); + vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", plist); return CMD_WARNING_CONFIG_FAILED; } ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, "."); - if (ssm_plist_name && !strcmp(ssm_plist_name, argv[5]->arg)) { - nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, - NULL); - + if (ssm_plist_name && !strcmp(ssm_plist_name, plist)) { + nb_cli_enqueue_change(vty, ssm_plist_xpath, NB_OP_DESTROY, NULL); return nb_cli_apply_changes(vty, NULL); } - vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", argv[5]->arg); + vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", plist); return CMD_WARNING_CONFIG_FAILED; } +DEFPY_ATTR(no_ip_pim_ssm_prefix_list_name, + no_ip_pim_ssm_prefix_list_name_cmd, + "no ip pim ssm prefix-list PREFIXLIST4_NAME$plist", + NO_STR + IP_STR + PIM_STR + "Source Specific Multicast\n" + "group range prefix-list filter\n" + "Name of a prefix-list\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + const struct lyd_node *ssm_plist_dnode; + char ssm_plist_xpath[XPATH_MAXLEN]; + const char *ssm_plist_name; + int ret = CMD_WARNING_CONFIG_FAILED; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "%s/ssm-prefix-list", + VTY_CURR_XPATH); + ssm_plist_dnode = yang_dnode_get(vty->candidate_config->dnode, + ssm_plist_xpath); + if (ssm_plist_dnode) { + ssm_plist_name = yang_dnode_get_string(ssm_plist_dnode, "."); + if (ssm_plist_name && !strcmp(ssm_plist_name, plist)) { + nb_cli_enqueue_change(vty, ssm_plist_xpath, + NB_OP_DESTROY, NULL); + ret = nb_cli_apply_changes(vty, NULL); + } else { + vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", + plist); + } + } else { + vty_out(vty, "%% pim ssm prefix-list %s doesn't exist\n", plist); + } + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} DEFUN (show_ip_pim_ssm_range, show_ip_pim_ssm_range_cmd, @@ -3511,135 +4487,354 @@ DEFPY (show_ip_pim_bsr, return pim_show_bsr_helper(vrf, vty, !!json); } -DEFUN (ip_ssmpingd, - ip_ssmpingd_cmd, - "ip ssmpingd [A.B.C.D]", - IP_STR +DEFPY (pim_ssmpingd, + pim_ssmpingd_cmd, + "ssmpingd [A.B.C.D]$src", CONF_SSMPINGD_STR "Source address\n") { - int idx_ipv4 = 2; - const char *src_str = (argc == 3) ? argv[idx_ipv4]->arg : "0.0.0.0"; + if (src_str) + return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str); + else + return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, "0.0.0.0"); +} +DEFPY_ATTR(ip_pim_ssmpingd, + ip_ssmpingd_cmd, + "ip ssmpingd [A.B.C.D]$src", + IP_STR + CONF_SSMPINGD_STR + "Source address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; - return pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str); + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (src_str) + ret = pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, src_str); + else + ret = pim_process_ssmpingd_cmd(vty, NB_OP_CREATE, "0.0.0.0"); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFUN (no_ip_ssmpingd, - no_ip_ssmpingd_cmd, - "no ip ssmpingd [A.B.C.D]", +DEFPY (no_pim_ssmpingd, + no_pim_ssmpingd_cmd, + "no ssmpingd [A.B.C.D]$src", NO_STR - IP_STR CONF_SSMPINGD_STR "Source address\n") { - int idx_ipv4 = 3; - const char *src_str = (argc == 4) ? argv[idx_ipv4]->arg : "0.0.0.0"; + if (src_str) + return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str); + else + return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, "0.0.0.0"); +} +DEFPY_ATTR(no_ip_pim_ssmpingd, + no_ip_ssmpingd_cmd, + "no ip ssmpingd [A.B.C.D]$src", + NO_STR + IP_STR + CONF_SSMPINGD_STR + "Source address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + if (src_str) + ret = pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str); + else + ret = pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, "0.0.0.0"); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } - return pim_process_ssmpingd_cmd(vty, NB_OP_DESTROY, src_str); + return ret; } -DEFUN (ip_pim_ecmp, - ip_pim_ecmp_cmd, - "ip pim ecmp", - IP_STR - "pim multicast routing\n" +DEFPY (pim_ecmp, + pim_ecmp_cmd, + "ecmp", "Enable PIM ECMP \n") { - const char *vrfname; char ecmp_xpath[XPATH_MAXLEN]; + snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp"); + nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(ip_pim_ecmp, + ip_pim_ecmp_cmd, + "ip pim ecmp", + IP_STR + PIM_STR + "Enable PIM ECMP \n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char ecmp_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } - snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath)); - + snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp"); nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true"); - return nb_cli_apply_changes(vty, NULL); + ret = nb_cli_apply_changes(vty, NULL); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFUN (no_ip_pim_ecmp, - no_ip_pim_ecmp_cmd, - "no ip pim ecmp", +DEFPY (no_pim_ecmp, + no_pim_ecmp_cmd, + "no ecmp", NO_STR - IP_STR - "pim multicast routing\n" "Disable PIM ECMP \n") { - const char *vrfname; char ecmp_xpath[XPATH_MAXLEN]; + snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp"); + nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(no_ip_pim_ecmp, + no_ip_pim_ecmp_cmd, + "no ip pim ecmp", + NO_STR + IP_STR + PIM_STR + "Disable PIM ECMP \n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char ecmp_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } - snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath)); - + snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp"); nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "false"); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFUN (ip_pim_ecmp_rebalance, - ip_pim_ecmp_rebalance_cmd, - "ip pim ecmp rebalance", - IP_STR - "pim multicast routing\n" +DEFPY (pim_ecmp_rebalance, + pim_ecmp_rebalance_cmd, + "ecmp rebalance", "Enable PIM ECMP \n" "Enable PIM ECMP Rebalance\n") { - const char *vrfname; char ecmp_xpath[XPATH_MAXLEN]; char ecmp_rebalance_xpath[XPATH_MAXLEN]; + snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp"); + snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath), + "./ecmp-rebalance"); + + nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true"); + nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(ip_pim_ecmp_rebalance, + ip_pim_ecmp_rebalance_cmd, + "ip pim ecmp rebalance", + IP_STR + PIM_STR + "Enable PIM ECMP \n" + "Enable PIM ECMP Rebalance\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char ecmp_xpath[XPATH_MAXLEN]; + char ecmp_rebalance_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } - snprintf(ecmp_xpath, sizeof(ecmp_xpath), FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ecmp_xpath, "/ecmp", sizeof(ecmp_xpath)); + snprintf(ecmp_xpath, sizeof(ecmp_xpath), "./ecmp"); snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance", - sizeof(ecmp_rebalance_xpath)); - + "./ecmp-rebalance"); nb_cli_enqueue_change(vty, ecmp_xpath, NB_OP_MODIFY, "true"); nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "true"); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFUN (no_ip_pim_ecmp_rebalance, - no_ip_pim_ecmp_rebalance_cmd, - "no ip pim ecmp rebalance", +DEFPY (no_pim_ecmp_rebalance, + no_pim_ecmp_rebalance_cmd, + "no ecmp rebalance", NO_STR - IP_STR - "pim multicast routing\n" "Disable PIM ECMP \n" "Disable PIM ECMP Rebalance\n") { - const char *vrfname; char ecmp_rebalance_xpath[XPATH_MAXLEN]; + snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath), + "./ecmp-rebalance"); + + nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(no_ip_pim_ecmp_rebalance, + no_ip_pim_ecmp_rebalance_cmd, + "no ip pim ecmp rebalance", + NO_STR + IP_STR + PIM_STR + "Disable PIM ECMP \n" + "Disable PIM ECMP Rebalance\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char ecmp_rebalance_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } snprintf(ecmp_rebalance_xpath, sizeof(ecmp_rebalance_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - strlcat(ecmp_rebalance_xpath, "/ecmp-rebalance", - sizeof(ecmp_rebalance_xpath)); - + "./ecmp-rebalance"); nb_cli_enqueue_change(vty, ecmp_rebalance_xpath, NB_OP_MODIFY, "false"); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } DEFUN (interface_ip_igmp, @@ -4648,15 +5843,24 @@ DEFPY (debug_pim_zebra, return CMD_SUCCESS; } -DEFUN(debug_pim_mlag, debug_pim_mlag_cmd, "debug pim mlag", - DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR) +DEFUN(debug_pim_mlag, + debug_pim_mlag_cmd, + "debug pim mlag", + DEBUG_STR + DEBUG_PIM_STR + DEBUG_PIM_MLAG_STR) { PIM_DO_DEBUG_MLAG; return CMD_SUCCESS; } -DEFUN(no_debug_pim_mlag, no_debug_pim_mlag_cmd, "no debug pim mlag", - NO_STR DEBUG_STR DEBUG_PIM_STR DEBUG_PIM_MLAG_STR) +DEFUN(no_debug_pim_mlag, + no_debug_pim_mlag_cmd, + "no debug pim mlag", + NO_STR + DEBUG_STR + DEBUG_PIM_STR + DEBUG_PIM_MLAG_STR) { PIM_DONT_DEBUG_MLAG; return CMD_SUCCESS; @@ -5016,145 +6220,333 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd, "Desired min transmit interval\n") #endif /* !HAVE_BFDD */ -DEFPY(ip_msdp_peer, ip_msdp_peer_cmd, - "ip msdp peer A.B.C.D$peer source A.B.C.D$source", - IP_STR +DEFPY(pim_msdp_peer, pim_msdp_peer_cmd, + "msdp peer A.B.C.D$peer source A.B.C.D$source", CFG_MSDP_STR "Configure MSDP peer\n" "Peer IP address\n" "Source address for TCP connection\n" "Local IP address\n") { - const char *vrfname; - char temp_xpath[XPATH_MAXLEN]; char msdp_peer_source_xpath[XPATH_MAXLEN]; + snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath), + "./msdp-peer[peer-ip='%s']/source-ip", peer_str); + nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY, + source_str); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(ip_pim_msdp_peer, + ip_msdp_peer_cmd, + "ip msdp peer A.B.C.D$peer source A.B.C.D$source", + IP_STR + CFG_MSDP_STR + "Configure MSDP peer\n" + "Peer IP address\n" + "Source address for TCP connection\n" + "Local IP address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char msdp_peer_source_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } snprintf(msdp_peer_source_xpath, sizeof(msdp_peer_source_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - "frr-routing:ipv4"); - snprintf(temp_xpath, sizeof(temp_xpath), - "/msdp-peer[peer-ip='%s']/source-ip", peer_str); - strlcat(msdp_peer_source_xpath, temp_xpath, - sizeof(msdp_peer_source_xpath)); - + "./msdp-peer[peer-ip='%s']/source-ip", peer_str); nb_cli_enqueue_change(vty, msdp_peer_source_xpath, NB_OP_MODIFY, source_str); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, - FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv4"); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFPY(ip_msdp_timers, ip_msdp_timers_cmd, - "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]", - IP_STR +DEFPY(pim_msdp_timers, pim_msdp_timers_cmd, + "msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]", CFG_MSDP_STR "MSDP timers configuration\n" "Keep alive period (in seconds)\n" "Hold time period (in seconds)\n" "Connection retry period (in seconds)\n") { + nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_MODIFY, + holdtime_str); + nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_MODIFY, + keepalive_str); + if (connretry_str) + nb_cli_enqueue_change(vty, "./msdp/connection-retry", + NB_OP_MODIFY, connretry_str); + else + nb_cli_enqueue_change(vty, "./msdp/connection-retry", + NB_OP_DESTROY, NULL); + + nb_cli_apply_changes(vty, NULL); + return CMD_SUCCESS; +} +DEFPY_ATTR(ip_pim_msdp_timers, + ip_msdp_timers_cmd, + "ip msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]", + IP_STR + CFG_MSDP_STR + "MSDP timers configuration\n" + "Keep alive period (in seconds)\n" + "Hold time period (in seconds)\n" + "Connection retry period (in seconds)\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } - nb_cli_enqueue_change(vty, "./hold-time", NB_OP_MODIFY, holdtime_str); - nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_MODIFY, keepalive_str); + nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_MODIFY, + holdtime_str); + nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_MODIFY, + keepalive_str); if (connretry_str) - nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_MODIFY, - connretry_str); + nb_cli_enqueue_change(vty, "./msdp/connection-retry", + NB_OP_MODIFY, connretry_str); else - nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, - NULL); + nb_cli_enqueue_change(vty, "./msdp/connection-retry", + NB_OP_DESTROY, NULL); + ret = nb_cli_apply_changes(vty, NULL); - nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim", - vrfname, "frr-routing:ipv4"); - return CMD_SUCCESS; + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFPY(no_ip_msdp_timers, no_ip_msdp_timers_cmd, - "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]", +DEFPY(no_pim_msdp_timers, no_pim_msdp_timers_cmd, + "no msdp timers [(1-65535) (1-65535) [(1-65535)]]", NO_STR - IP_STR CFG_MSDP_STR "MSDP timers configuration\n" IGNORED_IN_NO_STR IGNORED_IN_NO_STR IGNORED_IN_NO_STR) { + nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msdp/connection-retry", NB_OP_DESTROY, + NULL); + nb_cli_apply_changes(vty, NULL); + return CMD_SUCCESS; +} +DEFPY_ATTR(no_ip_pim_msdp_timers, + no_ip_msdp_timers_cmd, + "no ip msdp timers [(1-65535) (1-65535) [(1-65535)]]", + NO_STR + IP_STR + CFG_MSDP_STR + "MSDP timers configuration\n" + IGNORED_IN_NO_STR + IGNORED_IN_NO_STR + IGNORED_IN_NO_STR, + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + int ret; const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } - nb_cli_enqueue_change(vty, "./hold-time", NB_OP_DESTROY, NULL); - nb_cli_enqueue_change(vty, "./keep-alive", NB_OP_DESTROY, NULL); - nb_cli_enqueue_change(vty, "./connection-retry", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msdp/hold-time", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msdp/keep-alive", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./msdp/connection-retry", NB_OP_DESTROY, + NULL); + ret = nb_cli_apply_changes(vty, NULL); - nb_cli_apply_changes(vty, FRR_PIM_MSDP_XPATH, "frr-pim:pimd", "pim", - vrfname, "frr-routing:ipv4"); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } - return CMD_SUCCESS; + return ret; } -DEFUN (no_ip_msdp_peer, - no_ip_msdp_peer_cmd, - "no ip msdp peer A.B.C.D", +DEFPY (no_pim_msdp_peer, + no_pim_msdp_peer_cmd, + "no msdp peer A.B.C.D", NO_STR - IP_STR CFG_MSDP_STR "Delete MSDP peer\n" "peer ip address\n") { - const char *vrfname; char msdp_peer_xpath[XPATH_MAXLEN]; - char temp_xpath[XPATH_MAXLEN]; + + snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath), + "./msdp-peer[peer-ip='%s']", peer_str); + nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(no_ip_pim_msdp_peer, + no_ip_msdp_peer_cmd, + "no ip msdp peer A.B.C.D", + NO_STR + IP_STR + CFG_MSDP_STR + "Delete MSDP peer\n" + "peer ip address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char msdp_peer_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } snprintf(msdp_peer_xpath, sizeof(msdp_peer_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4"); - snprintf(temp_xpath, sizeof(temp_xpath), - "/msdp-peer[peer-ip='%s']", - argv[4]->arg); - - strlcat(msdp_peer_xpath, temp_xpath, sizeof(msdp_peer_xpath)); - + "./msdp-peer[peer-ip='%s']", peer_str); nb_cli_enqueue_change(vty, msdp_peer_xpath, NB_OP_DESTROY, NULL); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFPY(ip_msdp_mesh_group_member, - ip_msdp_mesh_group_member_cmd, - "ip msdp mesh-group WORD$gname member A.B.C.D$maddr", - IP_STR +DEFPY(pim_msdp_mesh_group_member, + pim_msdp_mesh_group_member_cmd, + "msdp mesh-group WORD$gname member A.B.C.D$maddr", CFG_MSDP_STR "Configure MSDP mesh-group\n" "Mesh group name\n" "Mesh group member\n" "Peer IP address\n") { - const char *vrfname; char xpath_value[XPATH_MAXLEN]; + /* Create mesh group. */ + snprintf(xpath_value, sizeof(xpath_value), + "./msdp-mesh-groups[name='%s']", gname); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); + + /* Create mesh group member. */ + strlcat(xpath_value, "/members[address='", sizeof(xpath_value)); + strlcat(xpath_value, maddr_str, sizeof(xpath_value)); + strlcat(xpath_value, "']", sizeof(xpath_value)); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(ip_pim_msdp_mesh_group_member, + ip_msdp_mesh_group_member_cmd, + "ip msdp mesh-group WORD$gname member A.B.C.D$maddr", + IP_STR + CFG_MSDP_STR + "Configure MSDP mesh-group\n" + "Mesh group name\n" + "Mesh group member\n" + "Peer IP address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char xpath_value[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } /* Create mesh group. */ snprintf(xpath_value, sizeof(xpath_value), - FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']", - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname); + "./msdp-mesh-groups[name='%s']", gname); nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); /* Create mesh group member. */ @@ -5162,33 +6554,32 @@ DEFPY(ip_msdp_mesh_group_member, strlcat(xpath_value, maddr_str, sizeof(xpath_value)); strlcat(xpath_value, "']", sizeof(xpath_value)); nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFPY(no_ip_msdp_mesh_group_member, - no_ip_msdp_mesh_group_member_cmd, - "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr", +DEFPY(no_pim_msdp_mesh_group_member, + no_pim_msdp_mesh_group_member_cmd, + "no msdp mesh-group WORD$gname member A.B.C.D$maddr", NO_STR - IP_STR CFG_MSDP_STR "Delete MSDP mesh-group member\n" "Mesh group name\n" "Mesh group member\n" "Peer IP address\n") { - const char *vrfname; char xpath_value[XPATH_MAXLEN]; char xpath_member_value[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - /* Get mesh group base XPath. */ snprintf(xpath_value, sizeof(xpath_value), - FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']", - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname); + "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname); if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) { vty_out(vty, "%% mesh-group does not exist\n"); @@ -5217,59 +6608,221 @@ DEFPY(no_ip_msdp_mesh_group_member, return nb_cli_apply_changes(vty, NULL); } +DEFPY_ATTR(no_ip_pim_msdp_mesh_group_member, + no_ip_msdp_mesh_group_member_cmd, + "no ip msdp mesh-group WORD$gname member A.B.C.D$maddr", + NO_STR + IP_STR + CFG_MSDP_STR + "Delete MSDP mesh-group member\n" + "Mesh group name\n" + "Mesh group member\n" + "Peer IP address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char xpath_value[XPATH_MAXLEN]; + char xpath_member_value[XPATH_MAXLEN]; + int ret = CMD_WARNING_CONFIG_FAILED; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; -DEFPY(ip_msdp_mesh_group_source, - ip_msdp_mesh_group_source_cmd, - "ip msdp mesh-group WORD$gname source A.B.C.D$saddr", - IP_STR + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Get mesh group base XPath. */ + snprintf(xpath_value, sizeof(xpath_value), + "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname); + + if (yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) { + /* Remove mesh group member. */ + strlcpy(xpath_member_value, xpath_value, + sizeof(xpath_member_value)); + strlcat(xpath_member_value, "/members[address='", + sizeof(xpath_member_value)); + strlcat(xpath_member_value, maddr_str, + sizeof(xpath_member_value)); + strlcat(xpath_member_value, "']", sizeof(xpath_member_value)); + if (yang_dnode_exists(vty->candidate_config->dnode, + xpath_member_value)) { + nb_cli_enqueue_change(vty, xpath_member_value, + NB_OP_DESTROY, NULL); + + /* + * If this is the last member, then we must remove the group altogether + * to not break legacy CLI behaviour. + */ + pim_cli_legacy_mesh_group_behavior(vty, gname); + ret = nb_cli_apply_changes(vty, NULL); + } else { + vty_out(vty, "%% mesh-group member does not exist\n"); + } + } else { + vty_out(vty, "%% mesh-group does not exist\n"); + } + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY(pim_msdp_mesh_group_source, + pim_msdp_mesh_group_source_cmd, + "msdp mesh-group WORD$gname source A.B.C.D$saddr", CFG_MSDP_STR "Configure MSDP mesh-group\n" "Mesh group name\n" "Mesh group local address\n" "Source IP address for the TCP connection\n") { - const char *vrfname; char xpath_value[XPATH_MAXLEN]; + /* Create mesh group. */ + snprintf(xpath_value, sizeof(xpath_value), + "./msdp-mesh-groups[name='%s']", gname); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); + + /* Create mesh group source. */ + strlcat(xpath_value, "/source", sizeof(xpath_value)); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(ip_pim_msdp_mesh_group_source, + ip_msdp_mesh_group_source_cmd, + "ip msdp mesh-group WORD$gname source A.B.C.D$saddr", + IP_STR + CFG_MSDP_STR + "Configure MSDP mesh-group\n" + "Mesh group name\n" + "Mesh group local address\n" + "Source IP address for the TCP connection\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char xpath_value[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } /* Create mesh group. */ snprintf(xpath_value, sizeof(xpath_value), - FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']", - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname); + "./msdp-mesh-groups[name='%s']", gname); nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); - /* Create mesh group source. */ strlcat(xpath_value, "/source", sizeof(xpath_value)); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, saddr_str); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFPY(no_ip_msdp_mesh_group_source, - no_ip_msdp_mesh_group_source_cmd, - "no ip msdp mesh-group WORD$gname source [A.B.C.D]", +DEFPY(no_pim_msdp_mesh_group_source, + no_pim_msdp_mesh_group_source_cmd, + "no msdp mesh-group WORD$gname source [A.B.C.D]", NO_STR - IP_STR CFG_MSDP_STR "Delete MSDP mesh-group source\n" "Mesh group name\n" "Mesh group source\n" "Mesh group local address\n") { - const char *vrfname; char xpath_value[XPATH_MAXLEN]; + /* Get mesh group base XPath. */ + snprintf(xpath_value, sizeof(xpath_value), + "./msdp-mesh-groups[name='%s']", gname); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); + + /* Create mesh group source. */ + strlcat(xpath_value, "/source", sizeof(xpath_value)); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL); + + /* + * If this is the last member, then we must remove the group altogether + * to not break legacy CLI behaviour. + */ + pim_cli_legacy_mesh_group_behavior(vty, gname); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(no_ip_pim_msdp_mesh_group_source, + no_ip_msdp_mesh_group_source_cmd, + "no ip msdp mesh-group WORD$gname source [A.B.C.D]", + NO_STR + IP_STR + CFG_MSDP_STR + "Delete MSDP mesh-group source\n" + "Mesh group name\n" + "Mesh group source\n" + "Mesh group local address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char xpath_value[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); return CMD_WARNING_CONFIG_FAILED; + } /* Get mesh group base XPath. */ snprintf(xpath_value, sizeof(xpath_value), - FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']", - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname); + "./msdp-mesh-groups[name='%s']", gname); nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); /* Create mesh group source. */ @@ -5281,36 +6834,83 @@ DEFPY(no_ip_msdp_mesh_group_source, * to not break legacy CLI behaviour. */ pim_cli_legacy_mesh_group_behavior(vty, gname); + ret = nb_cli_apply_changes(vty, NULL); - return nb_cli_apply_changes(vty, NULL); + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; } -DEFPY(no_ip_msdp_mesh_group, - no_ip_msdp_mesh_group_cmd, - "no ip msdp mesh-group WORD$gname", +DEFPY(no_pim_msdp_mesh_group, + no_pim_msdp_mesh_group_cmd, + "no msdp mesh-group WORD$gname", NO_STR - IP_STR CFG_MSDP_STR "Delete MSDP mesh-group\n" "Mesh group name\n") { - const char *vrfname; char xpath_value[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - /* Get mesh group base XPath. */ snprintf(xpath_value, sizeof(xpath_value), - FRR_PIM_VRF_XPATH "/msdp-mesh-groups[name='%s']", - "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4", gname); + "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname); if (!yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) return CMD_SUCCESS; nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL); return nb_cli_apply_changes(vty, NULL); } +DEFPY_ATTR(no_ip_pim_msdp_mesh_group, + no_ip_msdp_mesh_group_cmd, + "no ip msdp mesh-group WORD$gname", + NO_STR + IP_STR + CFG_MSDP_STR + "Delete MSDP mesh-group\n" + "Mesh group name\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char xpath_value[XPATH_MAXLEN]; + int ret = CMD_SUCCESS; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + /* Get mesh group base XPath. */ + snprintf(xpath_value, sizeof(xpath_value), + "%s/msdp-mesh-groups[name='%s']", VTY_CURR_XPATH, gname); + if (yang_dnode_exists(vty->candidate_config->dnode, xpath_value)) { + nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, NULL); + ret = nb_cli_apply_changes(vty, NULL); + } + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg, struct json_object *json) @@ -5329,7 +6929,8 @@ static void ip_msdp_show_mesh_group(struct vty *vty, struct pim_msdp_mg *mg, if (json) { /* currently there is only one mesh group but we should still * make - * it a dict with mg-name as key */ + * it a dict with mg-name as key + */ json_mg_row = json_object_new_object(); json_object_string_add(json_mg_row, "name", mg->mesh_group_name); @@ -6311,119 +7912,224 @@ DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work, return CMD_SUCCESS; } -DEFUN_HIDDEN (no_ip_pim_mlag, - no_ip_pim_mlag_cmd, - "no ip pim mlag", +DEFPY_HIDDEN (no_pim_mlag, + no_pim_mlag_cmd, + "no mlag", NO_STR - IP_STR - PIM_STR "MLAG\n") { char mlag_xpath[XPATH_MAXLEN]; - snprintf(mlag_xpath, sizeof(mlag_xpath), FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", "default", "frr-routing:ipv4"); - strlcat(mlag_xpath, "/mlag", sizeof(mlag_xpath)); + snprintf(mlag_xpath, sizeof(mlag_xpath), "./mlag"); + nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} +DEFPY_ATTR(no_ip_pim_mlag, + no_ip_pim_mlag_cmd, + "no ip pim mlag", + NO_STR + IP_STR + PIM_STR + "MLAG\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) +{ + char mlag_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; + + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } + snprintf(mlag_xpath, sizeof(mlag_xpath), "./mlag"); nb_cli_enqueue_change(vty, mlag_xpath, NB_OP_DESTROY, NULL); + ret = nb_cli_apply_changes(vty, NULL); + + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } + + return ret; +} + +DEFPY_HIDDEN (pim_mlag, + pim_mlag_cmd, + "mlag INTERFACE$iface role [primary|secondary]$role state [up|down]$state addr A.B.C.D$addr", + "MLAG\n" + "peerlink sub interface\n" + "MLAG role\n" + "MLAG role primary\n" + "MLAG role secondary\n" + "peer session state\n" + "peer session state up\n" + "peer session state down\n" + "configure PIP\n" + "unique ip address\n") +{ + char mlag_peerlink_rif_xpath[XPATH_MAXLEN]; + char mlag_my_role_xpath[XPATH_MAXLEN]; + char mlag_peer_state_xpath[XPATH_MAXLEN]; + char mlag_reg_address_xpath[XPATH_MAXLEN]; + + snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath), + "./mlag/peerlink-rif"); + nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY, iface); + + snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath), + "./mlag/my-role"); + if (!strcmp(role, "primary")) { + nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY, + "MLAG_ROLE_PRIMARY"); + } else if (!strcmp(role, "secondary")) { + nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY, + "MLAG_ROLE_SECONDARY"); + } else { + vty_out(vty, "unknown MLAG role %s\n", role); + return CMD_WARNING; + } + + snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath), + "./mlag/peer-state"); + if (!strcmp(state, "up")) { + nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY, + "true"); + } else if (strcmp(state, "down")) { + nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY, + "false"); + } else { + vty_out(vty, "unknown MLAG state %s\n", state); + return CMD_WARNING; + } + snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath), + "./mlag/reg-address"); + nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY, + addr_str); return nb_cli_apply_changes(vty, NULL); } - -DEFUN_HIDDEN (ip_pim_mlag, - ip_pim_mlag_cmd, - "ip pim mlag INTERFACE role [primary|secondary] state [up|down] addr A.B.C.D", - IP_STR - PIM_STR - "MLAG\n" - "peerlink sub interface\n" - "MLAG role\n" - "MLAG role primary\n" - "MLAG role secondary\n" - "peer session state\n" - "peer session state up\n" - "peer session state down\n" - "configure PIP\n" - "unique ip address\n") +DEFPY_ATTR(ip_pim_mlag, + ip_pim_mlag_cmd, + "ip pim mlag INTERFACE$iface role [primary|secondary]$role state [up|down]$state addr A.B.C.D$addr", + IP_STR + PIM_STR + "MLAG\n" + "peerlink sub interface\n" + "MLAG role\n" + "MLAG role primary\n" + "MLAG role secondary\n" + "peer session state\n" + "peer session state up\n" + "peer session state down\n" + "configure PIP\n" + "unique ip address\n", + CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) { - int idx; char mlag_peerlink_rif_xpath[XPATH_MAXLEN]; char mlag_my_role_xpath[XPATH_MAXLEN]; char mlag_peer_state_xpath[XPATH_MAXLEN]; char mlag_reg_address_xpath[XPATH_MAXLEN]; + int ret; + const char *vrfname; + char xpath[XPATH_MAXLEN]; + int orig_node = -1; - snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", "default", "frr-routing:ipv4"); - strlcat(mlag_peerlink_rif_xpath, "/mlag/peerlink-rif", - sizeof(mlag_peerlink_rif_xpath)); + vrfname = pim_cli_get_vrf_name(vty); + if (vrfname) { + snprintf(xpath, sizeof(xpath), FRR_PIM_VRF_XPATH, + "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + if (nb_cli_apply_changes_clear_pending(vty, NULL) == + CMD_SUCCESS) { + orig_node = vty->node; + VTY_PUSH_XPATH(PIM_NODE, xpath); + } else { + return CMD_WARNING_CONFIG_FAILED; + } + } else { + vty_out(vty, "%% Failed to determine vrf name\n"); + return CMD_WARNING_CONFIG_FAILED; + } - idx = 3; - nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY, - argv[idx]->arg); + snprintf(mlag_peerlink_rif_xpath, sizeof(mlag_peerlink_rif_xpath), + "./mlag/peerlink-rif"); + nb_cli_enqueue_change(vty, mlag_peerlink_rif_xpath, NB_OP_MODIFY, iface); snprintf(mlag_my_role_xpath, sizeof(mlag_my_role_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", "default", "frr-routing:ipv4"); - strlcat(mlag_my_role_xpath, "/mlag/my-role", - sizeof(mlag_my_role_xpath)); - - idx += 2; - if (!strcmp(argv[idx]->arg, "primary")) { + "./mlag/my-role"); + if (!strcmp(role, "primary")) { nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY, "MLAG_ROLE_PRIMARY"); - - } else if (!strcmp(argv[idx]->arg, "secondary")) { + } else if (!strcmp(role, "secondary")) { nb_cli_enqueue_change(vty, mlag_my_role_xpath, NB_OP_MODIFY, "MLAG_ROLE_SECONDARY"); - } else { - vty_out(vty, "unknown MLAG role %s\n", argv[idx]->arg); - return CMD_WARNING; + vty_out(vty, "unknown MLAG role %s\n", role); + ret = CMD_WARNING; + goto done; } snprintf(mlag_peer_state_xpath, sizeof(mlag_peer_state_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", "default", "frr-routing:ipv4"); - strlcat(mlag_peer_state_xpath, "/mlag/peer-state", - sizeof(mlag_peer_state_xpath)); - - idx += 2; - if (!strcmp(argv[idx]->arg, "up")) { + "./mlag/peer-state"); + if (!strcmp(state, "up")) { nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY, "true"); - - } else if (strcmp(argv[idx]->arg, "down")) { + } else if (strcmp(state, "down")) { nb_cli_enqueue_change(vty, mlag_peer_state_xpath, NB_OP_MODIFY, "false"); - } else { - vty_out(vty, "unknown MLAG state %s\n", argv[idx]->arg); - return CMD_WARNING; + vty_out(vty, "unknown MLAG state %s\n", state); + ret = CMD_WARNING; + goto done; } snprintf(mlag_reg_address_xpath, sizeof(mlag_reg_address_xpath), - FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", "default", "frr-routing:ipv4"); - strlcat(mlag_reg_address_xpath, "/mlag/reg-address", - sizeof(mlag_reg_address_xpath)); - - idx += 2; + "./mlag/reg-address"); nb_cli_enqueue_change(vty, mlag_reg_address_xpath, NB_OP_MODIFY, - argv[idx]->arg); + addr_str); - return nb_cli_apply_changes(vty, NULL); -} + ret = nb_cli_apply_changes(vty, NULL); -void pim_cmd_init(void) -{ - if_cmd_init(pim_interface_config_write); +done: + if (orig_node != -1) { + vty->node = orig_node; + vty->xpath_index--; + } - install_node(&debug_node); + return ret; +} - install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd); +struct cmd_node pim_node = { + .name = "pim", + .node = PIM_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pim)# ", + .config_write = pim_router_config_write, +}; +/* This function installs all of the deprecated PIM configuration commands that live in the global config and/or VRF nodes + * This configuration has been moved to the new 'router pim' config node instead like all the other routing protocols. + * No new commands should be added here. + */ +static void pim_install_deprecated(void) +{ install_element(CONFIG_NODE, &ip_pim_rp_cmd); install_element(VRF_NODE, &ip_pim_rp_cmd); install_element(CONFIG_NODE, &no_ip_pim_rp_cmd); @@ -6449,8 +8155,8 @@ void pim_cmd_init(void) install_element(CONFIG_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd); install_element(VRF_NODE, &no_ip_pim_spt_switchover_infinity_plist_cmd); - install_element(CONFIG_NODE, &pim_register_accept_list_cmd); - install_element(VRF_NODE, &pim_register_accept_list_cmd); + install_element(CONFIG_NODE, &ip_pim_register_accept_list_cmd); + install_element(VRF_NODE, &ip_pim_register_accept_list_cmd); install_element(CONFIG_NODE, &ip_pim_joinprune_time_cmd); install_element(CONFIG_NODE, &no_ip_pim_joinprune_time_cmd); install_element(CONFIG_NODE, &ip_pim_keep_alive_cmd); @@ -6467,14 +8173,6 @@ void pim_cmd_init(void) install_element(VRF_NODE, &ip_pim_v6_secondary_cmd); install_element(CONFIG_NODE, &no_ip_pim_v6_secondary_cmd); install_element(VRF_NODE, &no_ip_pim_v6_secondary_cmd); - install_element(CONFIG_NODE, &ip_ssmpingd_cmd); - install_element(VRF_NODE, &ip_ssmpingd_cmd); - install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd); - install_element(VRF_NODE, &no_ip_ssmpingd_cmd); - install_element(CONFIG_NODE, &ip_msdp_peer_cmd); - install_element(VRF_NODE, &ip_msdp_peer_cmd); - install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd); - install_element(VRF_NODE, &no_ip_msdp_peer_cmd); install_element(CONFIG_NODE, &ip_pim_ecmp_cmd); install_element(VRF_NODE, &ip_pim_ecmp_cmd); install_element(CONFIG_NODE, &no_ip_pim_ecmp_cmd); @@ -6485,10 +8183,87 @@ 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, &ip_igmp_group_watermark_cmd); - install_element(VRF_NODE, &ip_igmp_group_watermark_cmd); - install_element(CONFIG_NODE, &no_ip_igmp_group_watermark_cmd); - install_element(VRF_NODE, &no_ip_igmp_group_watermark_cmd); + + install_element(CONFIG_NODE, &ip_ssmpingd_cmd); + install_element(VRF_NODE, &ip_ssmpingd_cmd); + install_element(CONFIG_NODE, &no_ip_ssmpingd_cmd); + install_element(VRF_NODE, &no_ip_ssmpingd_cmd); + + install_element(CONFIG_NODE, &ip_msdp_peer_cmd); + install_element(VRF_NODE, &ip_msdp_peer_cmd); + install_element(CONFIG_NODE, &no_ip_msdp_peer_cmd); + install_element(VRF_NODE, &no_ip_msdp_peer_cmd); + install_element(CONFIG_NODE, &ip_msdp_timers_cmd); + install_element(VRF_NODE, &ip_msdp_timers_cmd); + install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd); + install_element(VRF_NODE, &no_ip_msdp_timers_cmd); + install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd); + install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd); + install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd); + install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd); + install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd); + install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd); + install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd); + install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd); + install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd); + install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd); +} + +void pim_cmd_init(void) +{ + if_cmd_init(pim_interface_config_write); + + install_node(&debug_node); + + install_element(CONFIG_NODE, &router_pim_cmd); + install_element(CONFIG_NODE, &no_router_pim_cmd); + + install_node(&pim_node); + install_default(PIM_NODE); + + install_element(PIM_NODE, &pim_rp_cmd); + install_element(PIM_NODE, &no_pim_rp_cmd); + install_element(PIM_NODE, &pim_rp_prefix_list_cmd); + install_element(PIM_NODE, &no_pim_rp_prefix_list_cmd); + install_element(PIM_NODE, &no_pim_ssm_prefix_list_cmd); + install_element(PIM_NODE, &no_pim_ssm_prefix_list_name_cmd); + install_element(PIM_NODE, &pim_ssm_prefix_list_cmd); + install_element(PIM_NODE, &pim_register_suppress_cmd); + install_element(PIM_NODE, &no_pim_register_suppress_cmd); + install_element(PIM_NODE, &pim_spt_switchover_infinity_cmd); + install_element(PIM_NODE, &pim_spt_switchover_infinity_plist_cmd); + install_element(PIM_NODE, &no_pim_spt_switchover_infinity_cmd); + install_element(PIM_NODE, &no_pim_spt_switchover_infinity_plist_cmd); + install_element(PIM_NODE, &pim_register_accept_list_cmd); + install_element(PIM_NODE, &pim_joinprune_time_cmd); + install_element(PIM_NODE, &no_pim_joinprune_time_cmd); + install_element(PIM_NODE, &pim_keep_alive_cmd); + install_element(PIM_NODE, &pim_rp_keep_alive_cmd); + install_element(PIM_NODE, &no_pim_keep_alive_cmd); + install_element(PIM_NODE, &no_pim_rp_keep_alive_cmd); + install_element(PIM_NODE, &pim_packets_cmd); + install_element(PIM_NODE, &no_pim_packets_cmd); + install_element(PIM_NODE, &pim_v6_secondary_cmd); + install_element(PIM_NODE, &no_pim_v6_secondary_cmd); + install_element(PIM_NODE, &pim_ecmp_cmd); + install_element(PIM_NODE, &no_pim_ecmp_cmd); + install_element(PIM_NODE, &pim_ecmp_rebalance_cmd); + install_element(PIM_NODE, &no_pim_ecmp_rebalance_cmd); + install_element(PIM_NODE, &pim_mlag_cmd); + install_element(PIM_NODE, &no_pim_mlag_cmd); + + install_element(PIM_NODE, &pim_ssmpingd_cmd); + install_element(PIM_NODE, &no_pim_ssmpingd_cmd); + + install_element(PIM_NODE, &pim_msdp_peer_cmd); + install_element(PIM_NODE, &no_pim_msdp_peer_cmd); + install_element(PIM_NODE, &pim_msdp_timers_cmd); + install_element(PIM_NODE, &no_pim_msdp_timers_cmd); + install_element(PIM_NODE, &pim_msdp_mesh_group_member_cmd); + install_element(PIM_NODE, &no_pim_msdp_mesh_group_member_cmd); + install_element(PIM_NODE, &pim_msdp_mesh_group_source_cmd); + install_element(PIM_NODE, &no_pim_msdp_mesh_group_source_cmd); + install_element(PIM_NODE, &no_pim_msdp_mesh_group_cmd); install_element(INTERFACE_NODE, &interface_ip_igmp_cmd); install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd); @@ -6534,6 +8309,22 @@ void pim_cmd_init(void) install_element(INTERFACE_NODE, &interface_ip_mroute_cmd); install_element(INTERFACE_NODE, &interface_no_ip_mroute_cmd); + install_element(INTERFACE_NODE, &interface_pim_use_source_cmd); + install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd); + /* Install BSM command */ + install_element(INTERFACE_NODE, &ip_pim_bsm_cmd); + install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd); + install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd); + install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd); + /* Install BFD command */ + install_element(INTERFACE_NODE, &ip_pim_bfd_cmd); + install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd); + install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd); + install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd); +#if HAVE_BFDD == 0 + install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd); +#endif /* !HAVE_BFDD */ + install_element(VIEW_NODE, &show_ip_igmp_interface_cmd); install_element(VIEW_NODE, &show_ip_igmp_interface_vrf_all_cmd); install_element(VIEW_NODE, &show_ip_igmp_join_cmd); @@ -6590,6 +8381,20 @@ void pim_cmd_init(void) install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd); install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd); install_element(VIEW_NODE, &show_ip_pim_statistics_cmd); + install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd); + install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd); + install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd); + install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd); + install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd); + install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd); + install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd); + install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd); + install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd); + install_element(VIEW_NODE, &show_ip_pim_group_type_cmd); + install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd); + install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd); + + install_element(ENABLE_NODE, &pim_test_sg_keepalive_cmd); install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd); install_element(ENABLE_NODE, &clear_ip_interfaces_cmd); @@ -6604,134 +8409,98 @@ void pim_cmd_init(void) install_element(ENABLE_NODE, &show_debugging_pim_cmd); install_element(ENABLE_NODE, &debug_igmp_cmd); - install_element(ENABLE_NODE, &no_debug_igmp_cmd); - install_element(ENABLE_NODE, &debug_igmp_events_cmd); - install_element(ENABLE_NODE, &no_debug_igmp_events_cmd); - install_element(ENABLE_NODE, &debug_igmp_packets_cmd); - install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd); - install_element(ENABLE_NODE, &debug_igmp_trace_cmd); - install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd); - install_element(ENABLE_NODE, &debug_igmp_trace_detail_cmd); - install_element(ENABLE_NODE, &no_debug_igmp_trace_detail_cmd); - install_element(ENABLE_NODE, &debug_mroute_cmd); - install_element(ENABLE_NODE, &debug_mroute_detail_cmd); - install_element(ENABLE_NODE, &no_debug_mroute_cmd); - install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd); - install_element(ENABLE_NODE, &debug_pim_static_cmd); - install_element(ENABLE_NODE, &no_debug_pim_static_cmd); - install_element(ENABLE_NODE, &debug_pim_cmd); - install_element(ENABLE_NODE, &debug_pim_nht_cmd); - install_element(ENABLE_NODE, &debug_pim_nht_det_cmd); - install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd); - install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd); - install_element(ENABLE_NODE, &debug_pim_events_cmd); - install_element(ENABLE_NODE, &debug_pim_packets_cmd); - install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd); - install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd); - install_element(ENABLE_NODE, &debug_pim_trace_cmd); - install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd); - install_element(ENABLE_NODE, &debug_ssmpingd_cmd); - install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd); - install_element(ENABLE_NODE, &debug_pim_zebra_cmd); - install_element(ENABLE_NODE, &debug_pim_mlag_cmd); - install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd); - install_element(ENABLE_NODE, &debug_pim_vxlan_cmd); - install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd); - install_element(ENABLE_NODE, &debug_msdp_cmd); - install_element(ENABLE_NODE, &no_debug_msdp_cmd); - install_element(ENABLE_NODE, &debug_msdp_events_cmd); - install_element(ENABLE_NODE, &no_debug_msdp_events_cmd); - install_element(ENABLE_NODE, &debug_msdp_packets_cmd); - install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd); - install_element(ENABLE_NODE, &debug_mtrace_cmd); - install_element(ENABLE_NODE, &no_debug_mtrace_cmd); - install_element(ENABLE_NODE, &debug_bsm_cmd); - install_element(ENABLE_NODE, &no_debug_bsm_cmd); - install_element(CONFIG_NODE, &debug_igmp_cmd); + install_element(ENABLE_NODE, &no_debug_igmp_cmd); install_element(CONFIG_NODE, &no_debug_igmp_cmd); + install_element(ENABLE_NODE, &debug_igmp_events_cmd); install_element(CONFIG_NODE, &debug_igmp_events_cmd); + install_element(ENABLE_NODE, &no_debug_igmp_events_cmd); install_element(CONFIG_NODE, &no_debug_igmp_events_cmd); + install_element(ENABLE_NODE, &debug_igmp_packets_cmd); install_element(CONFIG_NODE, &debug_igmp_packets_cmd); + install_element(ENABLE_NODE, &no_debug_igmp_packets_cmd); install_element(CONFIG_NODE, &no_debug_igmp_packets_cmd); + install_element(ENABLE_NODE, &debug_igmp_trace_cmd); install_element(CONFIG_NODE, &debug_igmp_trace_cmd); + install_element(ENABLE_NODE, &no_debug_igmp_trace_cmd); install_element(CONFIG_NODE, &no_debug_igmp_trace_cmd); + install_element(ENABLE_NODE, &debug_igmp_trace_detail_cmd); install_element(CONFIG_NODE, &debug_igmp_trace_detail_cmd); + install_element(ENABLE_NODE, &no_debug_igmp_trace_detail_cmd); install_element(CONFIG_NODE, &no_debug_igmp_trace_detail_cmd); + install_element(ENABLE_NODE, &debug_mroute_cmd); install_element(CONFIG_NODE, &debug_mroute_cmd); + install_element(ENABLE_NODE, &debug_mroute_detail_cmd); install_element(CONFIG_NODE, &debug_mroute_detail_cmd); + install_element(ENABLE_NODE, &no_debug_mroute_cmd); install_element(CONFIG_NODE, &no_debug_mroute_cmd); + install_element(ENABLE_NODE, &no_debug_mroute_detail_cmd); install_element(CONFIG_NODE, &no_debug_mroute_detail_cmd); + install_element(ENABLE_NODE, &debug_pim_static_cmd); install_element(CONFIG_NODE, &debug_pim_static_cmd); + install_element(ENABLE_NODE, &no_debug_pim_static_cmd); install_element(CONFIG_NODE, &no_debug_pim_static_cmd); + install_element(ENABLE_NODE, &debug_pim_cmd); install_element(CONFIG_NODE, &debug_pim_cmd); + install_element(ENABLE_NODE, &debug_pim_nht_cmd); install_element(CONFIG_NODE, &debug_pim_nht_cmd); + install_element(ENABLE_NODE, &debug_pim_nht_det_cmd); install_element(CONFIG_NODE, &debug_pim_nht_det_cmd); + install_element(ENABLE_NODE, &debug_pim_nht_rp_cmd); install_element(CONFIG_NODE, &debug_pim_nht_rp_cmd); + install_element(ENABLE_NODE, &no_debug_pim_nht_rp_cmd); install_element(CONFIG_NODE, &no_debug_pim_nht_rp_cmd); + install_element(ENABLE_NODE, &debug_pim_events_cmd); install_element(CONFIG_NODE, &debug_pim_events_cmd); + install_element(ENABLE_NODE, &debug_pim_packets_cmd); install_element(CONFIG_NODE, &debug_pim_packets_cmd); + install_element(ENABLE_NODE, &debug_pim_packetdump_send_cmd); install_element(CONFIG_NODE, &debug_pim_packetdump_send_cmd); + install_element(ENABLE_NODE, &debug_pim_packetdump_recv_cmd); install_element(CONFIG_NODE, &debug_pim_packetdump_recv_cmd); + install_element(ENABLE_NODE, &debug_pim_trace_cmd); install_element(CONFIG_NODE, &debug_pim_trace_cmd); + install_element(ENABLE_NODE, &debug_pim_trace_detail_cmd); install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd); + install_element(ENABLE_NODE, &debug_ssmpingd_cmd); install_element(CONFIG_NODE, &debug_ssmpingd_cmd); + install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd); install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd); + install_element(ENABLE_NODE, &debug_pim_zebra_cmd); install_element(CONFIG_NODE, &debug_pim_zebra_cmd); + install_element(ENABLE_NODE, &debug_pim_mlag_cmd); install_element(CONFIG_NODE, &debug_pim_mlag_cmd); + install_element(ENABLE_NODE, &no_debug_pim_mlag_cmd); install_element(CONFIG_NODE, &no_debug_pim_mlag_cmd); + install_element(ENABLE_NODE, &debug_pim_vxlan_cmd); install_element(CONFIG_NODE, &debug_pim_vxlan_cmd); + install_element(ENABLE_NODE, &no_debug_pim_vxlan_cmd); install_element(CONFIG_NODE, &no_debug_pim_vxlan_cmd); + install_element(ENABLE_NODE, &debug_msdp_cmd); install_element(CONFIG_NODE, &debug_msdp_cmd); + install_element(ENABLE_NODE, &no_debug_msdp_cmd); install_element(CONFIG_NODE, &no_debug_msdp_cmd); + install_element(ENABLE_NODE, &debug_msdp_events_cmd); install_element(CONFIG_NODE, &debug_msdp_events_cmd); + install_element(ENABLE_NODE, &no_debug_msdp_events_cmd); install_element(CONFIG_NODE, &no_debug_msdp_events_cmd); + install_element(ENABLE_NODE, &debug_msdp_packets_cmd); install_element(CONFIG_NODE, &debug_msdp_packets_cmd); + install_element(ENABLE_NODE, &no_debug_msdp_packets_cmd); install_element(CONFIG_NODE, &no_debug_msdp_packets_cmd); + install_element(ENABLE_NODE, &debug_mtrace_cmd); install_element(CONFIG_NODE, &debug_mtrace_cmd); + install_element(ENABLE_NODE, &no_debug_mtrace_cmd); install_element(CONFIG_NODE, &no_debug_mtrace_cmd); + install_element(ENABLE_NODE, &debug_bsm_cmd); install_element(CONFIG_NODE, &debug_bsm_cmd); + install_element(ENABLE_NODE, &no_debug_bsm_cmd); install_element(CONFIG_NODE, &no_debug_bsm_cmd); - install_element(CONFIG_NODE, &ip_msdp_timers_cmd); - install_element(VRF_NODE, &ip_msdp_timers_cmd); - install_element(CONFIG_NODE, &no_ip_msdp_timers_cmd); - install_element(VRF_NODE, &no_ip_msdp_timers_cmd); - install_element(CONFIG_NODE, &ip_msdp_mesh_group_member_cmd); - install_element(VRF_NODE, &ip_msdp_mesh_group_member_cmd); - install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_member_cmd); - install_element(VRF_NODE, &no_ip_msdp_mesh_group_member_cmd); - install_element(CONFIG_NODE, &ip_msdp_mesh_group_source_cmd); - install_element(VRF_NODE, &ip_msdp_mesh_group_source_cmd); - install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_source_cmd); - install_element(VRF_NODE, &no_ip_msdp_mesh_group_source_cmd); - install_element(CONFIG_NODE, &no_ip_msdp_mesh_group_cmd); - install_element(VRF_NODE, &no_ip_msdp_mesh_group_cmd); - install_element(VIEW_NODE, &show_ip_msdp_peer_detail_cmd); - install_element(VIEW_NODE, &show_ip_msdp_peer_detail_vrf_all_cmd); - install_element(VIEW_NODE, &show_ip_msdp_sa_detail_cmd); - install_element(VIEW_NODE, &show_ip_msdp_sa_detail_vrf_all_cmd); - install_element(VIEW_NODE, &show_ip_msdp_sa_sg_cmd); - install_element(VIEW_NODE, &show_ip_msdp_sa_sg_vrf_all_cmd); - install_element(VIEW_NODE, &show_ip_msdp_mesh_group_cmd); - install_element(VIEW_NODE, &show_ip_msdp_mesh_group_vrf_all_cmd); - install_element(VIEW_NODE, &show_ip_pim_ssm_range_cmd); - install_element(VIEW_NODE, &show_ip_pim_group_type_cmd); - install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_cmd); - install_element(VIEW_NODE, &show_ip_pim_vxlan_sg_work_cmd); - install_element(INTERFACE_NODE, &interface_pim_use_source_cmd); - install_element(INTERFACE_NODE, &interface_no_pim_use_source_cmd); - /* Install BSM command */ - install_element(INTERFACE_NODE, &ip_pim_bsm_cmd); - install_element(INTERFACE_NODE, &no_ip_pim_bsm_cmd); - install_element(INTERFACE_NODE, &ip_pim_ucast_bsm_cmd); - install_element(INTERFACE_NODE, &no_ip_pim_ucast_bsm_cmd); - /* Install BFD command */ - install_element(INTERFACE_NODE, &ip_pim_bfd_cmd); - install_element(INTERFACE_NODE, &ip_pim_bfd_param_cmd); - install_element(INTERFACE_NODE, &no_ip_pim_bfd_profile_cmd); - install_element(INTERFACE_NODE, &no_ip_pim_bfd_cmd); -#if HAVE_BFDD == 0 - install_element(INTERFACE_NODE, &no_ip_pim_bfd_param_cmd); -#endif /* !HAVE_BFDD */ + install_element(CONFIG_NODE, &ip_igmp_group_watermark_cmd); + install_element(VRF_NODE, &ip_igmp_group_watermark_cmd); + install_element(CONFIG_NODE, &no_ip_igmp_group_watermark_cmd); + install_element(VRF_NODE, &no_ip_igmp_group_watermark_cmd); + + pim_install_deprecated(); } diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c index 5e50a09355cf..c6cb28c097b9 100644 --- a/pimd/pim_cmd_common.c +++ b/pimd/pim_cmd_common.c @@ -100,25 +100,13 @@ int pim_process_no_join_prune_cmd(struct vty *vty) int pim_process_spt_switchover_infinity_cmd(struct vty *vty) { - const char *vrfname; char spt_plist_xpath[XPATH_MAXLEN]; char spt_action_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - snprintf(spt_plist_xpath, sizeof(spt_plist_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(spt_plist_xpath, "/spt-switchover/spt-infinity-prefix-list", - sizeof(spt_plist_xpath)); - + "%s/spt-switchover/spt-infinity-prefix-list", VTY_CURR_XPATH); snprintf(spt_action_xpath, sizeof(spt_action_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(spt_action_xpath, "/spt-switchover/spt-action", - sizeof(spt_action_xpath)); + "%s/spt-switchover/spt-action", VTY_CURR_XPATH); if (yang_dnode_exists(vty->candidate_config->dnode, spt_plist_xpath)) nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_DESTROY, @@ -132,55 +120,30 @@ int pim_process_spt_switchover_infinity_cmd(struct vty *vty) int pim_process_spt_switchover_prefixlist_cmd(struct vty *vty, const char *plist) { - const char *vrfname; char spt_plist_xpath[XPATH_MAXLEN]; char spt_action_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - snprintf(spt_plist_xpath, sizeof(spt_plist_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(spt_plist_xpath, "/spt-switchover/spt-infinity-prefix-list", - sizeof(spt_plist_xpath)); - + "./spt-switchover/spt-infinity-prefix-list"); snprintf(spt_action_xpath, sizeof(spt_action_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(spt_action_xpath, "/spt-switchover/spt-action", - sizeof(spt_action_xpath)); + "./spt-switchover/spt-action"); nb_cli_enqueue_change(vty, spt_action_xpath, NB_OP_MODIFY, "PIM_SPT_INFINITY"); - nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_MODIFY, - plist); + nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_MODIFY, plist); return nb_cli_apply_changes(vty, NULL); } int pim_process_no_spt_switchover_cmd(struct vty *vty) { - const char *vrfname; char spt_plist_xpath[XPATH_MAXLEN]; char spt_action_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - snprintf(spt_plist_xpath, sizeof(spt_plist_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(spt_plist_xpath, "/spt-switchover/spt-infinity-prefix-list", - sizeof(spt_plist_xpath)); - + "./spt-switchover/spt-infinity-prefix-list"); snprintf(spt_action_xpath, sizeof(spt_action_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(spt_action_xpath, "/spt-switchover/spt-action", - sizeof(spt_action_xpath)); + "./spt-switchover/spt-action"); nb_cli_enqueue_change(vty, spt_plist_xpath, NB_OP_DESTROY, NULL); nb_cli_enqueue_change(vty, spt_action_xpath, NB_OP_MODIFY, @@ -217,35 +180,20 @@ int pim_process_no_pim_packet_cmd(struct vty *vty) int pim_process_keepalivetimer_cmd(struct vty *vty, const char *kat) { - const char *vrfname; char ka_timer_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - - snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); - strlcat(ka_timer_xpath, "/keep-alive-timer", sizeof(ka_timer_xpath)); + snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), "./keep-alive-timer"); - nb_cli_enqueue_change(vty, ka_timer_xpath, NB_OP_MODIFY, - kat); + nb_cli_enqueue_change(vty, ka_timer_xpath, NB_OP_MODIFY, kat); return nb_cli_apply_changes(vty, NULL); } int pim_process_no_keepalivetimer_cmd(struct vty *vty) { - const char *vrfname; char ka_timer_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - - snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), FRR_PIM_VRF_XPATH, - "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL); - strlcat(ka_timer_xpath, "/keep-alive-timer", sizeof(ka_timer_xpath)); + snprintf(ka_timer_xpath, sizeof(ka_timer_xpath), "./keep-alive-timer"); nb_cli_enqueue_change(vty, ka_timer_xpath, NB_OP_DESTROY, NULL); @@ -254,35 +202,25 @@ int pim_process_no_keepalivetimer_cmd(struct vty *vty) int pim_process_rp_kat_cmd(struct vty *vty, const char *rpkat) { - const char *vrfname; char rp_ka_timer_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - snprintf(rp_ka_timer_xpath, sizeof(rp_ka_timer_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(rp_ka_timer_xpath, "/rp-keep-alive-timer", - sizeof(rp_ka_timer_xpath)); + "./rp-keep-alive-timer"); - nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY, - rpkat); + nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY, rpkat); return nb_cli_apply_changes(vty, NULL); } int pim_process_no_rp_kat_cmd(struct vty *vty) { - const char *vrfname; char rp_ka_timer[6]; char rp_ka_timer_xpath[XPATH_MAXLEN]; uint v; char rs_timer_xpath[XPATH_MAXLEN]; - snprintf(rs_timer_xpath, sizeof(rs_timer_xpath), - FRR_PIM_ROUTER_XPATH, FRR_PIM_AF_XPATH_VAL); + snprintf(rs_timer_xpath, sizeof(rs_timer_xpath), FRR_PIM_ROUTER_XPATH, + FRR_PIM_AF_XPATH_VAL); strlcat(rs_timer_xpath, "/register-suppress-time", sizeof(rs_timer_xpath)); @@ -301,18 +239,10 @@ int pim_process_no_rp_kat_cmd(struct vty *vty) v = UINT16_MAX; snprintf(rp_ka_timer, sizeof(rp_ka_timer), "%u", v); - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - snprintf(rp_ka_timer_xpath, sizeof(rp_ka_timer_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); - strlcat(rp_ka_timer_xpath, "/rp-keep-alive-timer", - sizeof(rp_ka_timer_xpath)); + "./rp-keep-alive-timer"); - nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY, - rp_ka_timer); + nb_cli_enqueue_change(vty, rp_ka_timer_xpath, NB_OP_MODIFY, rp_ka_timer); return nb_cli_apply_changes(vty, NULL); } @@ -531,9 +461,7 @@ int pim_process_no_ip_mroute_cmd(struct vty *vty, const char *interface, int pim_process_rp_cmd(struct vty *vty, const char *rp_str, const char *group_str) { - const char *vrfname; char group_xpath[XPATH_MAXLEN]; - char rp_xpath[XPATH_MAXLEN]; int printed; int result = 0; struct prefix group; @@ -575,14 +503,9 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str, } #endif - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - - snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH, - "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str); printed = snprintf(group_xpath, sizeof(group_xpath), - "%s/group-list[.='%s']", rp_xpath, group_str); + "./" FRR_PIM_STATIC_RP_XPATH "/group-list[.='%s']", + rp_str, group_str); if (printed >= (int)(sizeof(group_xpath))) { vty_out(vty, "Xpath too long (%d > %u)", printed + 1, @@ -601,15 +524,10 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str, char group_xpath[XPATH_MAXLEN]; char rp_xpath[XPATH_MAXLEN]; int printed; - const char *vrfname; const struct lyd_node *group_dnode; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - - snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH, - "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str); + snprintf(rp_xpath, sizeof(rp_xpath), "%s/" FRR_PIM_STATIC_RP_XPATH, + VTY_CURR_XPATH, rp_str); printed = snprintf(group_xpath, sizeof(group_xpath), "%s/group-list[.='%s']", rp_xpath, group_str); @@ -636,16 +554,10 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str, int pim_process_rp_plist_cmd(struct vty *vty, const char *rp_str, const char *prefix_list) { - const char *vrfname; char rp_plist_xpath[XPATH_MAXLEN]; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - snprintf(rp_plist_xpath, sizeof(rp_plist_xpath), - FRR_PIM_STATIC_RP_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL, rp_str); + "./" FRR_PIM_STATIC_RP_XPATH, rp_str); strlcat(rp_plist_xpath, "/prefix-list", sizeof(rp_plist_xpath)); nb_cli_enqueue_change(vty, rp_plist_xpath, NB_OP_MODIFY, prefix_list); @@ -658,19 +570,12 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str, { char rp_xpath[XPATH_MAXLEN]; char plist_xpath[XPATH_MAXLEN]; - const char *vrfname; const struct lyd_node *plist_dnode; const char *plist; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - - snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH, - "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str); - - snprintf(plist_xpath, sizeof(plist_xpath), FRR_PIM_STATIC_RP_XPATH, - "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str); + snprintf(rp_xpath, sizeof(rp_xpath), "%s/" FRR_PIM_STATIC_RP_XPATH, + VTY_CURR_XPATH, rp_str); + snprintf(plist_xpath, sizeof(plist_xpath), "%s", rp_xpath); strlcat(plist_xpath, "/prefix-list", sizeof(plist_xpath)); plist_dnode = yang_dnode_get(vty->candidate_config->dnode, plist_xpath); @@ -679,7 +584,7 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str, return NB_OK; } - plist = yang_dnode_get_string(plist_dnode, "%s", plist_xpath); + plist = yang_dnode_get_string(plist_dnode, NULL); if (strcmp(prefix_list, plist)) { vty_out(vty, "%% Unable to find specified RP\n"); return NB_OK; @@ -3408,21 +3313,11 @@ int gm_process_no_last_member_query_interval_cmd(struct vty *vty) int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation, const char *src_str) { - const char *vrfname; - char ssmpingd_ip_xpath[XPATH_MAXLEN]; char ssmpingd_src_ip_xpath[XPATH_MAXLEN]; int printed; - vrfname = pim_cli_get_vrf_name(vty); - if (vrfname == NULL) - return CMD_WARNING_CONFIG_FAILED; - - snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath), - FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname, - FRR_PIM_AF_XPATH_VAL); printed = snprintf(ssmpingd_src_ip_xpath, sizeof(ssmpingd_src_ip_xpath), - "%s/ssm-pingd-source-ip[.='%s']", ssmpingd_ip_xpath, - src_str); + "./ssm-pingd-source-ip[.='%s']", src_str); if (printed >= (int)sizeof(ssmpingd_src_ip_xpath)) { vty_out(vty, "Xpath too long (%d > %u)", printed + 1, XPATH_MAXLEN); @@ -5705,3 +5600,34 @@ int pim_show_bsm_db_helper(const char *vrf, struct vty *vty, bool uj) return CMD_SUCCESS; } + +int pim_router_config_write(struct vty *vty) +{ + struct vrf *vrf; + struct pim_instance *pim; + int writes = 0; + char framestr[64] = { 0 }; + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + pim = vrf->info; + + if (!pim) + continue; + + snprintfrr(framestr, sizeof(framestr), "router %s", + PIM_AF_ROUTER); + if (vrf->vrf_id != VRF_DEFAULT) { + strlcat(framestr, " vrf ", sizeof(framestr)); + strlcat(framestr, vrf->name, sizeof(framestr)); + } + vty_frame(vty, "%s\n", framestr); + ++writes; + + writes += pim_global_config_write_worker(pim, vty); + + vty_endframe(vty, "exit\n"); + ++writes; + } + + return writes; +} diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h index e30203fad75b..da2e44be585b 100644 --- a/pimd/pim_cmd_common.h +++ b/pimd/pim_cmd_common.h @@ -182,6 +182,8 @@ int pim_show_interface_traffic_helper(const char *vrf, const char *if_name, void clear_pim_interfaces(struct pim_instance *pim); void pim_show_bsr(struct pim_instance *pim, struct vty *vty, bool uj); int pim_show_bsr_helper(const char *vrf, struct vty *vty, bool uj); +int pim_router_config_write(struct vty *vty); + /* * Special Macro to allow us to get the correct pim_instance; */ diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index b3410d15af72..a9eec9a9d25b 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -201,6 +201,7 @@ static int pim_vrf_config_write(struct vty *vty) { struct vrf *vrf; struct pim_instance *pim; + char spaces[10]; RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { pim = vrf->info; @@ -208,10 +209,24 @@ static int pim_vrf_config_write(struct vty *vty) if (!pim) continue; - if (vrf->vrf_id != VRF_DEFAULT) + if (vrf->vrf_id != VRF_DEFAULT) { vty_frame(vty, "vrf %s\n", vrf->name); - - pim_global_config_write_worker(pim, vty); + snprintf(spaces, sizeof(spaces), "%s", " "); + } else { + snprintf(spaces, sizeof(spaces), "%s", ""); + } + + /* Global IGMP/MLD configuration */ + if (pim->gm_watermark_limit != 0) { +#if PIM_IPV == 4 + vty_out(vty, + "%s" PIM_AF_NAME " igmp watermark-warn %u\n", + spaces, pim->gm_watermark_limit); +#else + vty_out(vty, "%s" PIM_AF_NAME " mld watermark-warn %u\n", + spaces, pim->gm_watermark_limit); +#endif + } if (vrf->vrf_id != VRF_DEFAULT) vty_endframe(vty, "exit-vrf\n!\n"); diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 623c14bb0391..04b4d296ddbc 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -1276,8 +1276,7 @@ static void pim_msdp_src_del(struct pim_msdp_mg *mg) } /*********************** MSDP feature APIs *********************************/ -int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty, - const char *spaces) +int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty) { struct pim_msdp_mg *mg; struct listnode *mbrnode; @@ -1292,14 +1291,14 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty, if (mg->src_ip.s_addr != INADDR_ANY) { pim_inet4_dump("", mg->src_ip, src_str, sizeof(src_str)); - vty_out(vty, "%sip msdp mesh-group %s source %s\n", - spaces, mg->mesh_group_name, src_str); + vty_out(vty, " msdp mesh-group %s source %s\n", + mg->mesh_group_name, src_str); ++count; } for (ALL_LIST_ELEMENTS_RO(mg->mbr_list, mbrnode, mbr)) { - vty_out(vty, "%sip msdp mesh-group %s member %pI4\n", - spaces, mg->mesh_group_name, &mbr->mbr_ip); + vty_out(vty, " msdp mesh-group %s member %pI4\n", + mg->mesh_group_name, &mbr->mbr_ip); ++count; } } @@ -1307,8 +1306,7 @@ int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty, return count; } -bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim, - const char *spaces) +bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim) { struct pim_msdp_peer *mp; struct listnode *node; @@ -1319,8 +1317,8 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim, if (mp->flags & PIM_MSDP_PEERF_IN_GROUP) continue; - vty_out(vty, "%sip msdp peer %pI4 source %pI4\n", spaces, - &mp->peer, &mp->local); + vty_out(vty, " msdp peer %pI4 source %pI4\n", &mp->peer, + &mp->local); written = true; } diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index ddc015f9b62b..80ca003dc595 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -228,10 +228,8 @@ void pim_msdp_peer_pkt_rxed(struct pim_msdp_peer *mp); void pim_msdp_peer_stop_tcp_conn(struct pim_msdp_peer *mp, bool chg_state); void pim_msdp_peer_reset_tcp_conn(struct pim_msdp_peer *mp, const char *rc_str); void pim_msdp_write(struct event *thread); -int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty, - const char *spaces); -bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim, - const char *spaces); +int pim_msdp_config_write(struct pim_instance *pim, struct vty *vty); +bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim); void pim_msdp_peer_pkt_txed(struct pim_msdp_peer *mp); void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, pim_sgaddr *sg, struct in_addr rp); @@ -339,14 +337,13 @@ static inline void pim_msdp_sa_local_del(struct pim_instance *pim, } static inline int pim_msdp_config_write(struct pim_instance *pim, - struct vty *vty, const char *spaces) + struct vty *vty) { return 0; } static inline bool pim_msdp_peer_config_write(struct vty *vty, - struct pim_instance *pim, - const char *spaces) + struct pim_instance *pim) { return false; } diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h index 0321d076f0da..2d854d73de5e 100644 --- a/pimd/pim_nb.h +++ b/pimd/pim_nb.h @@ -207,9 +207,6 @@ int routing_control_plane_protocols_name_validate( "./frr-pim:pim/address-family[address-family='%s']/" \ "mroute[source-addr='%s'][group-addr='%s']" #define FRR_PIM_STATIC_RP_XPATH \ - "/frr-routing:routing/control-plane-protocols/" \ - "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \ - "frr-pim:pim/address-family[address-family='%s']/" \ "frr-pim-rp:rp/static-rp/rp-list[rp-address='%s']" #define FRR_GMP_INTERFACE_XPATH \ "./frr-gmp:gmp/address-family[address-family='%s']" @@ -218,6 +215,5 @@ int routing_control_plane_protocols_name_validate( #define FRR_GMP_JOIN_XPATH \ "./frr-gmp:gmp/address-family[address-family='%s']/" \ "static-group[group-addr='%s'][source-addr='%s']" -#define FRR_PIM_MSDP_XPATH FRR_PIM_VRF_XPATH "/msdp" #endif /* _FRR_PIM_NB_H_ */ diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 49be9c0a7339..0f8940bb16d7 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -1129,8 +1129,7 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up, return 1; } -int pim_rp_config_write(struct pim_instance *pim, struct vty *vty, - const char *spaces) +int pim_rp_config_write(struct pim_instance *pim, struct vty *vty) { struct listnode *node; struct rp_info *rp_info; @@ -1146,13 +1145,11 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty, rp_addr = rp_info->rp.rpf_addr; if (rp_info->plist) - vty_out(vty, - "%s" PIM_AF_NAME - " pim rp %pPA prefix-list %s\n", - spaces, &rp_addr, rp_info->plist); + vty_out(vty, " rp %pPA prefix-list %s\n", &rp_addr, + rp_info->plist); else - vty_out(vty, "%s" PIM_AF_NAME " pim rp %pPA %pFX\n", - spaces, &rp_addr, &rp_info->group); + vty_out(vty, " rp %pPA %pFX\n", &rp_addr, + &rp_info->group); count++; } diff --git a/pimd/pim_rp.h b/pimd/pim_rp.h index 9416a9a8a87e..32c6306740d6 100644 --- a/pimd/pim_rp.h +++ b/pimd/pim_rp.h @@ -46,8 +46,7 @@ int pim_rp_change(struct pim_instance *pim, pim_addr new_rp_addr, void pim_rp_prefix_list_update(struct pim_instance *pim, struct prefix_list *plist); -int pim_rp_config_write(struct pim_instance *pim, struct vty *vty, - const char *spaces); +int pim_rp_config_write(struct pim_instance *pim, struct vty *vty); void pim_rp_setup(struct pim_instance *pim); diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 0f6547ee2e9a..1910a684957e 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -172,89 +172,66 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) { int writes = 0; struct pim_ssm *ssm = pim->ssm_info; - char spaces[10]; - if (pim->vrf->vrf_id == VRF_DEFAULT) - snprintf(spaces, sizeof(spaces), "%s", ""); - else - snprintf(spaces, sizeof(spaces), "%s", " "); - - writes += pim_msdp_peer_config_write(vty, pim, spaces); - writes += pim_msdp_config_write(pim, vty, spaces); + writes += pim_msdp_peer_config_write(vty, pim); + writes += pim_msdp_config_write(pim, vty); if (!pim->send_v6_secondary) { - vty_out(vty, "%sno ip pim send-v6-secondary\n", spaces); + vty_out(vty, " no send-v6-secondary\n"); ++writes; } - writes += pim_rp_config_write(pim, vty, spaces); + writes += pim_rp_config_write(pim, vty); if (pim->vrf->vrf_id == VRF_DEFAULT) { if (router->register_suppress_time != PIM_REGISTER_SUPPRESSION_TIME_DEFAULT) { - vty_out(vty, "%s" PIM_AF_NAME " pim register-suppress-time %d\n", - spaces, router->register_suppress_time); + vty_out(vty, " register-suppress-time %d\n", + router->register_suppress_time); ++writes; } if (router->t_periodic != PIM_DEFAULT_T_PERIODIC) { - vty_out(vty, "%s" PIM_AF_NAME " pim join-prune-interval %d\n", - spaces, router->t_periodic); + vty_out(vty, " join-prune-interval %d\n", + router->t_periodic); ++writes; } if (router->packet_process != PIM_DEFAULT_PACKET_PROCESS) { - vty_out(vty, "%s" PIM_AF_NAME " pim packets %d\n", spaces, - router->packet_process); + vty_out(vty, " packets %d\n", router->packet_process); ++writes; } } if (pim->keep_alive_time != PIM_KEEPALIVE_PERIOD) { - vty_out(vty, "%s" PIM_AF_NAME " pim keep-alive-timer %d\n", - spaces, pim->keep_alive_time); + vty_out(vty, " keep-alive-timer %d\n", pim->keep_alive_time); ++writes; } if (pim->rp_keep_alive_time != (unsigned int)PIM_RP_KEEPALIVE_PERIOD) { - vty_out(vty, "%s" PIM_AF_NAME " pim rp keep-alive-timer %d\n", - spaces, pim->rp_keep_alive_time); + vty_out(vty, " rp keep-alive-timer %d\n", + pim->rp_keep_alive_time); ++writes; } if (ssm->plist_name) { - vty_out(vty, "%sip pim ssm prefix-list %s\n", spaces, - ssm->plist_name); + vty_out(vty, " ssm prefix-list %s\n", ssm->plist_name); ++writes; } if (pim->register_plist) { - vty_out(vty, "%sip pim register-accept-list %s\n", spaces, - pim->register_plist); + vty_out(vty, " register-accept-list %s\n", pim->register_plist); ++writes; } if (pim->spt.switchover == PIM_SPT_INFINITY) { if (pim->spt.plist) vty_out(vty, - "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond prefix-list %s\n", - spaces, pim->spt.plist); + " spt-switchover infinity-and-beyond prefix-list %s\n", + pim->spt.plist); else - vty_out(vty, - "%s" PIM_AF_NAME " pim spt-switchover infinity-and-beyond\n", - spaces); + vty_out(vty, " spt-switchover infinity-and-beyond\n"); ++writes; } if (pim->ecmp_rebalance_enable) { - vty_out(vty, "%sip pim ecmp rebalance\n", spaces); + vty_out(vty, " ecmp rebalance\n"); ++writes; } else if (pim->ecmp_enable) { - vty_out(vty, "%sip pim ecmp\n", spaces); - ++writes; - } - - if (pim->gm_watermark_limit != 0) { -#if PIM_IPV == 4 - vty_out(vty, "%s" PIM_AF_NAME " igmp watermark-warn %u\n", - spaces, pim->gm_watermark_limit); -#else - vty_out(vty, "%s" PIM_AF_NAME " mld watermark-warn %u\n", - spaces, pim->gm_watermark_limit); -#endif + vty_out(vty, " ecmp\n"); ++writes; } @@ -263,8 +240,7 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) struct ssmpingd_sock *ss; ++writes; for (ALL_LIST_ELEMENTS_RO(pim->ssmpingd_list, node, ss)) { - vty_out(vty, "%s" PIM_AF_NAME " ssmpingd %pPA\n", - spaces, &ss->source_addr); + vty_out(vty, " ssmpingd %pPA\n", &ss->source_addr); ++writes; } } @@ -272,8 +248,8 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty) if (pim->msdp.hold_time != PIM_MSDP_PEER_HOLD_TIME || pim->msdp.keep_alive != PIM_MSDP_PEER_KA_TIME || pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) { - vty_out(vty, "%sip msdp timers %u %u", spaces, - pim->msdp.hold_time, pim->msdp.keep_alive); + vty_out(vty, " msdp timers %u %u", pim->msdp.hold_time, + pim->msdp.keep_alive); if (pim->msdp.connection_retry != PIM_MSDP_PEER_CONNECT_RETRY_TIME) vty_out(vty, " %u", pim->msdp.connection_retry); diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 573320667c33..1f6dde83c148 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -1677,6 +1677,24 @@ static struct cmd_node bfd_profile_node = { }; #endif /* HAVE_BFDD */ +#ifdef HAVE_PIMD +static struct cmd_node pim_node = { + .name = "pim", + .node = PIM_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pim)# ", +}; +#endif /* HAVE_PIMD */ + +#ifdef HAVE_PIM6D +static struct cmd_node pim6_node = { + .name = "pim6", + .node = PIM6_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pim6)# ", +}; +#endif /* HAVE_PIM6D */ + /* Defined in lib/vty.c */ extern struct cmd_node vty_node; @@ -2413,6 +2431,30 @@ DEFUNSH(VTYSH_BFDD, bfd_profile_enter, bfd_profile_enter_cmd, } #endif /* HAVE_BFDD */ +#ifdef HAVE_PIMD +DEFUNSH(VTYSH_PIMD, router_pim, router_pim_cmd, + "router pim [vrf NAME]", + ROUTER_STR + "Start PIM configuration\n" + VRF_CMD_HELP_STR) +{ + vty->node = PIM_NODE; + return CMD_SUCCESS; +} +#endif /* HAVE_PIMD */ + +#ifdef HAVE_PIM6D +DEFUNSH(VTYSH_PIM6D, router_pim6, router_pim6_cmd, + "router pim6 [vrf NAME]", + ROUTER_STR + "Start PIMv6 configuration\n" + VRF_CMD_HELP_STR) +{ + vty->node = PIM6_NODE; + return CMD_SUCCESS; +} +#endif /* HAVE_PIM6D*/ + DEFUNSH(VTYSH_ALL, vtysh_line_vty, vtysh_line_vty_cmd, "line vty", "Configure a terminal line\n" "Virtual terminal\n") @@ -2826,6 +2868,34 @@ DEFUNSH(VTYSH_PATHD, vtysh_quit_pathd, vtysh_quit_pathd_cmd, "quit", } #endif /* HAVE_PATHD */ +#ifdef HAVE_PIMD +DEFUNSH(VTYSH_PIMD, vtysh_exit_pimd, vtysh_exit_pimd_cmd, "exit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit(vty); +} + +DEFUNSH(VTYSH_PIMD, vtysh_quit_pimd, vtysh_quit_pimd_cmd, "quit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit_pimd(self, vty, argc, argv); +} +#endif /* HAVE_PIMD */ + +#ifdef HAVE_PIM6D +DEFUNSH(VTYSH_PIM6D, vtysh_exit_pim6d, vtysh_exit_pim6d_cmd, "exit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit(vty); +} + +DEFUNSH(VTYSH_PIM6D, vtysh_quit_pim6d, vtysh_quit_pim6d_cmd, "quit", + "Exit current mode and down to previous mode\n") +{ + return vtysh_exit_pim6d(self, vty, argc, argv); +} +#endif /* HAVE_PIM6D */ + DEFUNSH(VTYSH_ALL, vtysh_exit_line_vty, vtysh_exit_line_vty_cmd, "exit", "Exit current mode and down to previous mode\n") { @@ -5293,6 +5363,25 @@ void vtysh_init_vty(void) install_element(INTERFACE_NODE, &vtysh_exit_interface_cmd); install_element(INTERFACE_NODE, &vtysh_quit_interface_cmd); + /* pimd */ +#ifdef HAVE_PIMD + install_node(&pim_node); + install_element(CONFIG_NODE, &router_pim_cmd); + install_element(PIM_NODE, &vtysh_exit_pimd_cmd); + install_element(PIM_NODE, &vtysh_quit_pimd_cmd); + install_element(PIM_NODE, &vtysh_end_all_cmd); +#endif /* HAVE_PIMD */ + + /* pim6d */ +#ifdef HAVE_PIM6D + install_node(&pim6_node); + install_element(CONFIG_NODE, &router_pim6_cmd); + install_element(PIM6_NODE, &vtysh_exit_pim6d_cmd); + install_element(PIM6_NODE, &vtysh_quit_pim6d_cmd); + install_element(PIM6_NODE, &vtysh_end_all_cmd); +#endif /* HAVE_PIM6D */ + + /* zebra and all, cont. */ install_node(&link_params_node); install_element(INTERFACE_NODE, &vtysh_link_params_cmd); install_element(LINK_PARAMS_NODE, &no_link_params_enable_cmd); diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index c207e4d42759..8f7cd84818c6 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -497,6 +497,11 @@ void vtysh_config_parse_line(void *arg, const char *line) config = config_get(BFD_NODE, line); else if (strncmp(line, "rpki", strlen("rpki")) == 0) config = config_get(RPKI_NODE, line); + else if (strncmp(line, "router pim", strlen("router pim")) == 0) + config = config_get(PIM_NODE, line); + else if (strncmp(line, "router pim6", strlen("router pim6")) == + 0) + config = config_get(PIM6_NODE, line); else { if (strncmp(line, "log", strlen("log")) == 0 || strncmp(line, "hostname", strlen("hostname")) == 0 || From 98d47f43fbba4e376c8351c724e8c625799805f7 Mon Sep 17 00:00:00 2001 From: Nathan Bahr Date: Mon, 17 Jun 2024 12:58:30 -0500 Subject: [PATCH 408/472] tools: Fix frr-reload to support legacy pim configuration from file Fix load from file in frr-reload to detect and convert legacy pim configuration so that the tool can continue to be used with legacy configurations. Signed-off-by: Nathan Bahr --- tools/frr-reload.py | 64 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 461f0e8c61bf..47e3637550e1 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -94,7 +94,7 @@ def is_config_available(self): output = self("configure") - if "VTY configuration is locked by other VTY" in output: + if "configuration is locked" in output.lower(): log.error("vtysh 'configure' returned\n%s\n" % (output)) return False @@ -261,6 +261,8 @@ def get_normalized_interface_vrf(line): "router ospf6": {}, "router eigrp ": {}, "router babel": {}, + "router pim": {}, + "router pim6": {}, "mpls ldp": {"address-family ": {"interface ": {}}}, "l2vpn ": {"member pseudowire ": {}}, "key chain ": {"key ": {}}, @@ -306,12 +308,62 @@ def load_from_file(self, filename): file_output = self.vtysh.mark_file(filename) + vrf_context = None + pim_vrfs = [] + for line in file_output.split("\n"): line = line.strip() # Compress duplicate whitespaces line = " ".join(line.split()) + # Detect when we are within a vrf context for converting legacy PIM commands + if vrf_context: + re_vrf = re.match("^(exit-vrf|exit|end)$", line) + if re_vrf: + vrf_context = None + else: + re_vrf = re.match("^vrf ([a-z]+)$", line) + if re_vrf: + vrf_context = re_vrf.group(1) + + # Detect legacy pim commands that need to move under the router pim context + re_pim = re.match("^ip(v6)? pim ((ecmp|join|keep|mlag|packets|register|rp|send|spt|ssm).*)$", line) + if re_pim and re_pim.group(2): + router_pim = "router pim" + if re_pim.group(1): + router_pim += "6" + if vrf_context: + router_pim += " vrf " + vrf_context + + if vrf_context: + pim_vrfs.append(router_pim) + pim_vrfs.append(re_pim.group(2)) + pim_vrfs.append("exit") + line="# PIM VRF LINE MOVED TO ROUTER PIM" + else: + self.lines.append(router_pim) + self.lines.append(re_pim.group(2)) + line = "exit" + + re_pim = re.match("^ip(v6)? ((ssmpingd|msdp).*)$", line) + if re_pim and re_pim.group(2): + router_pim = "router pim" + if re_pim.group(1): + router_pim += "6" + if vrf_context: + router_pim += " vrf " + vrf_context + + if vrf_context: + pim_vrfs.append(router_pim) + pim_vrfs.append(re_pim.group(2)) + pim_vrfs.append("exit") + line="# PIM VRF LINE MOVED TO ROUTER PIM" + else: + self.lines.append(router_pim) + self.lines.append(re_pim.group(2)) + line = "exit" + # Remove 'vrf ' from 'interface vrf ' if line.startswith("interface ") and "vrf" in line: line = get_normalized_interface_vrf(line) @@ -348,6 +400,8 @@ def load_from_file(self, filename): self.lines.append(line) + self.lines.append(pim_vrfs) + self.load_contexts() def load_from_show_running(self, daemon): @@ -1683,9 +1737,11 @@ def compare_context_objects(newconf, running): lines_to_del.append((running_ctx_keys, None)) # We cannot do 'no interface' or 'no vrf' in FRR, and so deal with it - elif running_ctx_keys[0].startswith("interface") or running_ctx_keys[ - 0 - ].startswith("vrf"): + elif ( + running_ctx_keys[0].startswith("interface") + or running_ctx_keys[0].startswith("vrf") + or running_ctx_keys[0].startswith("router pim") + ): for line in running_ctx.lines: lines_to_del.append((running_ctx_keys, line)) From b58592d05b7466081555394052367dbec9137572 Mon Sep 17 00:00:00 2001 From: Nathan Bahr Date: Mon, 24 Jun 2024 12:45:42 -0500 Subject: [PATCH 409/472] doc: Update PIM[6] configure docs Document 'router pim[6] [vrf NAME]' configuration. All the commands are basically the same, just dropped the 'ip pim[6]' prefix and document them under the router pim block. Signed-off-by: Nathan Bahr --- doc/user/pim.rst | 73 ++++++++++++++++++++++++++-------------------- doc/user/pimv6.rst | 43 +++++++++++++++------------ 2 files changed, 67 insertions(+), 49 deletions(-) diff --git a/doc/user/pim.rst b/doc/user/pim.rst index b19bb9d1b3ad..4c62f7528b18 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -55,16 +55,22 @@ Certain signals have special meanings to *pimd*. *pimd* invocation options. Common options that can be specified (:ref:`common-invocation-options`). -.. clicmd:: ip pim rp A.B.C.D A.B.C.D/M +PIM Routers +----------- + +.. clicmd:: router pim [vrf NAME] + Configure global PIM protocol + +.. clicmd:: rp A.B.C.D A.B.C.D/M In order to use pim, it is necessary to configure a RP for join messages to be sent to. Currently the only methodology to do this is via static rp commands. All routers in the pim network must agree on these values. The first ip address is the RP's address and the second value is the matching prefix of group ranges covered. This command is vrf aware, to configure for - a vrf, enter the vrf submode. + a vrf, specify the vrf in the router pim block. -.. clicmd:: ip pim rp keep-alive-timer (1-65535) +.. clicmd:: rp keep-alive-timer (1-65535) Modify the time out value for a S,G flow from 1-65535 seconds at RP. The normal keepalive period for the KAT(S,G) defaults to 210 seconds. @@ -74,41 +80,41 @@ Certain signals have special meanings to *pimd*. max(Keepalive_Period, RP_Keepalive_Period) when a Register-Stop is sent. If choosing a value below 31 seconds be aware that some hardware platforms cannot see data flowing in better than 30 second chunks. This command is - vrf aware, to configure for a vrf, enter the vrf submode. + vrf aware, to configure for a vrf, specify the vrf in the router pim block. -.. clicmd:: ip pim register-accept-list PLIST +.. clicmd:: register-accept-list PLIST When pim receives a register packet the source of the packet will be compared to the prefix-list specified, PLIST, and if a permit is received normal processing continues. If a deny is returned for the source address of the register packet a register stop message is sent to the source. -.. clicmd:: ip pim spt-switchover infinity-and-beyond [prefix-list PLIST] +.. clicmd:: spt-switchover infinity-and-beyond [prefix-list PLIST] On the last hop router if it is desired to not switch over to the SPT tree configure this command. Optional parameter prefix-list can be use to control which groups to switch or not switch. If a group is PERMIT as per the PLIST, then the SPT switchover does not happen for it and if it is DENY, then the SPT switchover happens. - This command is vrf aware, to configure for a vrf, - enter the vrf submode. + This command is vrf aware, to configure for a vrf, specify the vrf in the + router pim block. -.. clicmd:: ip pim ecmp +.. clicmd:: ecmp If pim has the a choice of ECMP nexthops for a particular RPF, pim will cause S,G flows to be spread out amongst the nexthops. If this command is not specified then the first nexthop found will be used. This command is vrf - aware, to configure for a vrf, enter the vrf submode. + aware, to configure for a vrf, specify the vrf in the router pim block. -.. clicmd:: ip pim ecmp rebalance +.. clicmd:: ecmp rebalance If pim is using ECMP and an interface goes down, cause pim to rebalance all S,G flows across the remaining nexthops. If this command is not configured pim only modifies those S,G flows that were using the interface that went - down. This command is vrf aware, to configure for a vrf, enter the vrf - submode. + down. This command is vrf aware, to configure for a vrf, specify the vrf in + the router pim block. -.. clicmd:: ip pim join-prune-interval (1-65535) +.. clicmd:: join-prune-interval (1-65535) Modify the join/prune interval that pim uses to the new value. Time is specified in seconds. This command is vrf aware, to configure for a vrf, @@ -116,39 +122,42 @@ Certain signals have special meanings to *pimd*. a value smaller than 60 seconds be aware that this can and will affect convergence at scale. -.. clicmd:: ip pim keep-alive-timer (1-65535) +.. clicmd:: keep-alive-timer (1-65535) Modify the time out value for a S,G flow from 1-65535 seconds. If choosing a value below 31 seconds be aware that some hardware platforms cannot see data flowing in better than 30 second chunks. This command is vrf aware, to - configure for a vrf, enter the vrf submode. + configure for a vrf, specify the vrf in the router pim block. -.. clicmd:: ip pim packets (1-255) +.. clicmd:: packets (1-255) When processing packets from a neighbor process the number of packets incoming at one time before moving on to the next task. The default value is 3 packets. This command is only useful at scale when you can possibly have a large number of pim control packets flowing. This command is vrf aware, to - configure for a vrf, enter the vrf submode. + configure for a vrf, specify the vrf in the router pim block. -.. clicmd:: ip pim register-suppress-time (1-65535) +.. clicmd:: register-suppress-time (1-65535) Modify the time that pim will register suppress a FHR will send register notifications to the kernel. This command is vrf aware, to configure for a - vrf, enter the vrf submode. + vrf, specify the vrf in the router pim block. -.. clicmd:: ip pim send-v6-secondary +.. clicmd:: send-v6-secondary When sending pim hello packets tell pim to send any v6 secondary addresses on the interface. This information is used to allow pim to use v6 nexthops in it's decision for RPF lookup. This command is vrf aware, to configure for - a vrf, enter the vrf submode. + a vrf, specify the vrf in the router pim block. -.. clicmd:: ip pim ssm prefix-list WORD +.. clicmd:: ssm prefix-list WORD Specify a range of group addresses via a prefix-list that forces pim to - never do SM over. This command is vrf aware, to configure for a vrf, enter - the vrf submode. + never do SM over. This command is vrf aware, to configure for a vrf, specify + the vrf in the router pim block. + +Global Multicast +---------------- .. clicmd:: ip multicast rpf-lookup-mode WORD @@ -334,11 +343,12 @@ MSDP can be setup in different ways: .. note:: MSDP default peer and SA filtering is not implemented. + MSDP configuration is available under 'router pim' Commands available for MSDP: -.. clicmd:: ip msdp timers (1-65535) (1-65535) [(1-65535)] +.. clicmd:: msdp timers (1-65535) (1-65535) [(1-65535)] Configure global MSDP timers. @@ -354,16 +364,16 @@ Commands available for MSDP: configures the interval between connection attempts. The default value is 30 seconds. -.. clicmd:: ip msdp mesh-group WORD member A.B.C.D +.. clicmd:: msdp mesh-group WORD member A.B.C.D Create or update a mesh group to include the specified MSDP peer. -.. clicmd:: ip msdp mesh-group WORD source A.B.C.D +.. clicmd:: msdp mesh-group WORD source A.B.C.D Create or update a mesh group to set the source address used to connect to peers. -.. clicmd:: ip msdp peer A.B.C.D source A.B.C.D +.. clicmd:: msdp peer A.B.C.D source A.B.C.D Create a regular MSDP session with peer using the specified source address. @@ -734,8 +744,9 @@ Sample configuration ! You may want to enable ssmpingd for troubleshooting ! See http://www.venaas.no/multicast/ssmping/ ! - ip ssmpingd 1.1.1.1 - ip ssmpingd 2.2.2.2 + router pim + ssmpingd 1.1.1.1 + ssmpingd 2.2.2.2 ! HINTS: ! - Enable "ip pim ssm" on the interface directly attached to the diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst index b8567e4863ae..fa78eeb70c7f 100644 --- a/doc/user/pimv6.rst +++ b/doc/user/pimv6.rst @@ -47,21 +47,28 @@ Certain signals have special meanings to *pim6d*. *pim6d* invocation options. Common options that can be specified (:ref:`common-invocation-options`). -.. clicmd:: ipv6 pim rp X:X::X:X Y:Y::Y:Y/M +PIMv6 Router +------------ + +.. clicmd:: router pim6 [vrf NAME] + + Configure the global PIMv6 protocol + +.. clicmd:: rp X:X::X:X Y:Y::Y:Y/M In order to use pimv6, it is necessary to configure a RP for join messages to be sent to. Currently the only methodology to do this is via static rp commands. All routers in the pimv6 network must agree on these values. The first ipv6 address is the RP's address and the second value is the matching prefix of group ranges covered. This command is vrf aware, to configure for - a vrf, enter the vrf submode. + a vrf, specify the vrf in the router pim6 block. -.. clicmd:: ipv6 pim rp X:X::X:X prefix-list WORD +.. clicmd:: rp X:X::X:X prefix-list WORD This CLI helps in configuring RP address for a range of groups specified by the prefix-list. -.. clicmd:: ipv6 pim rp keep-alive-timer (1-65535) +.. clicmd:: rp keep-alive-timer (1-65535) Modify the time out value for a S,G flow from 1-65535 seconds at RP. The normal keepalive period for the KAT(S,G) defaults to 210 seconds. @@ -71,19 +78,19 @@ Certain signals have special meanings to *pim6d*. max(Keepalive_Period, RP_Keepalive_Period) when a Register-Stop is sent. If choosing a value below 31 seconds be aware that some hardware platforms cannot see data flowing in better than 30 second chunks. This command is - vrf aware, to configure for a vrf, enter the vrf submode. + vrf aware, to configure for a vrf, specify the vrf in the router pim6 block. -.. clicmd:: ipv6 pim spt-switchover infinity-and-beyond [prefix-list PLIST] +.. clicmd:: spt-switchover infinity-and-beyond [prefix-list PLIST] On the last hop router if it is desired to not switch over to the SPT tree configure this command. Optional parameter prefix-list can be use to control which groups to switch or not switch. If a group is PERMIT as per the PLIST, then the SPT switchover does not happen for it and if it is DENY, then the SPT switchover happens. - This command is vrf aware, to configure for a vrf, - enter the vrf submode. + This command is vrf aware, to configure for a vrf, specify the vrf in the + router pim6 block. -.. clicmd:: ipv6 pim join-prune-interval (1-65535) +.. clicmd:: join-prune-interval (1-65535) Modify the join/prune interval that pim uses to the new value. Time is specified in seconds. This command is vrf aware, to configure for a vrf, @@ -91,28 +98,28 @@ Certain signals have special meanings to *pim6d*. a value smaller than 60 seconds be aware that this can and will affect convergence at scale. -.. clicmd:: ipv6 pim keep-alive-timer (1-65535) +.. clicmd:: keep-alive-timer (1-65535) Modify the time out value for a S,G flow from 1-65535 seconds. If choosing a value below 31 seconds be aware that some hardware platforms cannot see data flowing in better than 30 second chunks. This command is vrf aware, to - configure for a vrf, enter the vrf submode. + configure for a vrf, specify the vrf in the router pim6 block. -.. clicmd:: ipv6 pim packets (1-255) +.. clicmd:: packets (1-255) When processing packets from a neighbor process the number of packets incoming at one time before moving on to the next task. The default value is 3 packets. This command is only useful at scale when you can possibly have a large number of pim control packets flowing. This command is vrf aware, to - configure for a vrf, enter the vrf submode. + configure for a vrf, specify the vrf in the router pim6 block. -.. clicmd:: ipv6 pim register-suppress-time (1-65535) +.. clicmd:: register-suppress-time (1-65535) Modify the time that pim will register suppress a FHR will send register notifications to the kernel. This command is vrf aware, to configure for a - vrf, enter the vrf submode. + vrf, specify the vrf in the router pim6 block. -.. clicmd:: ipv6 ssmpingd [X:X::X:X] +.. clicmd:: ssmpingd [X:X::X:X] Enable ipv6 ssmpingd configuration. A network level management tool to check whether one can receive multicast packets via SSM from host. @@ -417,7 +424,7 @@ Clear commands reset various variables. .. clicmd:: clear ipv6 pim [vrf NAME] interface traffic - When this command is issued, resets the information about the + When this command is issued, resets the information about the number of PIM protocol packets sent/received on an interface. .. clicmd:: clear ipv6 pim oil @@ -494,7 +501,7 @@ the config was written out. .. clicmd:: debug mld trace [detail] - This traces mld code and how it is running. + This traces mld code and how it is running. .. clicmd:: debug pimv6 bsm From f46ce043fc0cba104c6fb4e13c1fd031928de346 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 17 Jul 2024 02:12:48 +0300 Subject: [PATCH 410/472] lib, vtysh: Removed deprecated aliases for `show thread ...` Signed-off-by: Donatas Abraitis --- lib/event.c | 28 ---------------------------- vtysh/vtysh.c | 3 --- 2 files changed, 31 deletions(-) diff --git a/lib/event.c b/lib/event.c index fc46a11c0b46..c04d309bc26a 100644 --- a/lib/event.c +++ b/lib/event.c @@ -304,9 +304,6 @@ static uint8_t parse_filter(const char *filterstr) return filter; } -#if CONFDATE > 20240707 - CPP_NOTICE("Remove `show thread ...` commands") -#endif DEFUN_NOSH (show_event_cpu, show_event_cpu_cmd, "show event cpu [FILTER]", @@ -332,14 +329,6 @@ DEFUN_NOSH (show_event_cpu, return CMD_SUCCESS; } -ALIAS(show_event_cpu, - show_thread_cpu_cmd, - "show thread cpu [FILTER]", - SHOW_STR - "Thread information\n" - "Thread CPU usage\n" - "Display filter (rwtex)\n") - DEFPY (service_cputime_stats, service_cputime_stats_cmd, "[no] service cputime-stats", @@ -440,13 +429,6 @@ DEFUN_NOSH (show_event_poll, return CMD_SUCCESS; } -ALIAS(show_event_poll, - show_thread_poll_cmd, - "show thread poll", - SHOW_STR - "Thread information\n" - "Show poll FD's and information\n") - DEFUN (clear_thread_cpu, clear_thread_cpu_cmd, "clear thread cpu [FILTER]", @@ -507,18 +489,9 @@ DEFPY_NOSH (show_event_timers, return CMD_SUCCESS; } -ALIAS(show_event_timers, - show_thread_timers_cmd, - "show thread timers", - SHOW_STR - "Thread information\n" - "Show all timers and how long they have in the system\n") - void event_cmd_init(void) { - install_element(VIEW_NODE, &show_thread_cpu_cmd); install_element(VIEW_NODE, &show_event_cpu_cmd); - install_element(VIEW_NODE, &show_thread_poll_cmd); install_element(VIEW_NODE, &show_event_poll_cmd); install_element(ENABLE_NODE, &clear_thread_cpu_cmd); @@ -526,7 +499,6 @@ void event_cmd_init(void) install_element(CONFIG_NODE, &service_cputime_warning_cmd); install_element(CONFIG_NODE, &service_walltime_warning_cmd); - install_element(VIEW_NODE, &show_thread_timers_cmd); install_element(VIEW_NODE, &show_event_timers_cmd); } /* CLI end ------------------------------------------------------------------ */ diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 573320667c33..9d56f04472a1 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2988,9 +2988,6 @@ static int show_one_daemon(struct vty *vty, struct cmd_token **argv, int argc, return ret; } -#if CONFDATE > 20240707 - CPP_NOTICE("Remove `show thread ...` commands") -#endif DEFUN (vtysh_show_event_timer, vtysh_show_event_timer_cmd, "show event timers", From 193e14e401c88d2d9e822a2474b0f777efff4958 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 17 Jul 2024 02:17:59 +0300 Subject: [PATCH 411/472] lib: Rename `clear thread cpu ...` to `clear event cpu ...` Add a deprecation cycle also. Signed-off-by: Donatas Abraitis --- lib/event.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/event.c b/lib/event.c index c04d309bc26a..f4aa7c58b9d2 100644 --- a/lib/event.c +++ b/lib/event.c @@ -429,12 +429,15 @@ DEFUN_NOSH (show_event_poll, return CMD_SUCCESS; } -DEFUN (clear_thread_cpu, - clear_thread_cpu_cmd, - "clear thread cpu [FILTER]", +#if CONFDATE > 20241231 +CPP_NOTICE("Remove `clear thread cpu` command") +#endif +DEFUN (clear_event_cpu, + clear_event_cpu_cmd, + "clear event cpu [FILTER]", "Clear stored data in all pthreads\n" - "Thread information\n" - "Thread CPU usage\n" + "Event information\n" + "Event CPU usage\n" "Display filter (rwtexb)\n") { uint8_t filter = (uint8_t)-1U; @@ -454,6 +457,14 @@ DEFUN (clear_thread_cpu, return CMD_SUCCESS; } +ALIAS (clear_event_cpu, + clear_thread_cpu_cmd, + "clear thread cpu [FILTER]", + "Clear stored data in all pthreads\n" + "Thread information\n" + "Thread CPU usage\n" + "Display filter (rwtexb)\n") + static void show_event_timers_helper(struct vty *vty, struct event_loop *m) { const char *name = m->name ? m->name : "main"; @@ -494,6 +505,7 @@ void event_cmd_init(void) install_element(VIEW_NODE, &show_event_cpu_cmd); install_element(VIEW_NODE, &show_event_poll_cmd); install_element(ENABLE_NODE, &clear_thread_cpu_cmd); + install_element(ENABLE_NODE, &clear_event_cpu_cmd); install_element(CONFIG_NODE, &service_cputime_stats_cmd); install_element(CONFIG_NODE, &service_cputime_warning_cmd); From 0546572d70c34a9b810aae6d517afdb655ec299f Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 17 Jul 2024 08:10:13 +0300 Subject: [PATCH 412/472] tools: Ignore ALIAS_* macros for clang-formatter Signed-off-by: Donatas Abraitis --- .clang-format | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.clang-format b/.clang-format index 06769c966152..7aefafa58fbf 100644 --- a/.clang-format +++ b/.clang-format @@ -224,4 +224,8 @@ WhitespaceSensitiveMacros: - "DEFUN_YANG_NOSH" - "DEFUNSH" - "DEFUNSH_HIDDEN" + - "ALIAS" + - "ALIAS_HIDDEN" + - "ALIAS_YANG" + - "ALIAS_DEPRECATED" ... From 5a70378a47f541b0354fbb96770dd0a65ec552b8 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 13 Jul 2024 08:43:36 +0200 Subject: [PATCH 413/472] ospfd: fix internal ldp-sync state flags when feature is disabled When enabling "mpls ldp-sync" under "router ospf" ospfd configures SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG) so internally knowing that the ldp-sync feature is enabled. However the flag is not cleared when turning of the feature using "nompls ldp-sync"! https://github.com/FRRouting/frr/issues/16375 Signed-off-by: Christian Breunig --- ospfd/ospf_ldp_sync.c | 2 +- tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref | 4 ++-- .../r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref | 4 ++-- .../r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref | 4 ++-- tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref | 4 ++-- .../r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref | 4 ++-- .../r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c index d1ef85c9a6eb..496ae5b4bdc9 100644 --- a/ospfd/ospf_ldp_sync.c +++ b/ospfd/ospf_ldp_sync.c @@ -901,7 +901,7 @@ DEFPY (no_mpls_ldp_sync, * stop holddown timer if running * restore ospf cost */ - SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); + UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG); ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT; ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED; EVENT_OFF(ldp_sync_info->t_holddown); diff --git a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref index 6c27a1042760..846be5b849c9 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync.ref @@ -5,8 +5,8 @@ "ldpIgpSyncState":"Sync achieved" }, "r2-eth2":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" } } diff --git a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref index 889f69ed7f40..ad3b8b5ca442 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r1_eth1_shutdown.ref @@ -5,8 +5,8 @@ "ldpIgpSyncState":"Holding down until Sync" }, "r2-eth2":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" } } diff --git a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref index d9036e124bca..d5e4b88d07cd 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r2/show_ospf_ldp_sync_r2_eth1_shutdown.ref @@ -1,7 +1,7 @@ { "r2-eth2":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" } } diff --git a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref index b417ab040ab5..5b9542d5a996 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync.ref @@ -1,8 +1,8 @@ { "r3-eth1":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" }, "r3-eth2":{ "ldpIgpSyncEnabled":true, diff --git a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref index b417ab040ab5..5b9542d5a996 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r1_eth1_shutdown.ref @@ -1,8 +1,8 @@ { "r3-eth1":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" }, "r3-eth2":{ "ldpIgpSyncEnabled":true, diff --git a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref index b417ab040ab5..5b9542d5a996 100644 --- a/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref +++ b/tests/topotests/ldp_sync_ospf_topo1/r3/show_ospf_ldp_sync_r2_eth1_shutdown.ref @@ -1,8 +1,8 @@ { "r3-eth1":{ - "ldpIgpSyncEnabled":false, + "ldpIgpSyncEnabled":true, "holdDownTimeInSec":50, - "ldpIgpSyncState":"Sync not required" + "ldpIgpSyncState":"Sync achieved" }, "r3-eth2":{ "ldpIgpSyncEnabled":true, From 55be38d98e4ba7ca4c7a88f0c0eef8c484e67d47 Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Wed, 17 Jul 2024 15:16:44 +0800 Subject: [PATCH 414/472] doc: adjust some commands for pim/pimv6 bsr Signed-off-by: anlan_cs --- doc/user/pim.rst | 4 ++-- doc/user/pimv6.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/user/pim.rst b/doc/user/pim.rst index b19bb9d1b3ad..862469852f0d 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -576,11 +576,11 @@ cause great confusion. Display current bsr, its uptime and last received bsm age. -.. clicmd:: show ip pim bsrp-info +.. clicmd:: show ip pim bsrp-info [vrf NAME] [json] Display group-to-rp mappings received from E-BSR. -.. clicmd:: show ip pim bsm-database +.. clicmd:: show ip pim bsm-database [vrf NAME] [json] Display all fragments of stored bootstrap message in user readable format. diff --git a/doc/user/pimv6.rst b/doc/user/pimv6.rst index b8567e4863ae..a166149bf74d 100644 --- a/doc/user/pimv6.rst +++ b/doc/user/pimv6.rst @@ -388,11 +388,11 @@ General multicast routing state Display current bsr, its uptime and last received bsm age. -.. clicmd:: show ipv6 pim bsrp-info +.. clicmd:: show ipv6 pim bsrp-info [vrf NAME] [json] Display group-to-rp mappings received from E-BSR. -.. clicmd:: show ipv6 pim bsm-database +.. clicmd:: show ipv6 pim bsm-database [vrf NAME] [json] Display all fragments of stored bootstrap message in user readable format. From e36e570c6c2c4ee9be618ffef667e9d1a5758478 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 17 Jul 2024 11:28:10 +0200 Subject: [PATCH 415/472] zebra: add nexthop counter to 'show zebra dplane' command The nexthop updates counter value was never displayed. Add it. > # show zebra dplane > Zebra dataplane: > Route updates: 7673010 > Route update errors: 0 > Nexthop updates: 1100 > Nexthop update errors: 0 > [..] Signed-off-by: Philippe Guibert --- zebra/zebra_dplane.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 0844b346723b..1cee1ebb9331 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -6003,6 +6003,14 @@ int dplane_show_helper(struct vty *vty, bool detailed) vty_out(vty, "Zebra dataplane:\nRoute updates: %"PRIu64"\n", incoming); vty_out(vty, "Route update errors: %"PRIu64"\n", errs); + + incoming = atomic_load_explicit(&zdplane_info.dg_nexthops_in, + memory_order_relaxed); + errs = atomic_load_explicit(&zdplane_info.dg_nexthop_errors, + memory_order_relaxed); + vty_out(vty, "Nexthop updates: %" PRIu64 "\n", incoming); + vty_out(vty, "Nexthop update errors: %" PRIu64 "\n", errs); + vty_out(vty, "Other errors : %"PRIu64"\n", other_errs); vty_out(vty, "Route update queue limit: %"PRIu64"\n", limit); vty_out(vty, "Route update queue depth: %"PRIu64"\n", queued); From 329a4192f65aa454c2d041da9285235143d7f270 Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Wed, 17 Jul 2024 16:20:13 +0530 Subject: [PATCH 416/472] yang: Fixed pyang warnings at frr-bfdd yang file Fixed warnings at frr-bfdd yang file Signed-off-by: y-bharath14 --- yang/frr-bfdd.yang | 3 --- 1 file changed, 3 deletions(-) diff --git a/yang/frr-bfdd.yang b/yang/frr-bfdd.yang index ffba42b53b9a..02ed9214599f 100644 --- a/yang/frr-bfdd.yang +++ b/yang/frr-bfdd.yang @@ -16,9 +16,6 @@ module frr-bfdd { import frr-vrf { prefix frr-vrf; } - import frr-route-types { - prefix frr-route-types; - } organization "FRRouting"; contact From 8b81f32e97876eefe13370d1efba6a7aeb1c6771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sang?= Date: Tue, 16 Jul 2024 14:03:11 +0200 Subject: [PATCH 417/472] bgpd: fix label lost when vrf loopback comes back MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VRF-label association drops when the VRF loopback goes down, however, it does not return once the interface is enabled again. Logs show that when VRF loopback goes down, a label drop message is sent to zebra and immediately resent label installation to zebra, trigged by "vpn_leak_postchange_all()": 2024/07/16 13:26:29 BGP: [RVJ1J-J2T22] ifp down r1-cust1 vrf id 7 2024/07/16 13:26:29 BGP: [WA2QY-06STJ] vpn_leak_zebra_vrf_label_withdraw: deleting label for vrf VRF r1-cust1 (id=7) 2024/07/16 13:26:30 BGP: [S82AC-6YAC8] vpn_leak_zebra_vrf_label_update: vrf VRF r1-cust1: afi IPv4: setting label 80 for vrf id 7 Since the interface is down, the netlink message is not send to kernel. Once the interface comes back, zebra ignore the installation assuming the label is already seen. To fix this, add a check for the interface status before attempting to reinstall the label. Signed-off-by: Loïc Sang --- bgpd/bgp_mplsvpn.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 90881621b331..a1d0a8512c82 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -280,7 +280,8 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, * * Sending this vrf-label association is qualified by a) whether vrf->vpn * exporting is active ("export vpn" is enabled, vpn-policy RD and RT list - * are set) and b) whether vpn-policy label is set. + * are set), b) whether vpn-policy label is set and c) the vrf loopback + * interface is up. * * If any of these conditions do not hold, then we send MPLS_LABEL_NONE * for this vrf, which zebra interprets to mean "delete this vrf-label @@ -288,6 +289,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr, */ void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi) { + struct interface *ifp; mpls_label_t label = MPLS_LABEL_NONE; int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL); @@ -301,7 +303,9 @@ void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi) } if (vpn_leak_to_vpn_active(bgp, afi, NULL, false)) { - label = bgp->vpn_policy[afi].tovpn_label; + ifp = if_get_vrf_loopback(bgp->vrf_id); + if (ifp && if_is_vrf(ifp) && if_is_up(ifp)) + label = bgp->vpn_policy[afi].tovpn_label; } if (debug) { From c21c597d5d885b46765ede114a96634d51071530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Sang?= Date: Wed, 17 Jul 2024 14:40:09 +0200 Subject: [PATCH 418/472] bgpd: do not update leak label at loopback up down MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The up/down state of the lo loopback interface does not determine the availability of the default vrf-lite. Do not update leak label at lo loopback up/down change. Fixes: b45c5cd959 ("bgpd: update route leak when vrf state changes") Signed-off-by: Louis Scalbert Signed-off-by: Loïc Sang --- bgpd/bgp_zebra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 7f91e3149e0b..180f4264ecfd 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -234,7 +234,7 @@ static int bgp_ifp_up(struct interface *ifp) hook_call(bgp_vrf_status_changed, bgp, ifp); bgp_nht_ifp_up(ifp); - if (bgp_get_default() && if_is_loopback(ifp)) { + if (bgp_get_default() && if_is_vrf(ifp)) { vpn_leak_zebra_vrf_label_update(bgp, AFI_IP); vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6); vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP); @@ -289,7 +289,7 @@ static int bgp_ifp_down(struct interface *ifp) hook_call(bgp_vrf_status_changed, bgp, ifp); bgp_nht_ifp_down(ifp); - if (bgp_get_default() && if_is_loopback(ifp)) { + if (bgp_get_default() && if_is_vrf(ifp)) { vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP); vpn_leak_zebra_vrf_label_withdraw(bgp, AFI_IP6); vpn_leak_zebra_vrf_sid_withdraw(bgp, AFI_IP); From ddc1c2eeae981232e4b9a7021ecf4cdaf33f3a05 Mon Sep 17 00:00:00 2001 From: Nathan Bahr Date: Wed, 17 Jul 2024 11:10:53 -0500 Subject: [PATCH 419/472] tests: OSPFv3 hello tests investigation, make assert output unique These failing tests are hard to track down. Added numbering to each assert to easily tell where the test fails. Signed-off-by: Nathan Bahr --- .../test_ospfv3_single_area.py | 97 +++++++++++++------ 1 file changed, 69 insertions(+), 28 deletions(-) diff --git a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py index 15e0f5316ea0..d981a84597b3 100644 --- a/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py +++ b/tests/topotests/ospfv3_basic_functionality/test_ospfv3_single_area.py @@ -388,6 +388,11 @@ def test_ospfv3_hello_tc10_p0(request): step("Bring up the base config as per the topology") reset_config_on_routers(tgen) + ospf_covergence = verify_ospf6_neighbor(tgen) + assert ( + ospf_covergence is True + ), "Testcase {} [01]: Reset Failed \n Error: {}".format(tc_name, ospf_covergence) + step("modify hello timer from default value to some other value on r1") topo1 = { @@ -402,7 +407,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [02]: Failed \n Error: {}".format( + tc_name, result + ) step( "verify that new timer value is configured and applied using " @@ -422,7 +429,9 @@ def test_ospfv3_hello_tc10_p0(request): } } result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [03]: Failed \n Error: {}".format( + tc_name, result + ) step("modify hello timer from default value to r1 hello timer on r2") @@ -438,7 +447,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [04]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that new timer value is configured.") input_dict = { @@ -455,12 +466,14 @@ def test_ospfv3_hello_tc10_p0(request): } dut = "r0" result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [05]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that ospf neighbours are full") ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) - assert ospf_covergence is True, "Testcase Failed \n Error: {}".format( - ospf_covergence + assert ospf_covergence is True, "Testcase {} [06]: Failed \n Error: {}".format( + tc_name, ospf_covergence ) step("reconfigure the default hello timer value to default on r1 and r2") @@ -477,7 +490,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [07]: Failed \n Error: {}".format( + tc_name, result + ) topo1 = { "r1": { @@ -491,7 +506,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [08]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that new timer value is configured.") input_dict = { @@ -508,12 +525,14 @@ def test_ospfv3_hello_tc10_p0(request): } dut = "r0" result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [09]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that ospf neighbours are full") ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) - assert ospf_covergence is True, "Testcase Failed \n Error: {}".format( - ospf_covergence + assert ospf_covergence is True, "Testcase {} [10]: Failed \n Error: {}".format( + tc_name, ospf_covergence ) step("reconfigure the default hello timer value to default on r1 and r2") @@ -530,7 +549,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [11]: Failed \n Error: {}".format( + tc_name, result + ) topo1 = { "r1": { @@ -544,7 +565,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [12]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that new timer value is configured.") input_dict = { @@ -561,12 +584,14 @@ def test_ospfv3_hello_tc10_p0(request): } dut = "r0" result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [13]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that ospf neighbours are full") ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) - assert ospf_covergence is True, "Testcase Failed \n Error: {}".format( - ospf_covergence + assert ospf_covergence is True, "Testcase {} [14]: Failed \n Error: {}".format( + tc_name, ospf_covergence ) step("configure hello timer = 1 on r1 and r2") @@ -582,7 +607,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [15]: Failed \n Error: {}".format( + tc_name, result + ) topo1 = { "r1": { @@ -596,7 +623,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [16]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that new timer value is configured.") input_dict = { @@ -613,12 +642,14 @@ def test_ospfv3_hello_tc10_p0(request): } dut = "r0" result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [17]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that ospf neighbours are full") ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) - assert ospf_covergence is True, "Testcase Failed \n Error: {}".format( - ospf_covergence + assert ospf_covergence is True, "Testcase {} [18]: Failed \n Error: {}".format( + tc_name, ospf_covergence ) step(" Configure hello timer = 65535") @@ -634,7 +665,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [19]: Failed \n Error: {}".format( + tc_name, result + ) topo1 = { "r1": { @@ -648,7 +681,9 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [20]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that new timer value is configured.") input_dict = { @@ -665,11 +700,13 @@ def test_ospfv3_hello_tc10_p0(request): } dut = "r0" result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [21]: Failed \n Error: {}".format( + tc_name, result + ) step("verify that ospf neighbours are full") ospf_covergence = verify_ospf6_neighbor(tgen, topo, dut=dut) - assert ospf_covergence is True, "Testcase {} : Failed \n Error: {}".format( + assert ospf_covergence is True, "Testcase {} [22]: Failed \n Error: {}".format( tc_name, ospf_covergence ) step(" Try configuring timer values outside range for example 65536") @@ -687,7 +724,7 @@ def test_ospfv3_hello_tc10_p0(request): result = create_interfaces_cfg(tgen, topo1) assert ( result is not True - ), "Testcase {} : Failed \n Create interface failed. Error: {}".format( + ), "Testcase {} [23]: Failed \n Create interface failed. Error: {}".format( tc_name, result ) @@ -706,13 +743,17 @@ def test_ospfv3_hello_tc10_p0(request): } result = create_interfaces_cfg(tgen, topo1) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [24]: Failed \n Error: {}".format( + tc_name, result + ) step("Verify that timer value is deleted from intf & set to default value 40 sec.") input_dict = {"r1": {"links": {"r0": {"ospf6": {"timerIntervalsConfigHello": 10}}}}} dut = "r1" result = verify_ospf6_interface(tgen, topo, dut=dut, input_dict=input_dict) - assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result) + assert result is True, "Testcase {} [25]: Failed \n Error: {}".format( + tc_name, result + ) write_test_footer(tc_name) From 55de91d8535d15c6cc08f8a36be5363b021e65ce Mon Sep 17 00:00:00 2001 From: Dave LeRoy Date: Wed, 17 Jul 2024 10:37:44 -0700 Subject: [PATCH 420/472] nhrpd: Fixes auth config change bug Freeing auth-token does not set nifp->auth_token to NULL. Explicitly set auth_token to NULL when deleting auth config in order for write config logic to succeed. Fix bug #16359 Signed-off-by: Dave LeRoy --- nhrpd/nhrp_vty.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nhrpd/nhrp_vty.c b/nhrpd/nhrp_vty.c index b938ae4cf0e8..22b6bdcec739 100644 --- a/nhrpd/nhrp_vty.c +++ b/nhrpd/nhrp_vty.c @@ -481,8 +481,10 @@ DEFPY(if_nhrp_authentication, if_nhrp_authentication_cmd, return CMD_WARNING_CONFIG_FAILED; } - if (nifp->auth_token) + if (nifp->auth_token) { zbuf_free(nifp->auth_token); + nifp->auth_token = NULL; + } nifp->auth_token = zbuf_alloc(pass_len + sizeof(uint32_t)); auth = (struct nhrp_cisco_authentication_extension *) @@ -505,8 +507,10 @@ DEFPY(if_no_nhrp_authentication, if_no_nhrp_authentication_cmd, VTY_DECLVAR_CONTEXT(interface, ifp); struct nhrp_interface *nifp = ifp->info; - if (nifp->auth_token) + if (nifp->auth_token) { zbuf_free(nifp->auth_token); + nifp->auth_token = NULL; + } return CMD_SUCCESS; } From c531584a37bb34e7d8cf62887fd27c701270cd4b Mon Sep 17 00:00:00 2001 From: Dave LeRoy Date: Thu, 18 Jul 2024 10:19:30 -0700 Subject: [PATCH 421/472] nhrpd: Fixes auth no redirect bug The nhrp_peer_forward() routine was not explicitly handling the Authentication Extension in the switch statement and instead fell through to the default case which checked whether this was an unhandled Compulsory extension and errored out, never forwarding the Resolution Request. Fix bug #16371 Signed-off-by: Dave LeRoy --- nhrpd/nhrp_peer.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 2414541bfaf4..0407b86be8a9 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -1046,6 +1046,13 @@ static void nhrp_peer_forward(struct nhrp_peer *p, zbuf_put(zb, extpl.head, len); } break; + case NHRP_EXTENSION_AUTHENTICATION: + /* At this point, received packet has been authenticated. + * Just need to regenerate auth extension before forwarding. + * This will be done below in nhrp_packet_complete_auth(). + */ + break; + default: if (htons(ext->type) & NHRP_EXTENSION_FLAG_COMPULSORY) /* FIXME: RFC says to just copy, but not @@ -1064,7 +1071,7 @@ static void nhrp_peer_forward(struct nhrp_peer *p, nhrp_ext_complete(zb, dst); } - nhrp_packet_complete_auth(zb, hdr, pp->ifp, false); + nhrp_packet_complete_auth(zb, hdr, pp->ifp, true); nhrp_peer_send(p, zb); zbuf_free(zb); zbuf_free(zb_copy); From e8169f9385f8423b7086f2a14ee0591811320444 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Fri, 19 Jul 2024 05:20:04 +0300 Subject: [PATCH 422/472] bgpd: Show extended parameters support for the OPEN messages We did that for the receiving side, but not for a sending side, let's fix it. Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 4625f15778a2..0fb59a94c283 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -651,6 +651,7 @@ void bgp_open_send(struct peer_connection *connection) uint16_t send_holdtime; as_t local_as; struct peer *peer = connection->peer; + bool ext_opt_params = false; if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) send_holdtime = peer->holdtime; @@ -677,15 +678,17 @@ void bgp_open_send(struct peer_connection *connection) /* Set capabilities */ if (CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) { - (void)bgp_open_capability(s, peer, true); + ext_opt_params = true; + (void)bgp_open_capability(s, peer, ext_opt_params); } else { struct stream *tmp = stream_new(STREAM_SIZE(s)); stream_copy(tmp, s); - if (bgp_open_capability(tmp, peer, false) - > BGP_OPEN_NON_EXT_OPT_LEN) { + if (bgp_open_capability(tmp, peer, ext_opt_params) > + BGP_OPEN_NON_EXT_OPT_LEN) { stream_free(tmp); - (void)bgp_open_capability(s, peer, true); + ext_opt_params = true; + (void)bgp_open_capability(s, peer, ext_opt_params); } else { stream_copy(s, tmp); stream_free(tmp); @@ -696,9 +699,10 @@ void bgp_open_send(struct peer_connection *connection) bgp_packet_set_size(s); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%pBP fd %d sending OPEN, version %d, my as %u, holdtime %d, id %pI4", - peer, peer->connection->fd, BGP_VERSION_4, local_as, - send_holdtime, &peer->local_id); + zlog_debug("%pBP fd %d sending OPEN%s, version %d, my as %u, holdtime %d, id %pI4", + peer, peer->connection->fd, + ext_opt_params ? " (Extended)" : "", BGP_VERSION_4, + local_as, send_holdtime, &peer->local_id); /* Dump packet if debug option is set. */ /* bgp_packet_dump (s); */ From c4bbb5b4369133f5b76275700ec79e90411a490d Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Tue, 16 Jul 2024 23:34:15 -0700 Subject: [PATCH 423/472] bgpd: backpressure - fix ret value evpn_route_select_install The return value of evpn_route_select_install is ignored in all cases except during vni route table install/uninstall and based on the returned value, an error is logged. Fixing this. Ticket :#3992392 Signed-off-by: Rajasekar Raja --- bgpd/bgp_evpn.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 75a7d85e88fc..9f0e26796549 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1490,11 +1490,12 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { if (bgp_zebra_has_route_changed(old_select)) { if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) - evpn_zebra_install(bgp, vpn, - (const struct prefix_evpn *) - bgp_dest_get_prefix( - dest), - old_select); + ret = evpn_zebra_install(bgp, vpn, + (const struct prefix_evpn + *) + bgp_dest_get_prefix( + dest), + old_select); else bgp_zebra_route_install(dest, old_select, bgp, true, vpn, false); @@ -1532,10 +1533,11 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, && (new_select->sub_type == BGP_ROUTE_IMPORTED || bgp_evpn_attr_is_sync(new_select->attr))) { if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) - evpn_zebra_install(bgp, vpn, - (const struct prefix_evpn *) - bgp_dest_get_prefix(dest), - new_select); + ret = evpn_zebra_install(bgp, vpn, + (const struct prefix_evpn *) + bgp_dest_get_prefix( + dest), + new_select); else bgp_zebra_route_install(dest, new_select, bgp, true, vpn, false); @@ -1559,11 +1561,12 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, old_select->sub_type == BGP_ROUTE_IMPORTED) { if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) || CHECK_FLAG(bgp->flags, BGP_FLAG_VNI_DOWN)) - evpn_zebra_uninstall(bgp, vpn, - (const struct prefix_evpn *) - bgp_dest_get_prefix( - dest), - old_select, false); + ret = evpn_zebra_uninstall(bgp, vpn, + (const struct prefix_evpn + *) + bgp_dest_get_prefix( + dest), + old_select, false); else bgp_zebra_route_install(dest, old_select, bgp, false, vpn, false); From 6cf5b7931101c343f6efaa1668f72fdf156f51c7 Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Thu, 18 Jul 2024 22:23:23 -0700 Subject: [PATCH 424/472] bgpd: backpressure - log error for evpn when route install to zebra fails. log error for evpn in case route install to zebra fails. Ticket :#3992392 Signed-off-by: Rajasekar Raja --- bgpd/bgp_zebra.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 72620de7d98e..2ab02bbafc42 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1785,6 +1785,7 @@ static void bgp_handle_route_announcements_to_zebra(struct event *e) struct bgp_table *table = NULL; enum zclient_send_status status = ZCLIENT_SEND_SUCCESS; bool install; + const struct prefix_evpn *evp = NULL; while (count < ZEBRA_ANNOUNCEMENTS_LIMIT) { is_evpn = false; @@ -1796,8 +1797,11 @@ static void bgp_handle_route_announcements_to_zebra(struct event *e) table = bgp_dest_table(dest); install = CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL); - if (table->afi == AFI_L2VPN && table->safi == SAFI_EVPN) + if (table->afi == AFI_L2VPN && table->safi == SAFI_EVPN) { is_evpn = true; + evp = (const struct prefix_evpn *)bgp_dest_get_prefix( + dest); + } if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("BGP %s%s route %pBD(%s) with dest %p and flags 0x%x to zebra", @@ -1835,6 +1839,17 @@ static void bgp_handle_route_announcements_to_zebra(struct event *e) UNSET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE); } + if (is_evpn && status == ZCLIENT_SEND_FAILURE) + flog_err(EC_BGP_EVPN_FAIL, + "%s (%u): Failed to %s EVPN %pFX %s route in VNI %u", + vrf_id_to_name(table->bgp->vrf_id), + table->bgp->vrf_id, + install ? "install" : "uninstall", evp, + evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE + ? "MACIP" + : "IMET", + dest->za_vpn->vni); + bgp_path_info_unlock(dest->za_bgp_pi); dest->za_bgp_pi = NULL; dest->za_vpn = NULL; From 8e5e19baaf88c82d8569ae6f3b950ba814e6184b Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Tue, 16 Jul 2024 12:49:10 +0530 Subject: [PATCH 425/472] yang: Corrected range in yang file Corrected range in yang file Signed-off-by: y-bharath14 --- yang/frr-eigrpd.yang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yang/frr-eigrpd.yang b/yang/frr-eigrpd.yang index f672dd557161..d3d9db2f62a3 100644 --- a/yang/frr-eigrpd.yang +++ b/yang/frr-eigrpd.yang @@ -75,7 +75,7 @@ module frr-eigrpd { typedef autonomous-system { description "Administrative domain identification for a network"; type uint16 { - range 1..65535; + range "1..65535"; } } From d022a4099c5476b78b2215fcc2f1c06559ceaf09 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sat, 20 Jul 2024 03:29:21 +0300 Subject: [PATCH 426/472] tools: Do not append an empty list (pim_vrfs) to the config lines If pim_vrfs is empty, we append [] into the lines array, and the reload is broken since it expects only strings, but gets an array inside at the end. ``` Traceback (most recent call last): File "/usr/lib/frr/frr-reload.py", line 2227, in log.debug("New Frr Config\n%s", newconf.get_lines()) File "/usr/lib/frr/frr-reload.py", line 436, in get_lines return "\n".join(self.lines) TypeError: sequence item 45: expected str instance, list found ``` Fixes: 98d47f43fbba4e376c8351c724e8c625799805f7 ("tools: Fix frr-reload to support legacy pim configuration from file") Signed-off-by: Donatas Abraitis --- tools/frr-reload.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 47e3637550e1..8a39f4204dae 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -400,7 +400,8 @@ def load_from_file(self, filename): self.lines.append(line) - self.lines.append(pim_vrfs) + if len(pim_vrfs) > 0: + self.lines.append(pim_vrfs) self.load_contexts() From 01b7bd3b133e0d09d86ff7d626616c2a66606694 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sat, 20 Jul 2024 03:30:08 +0300 Subject: [PATCH 427/472] tools: Apply black formatting for the recent frr-reload.py changes Signed-off-by: Donatas Abraitis --- tools/frr-reload.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 8a39f4204dae..342c57964cde 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -328,7 +328,10 @@ def load_from_file(self, filename): vrf_context = re_vrf.group(1) # Detect legacy pim commands that need to move under the router pim context - re_pim = re.match("^ip(v6)? pim ((ecmp|join|keep|mlag|packets|register|rp|send|spt|ssm).*)$", line) + re_pim = re.match( + "^ip(v6)? pim ((ecmp|join|keep|mlag|packets|register|rp|send|spt|ssm).*)$", + line, + ) if re_pim and re_pim.group(2): router_pim = "router pim" if re_pim.group(1): @@ -340,7 +343,7 @@ def load_from_file(self, filename): pim_vrfs.append(router_pim) pim_vrfs.append(re_pim.group(2)) pim_vrfs.append("exit") - line="# PIM VRF LINE MOVED TO ROUTER PIM" + line = "# PIM VRF LINE MOVED TO ROUTER PIM" else: self.lines.append(router_pim) self.lines.append(re_pim.group(2)) @@ -358,7 +361,7 @@ def load_from_file(self, filename): pim_vrfs.append(router_pim) pim_vrfs.append(re_pim.group(2)) pim_vrfs.append("exit") - line="# PIM VRF LINE MOVED TO ROUTER PIM" + line = "# PIM VRF LINE MOVED TO ROUTER PIM" else: self.lines.append(router_pim) self.lines.append(re_pim.group(2)) From 44ee7a4abe7f0a7fd56de75f762d328a63ec418c Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sun, 21 Jul 2024 09:36:28 +0200 Subject: [PATCH 428/472] tests: Fix warnings in `bgp_srv6l3vpn_to_bgp_vrf` When performing the `bgp_srv6l3vpn_to_bgp_vrf` topotest, the following warnings are observed: ``` 2024-07-21 08:01:51,390 WARNING: r1: Router(r1): proc failed: rc 127 pid 52974 args: /usr/bin/nsenter --mount=/proc/52322/ns/mnt --net=/proc/52322/ns/net --uts=/proc/52322/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,522 WARNING: r2: Router(r2): proc failed: rc 127 pid 52984 args: /usr/bin/nsenter --mount=/proc/52397/ns/mnt --net=/proc/52397/ns/net --uts=/proc/52397/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,632 WARNING: ce1: Router(ce1): proc failed: rc 127 pid 52994 args: /usr/bin/nsenter --mount=/proc/52472/ns/mnt --net=/proc/52472/ns/net --uts=/proc/52472/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,757 WARNING: ce2: Router(ce2): proc failed: rc 127 pid 53004 args: /usr/bin/nsenter --mount=/proc/52547/ns/mnt --net=/proc/52547/ns/net --uts=/proc/52547/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,878 WARNING: ce3: Router(ce3): proc failed: rc 127 pid 53014 args: /usr/bin/nsenter --mount=/proc/52622/ns/mnt --net=/proc/52622/ns/net --uts=/proc/52622/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,997 WARNING: ce4: Router(ce4): proc failed: rc 127 pid 53024 args: /usr/bin/nsenter --mount=/proc/52697/ns/mnt --net=/proc/52697/ns/net --uts=/proc/52697/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:52,109 WARNING: ce5: Router(ce5): proc failed: rc 127 pid 53034 args: /usr/bin/nsenter --mount=/proc/52772/ns/mnt --net=/proc/52772/ns/net --uts=/proc/52772/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:52,225 WARNING: ce6: Router(ce6): proc failed: rc 127 pid 53044 args: /usr/bin/nsenter --mount=/proc/52847/ns/mnt --net=/proc/52847/ns/net --uts=/proc/52847/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/setup.sh: No such file or directory stderr: *empty* ```` This occurs because the topotest attempts to execute the `setup.sh` file, and the file does not exist. Let's fix the issue by checking if the `setup.sh` file exists and executing it only if it does. Signed-off-by: Carmine Scarpitta --- .../bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py index 5d18083fd5e3..a6938668ad3b 100755 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py @@ -92,7 +92,8 @@ def setup_module(mod): tgen.start_topology() router_list = tgen.routers() for rname, router in tgen.routers().items(): - router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) + if os.path.exists("{}/{}/setup.sh".format(CWD, rname)): + router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) From 5d76346266e3db37501494400ac96b714ebffc32 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sun, 21 Jul 2024 09:36:47 +0200 Subject: [PATCH 429/472] tests: Fix warnings in `bgp_srv6l3vpn_to_bgp_vrf2` When performing the `bgp_srv6l3vpn_to_bgp_vrf2` topotest, the following warnings are observed: ``` 2024-07-21 08:01:51,390 WARNING: r1: Router(r1): proc failed: rc 127 pid 52974 args: /usr/bin/nsenter --mount=/proc/52322/ns/mnt --net=/proc/52322/ns/net --uts=/proc/52322/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,522 WARNING: r2: Router(r2): proc failed: rc 127 pid 52984 args: /usr/bin/nsenter --mount=/proc/52397/ns/mnt --net=/proc/52397/ns/net --uts=/proc/52397/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,632 WARNING: ce1: Router(ce1): proc failed: rc 127 pid 52994 args: /usr/bin/nsenter --mount=/proc/52472/ns/mnt --net=/proc/52472/ns/net --uts=/proc/52472/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,757 WARNING: ce2: Router(ce2): proc failed: rc 127 pid 53004 args: /usr/bin/nsenter --mount=/proc/52547/ns/mnt --net=/proc/52547/ns/net --uts=/proc/52547/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,878 WARNING: ce3: Router(ce3): proc failed: rc 127 pid 53014 args: /usr/bin/nsenter --mount=/proc/52622/ns/mnt --net=/proc/52622/ns/net --uts=/proc/52622/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,997 WARNING: ce4: Router(ce4): proc failed: rc 127 pid 53024 args: /usr/bin/nsenter --mount=/proc/52697/ns/mnt --net=/proc/52697/ns/net --uts=/proc/52697/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:52,109 WARNING: ce5: Router(ce5): proc failed: rc 127 pid 53034 args: /usr/bin/nsenter --mount=/proc/52772/ns/mnt --net=/proc/52772/ns/net --uts=/proc/52772/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:52,225 WARNING: ce6: Router(ce6): proc failed: rc 127 pid 53044 args: /usr/bin/nsenter --mount=/proc/52847/ns/mnt --net=/proc/52847/ns/net --uts=/proc/52847/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/setup.sh: No such file or directory stderr: *empty* ```` This occurs because the topotest attempts to execute the `setup.sh` file, and the file does not exist. Let's fix the issue by checking if the `setup.sh` file exists and executing it only if it does. Signed-off-by: Carmine Scarpitta --- .../test_bgp_srv6l3vpn_to_bgp_vrf2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py index 38baf434426d..3e21875503db 100755 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/test_bgp_srv6l3vpn_to_bgp_vrf2.py @@ -56,7 +56,8 @@ def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) tgen.start_topology() for rname, router in tgen.routers().items(): - router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) + if os.path.exists("{}/{}/setup.sh".format(CWD, rname)): + router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) From e3282e26e44573dd261da9c02c62e520912c101c Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Sun, 21 Jul 2024 09:37:06 +0200 Subject: [PATCH 430/472] tests: Fix warnings in `bgp_srv6l3vpn_to_bgp_vrf3` When performing the `bgp_srv6l3vpn_to_bgp_vrf3` topotest, the following warnings are observed: ``` 2024-07-21 08:01:51,390 WARNING: r1: Router(r1): proc failed: rc 127 pid 52974 args: /usr/bin/nsenter --mount=/proc/52322/ns/mnt --net=/proc/52322/ns/net --uts=/proc/52322/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,522 WARNING: r2: Router(r2): proc failed: rc 127 pid 52984 args: /usr/bin/nsenter --mount=/proc/52397/ns/mnt --net=/proc/52397/ns/net --uts=/proc/52397/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,632 WARNING: ce1: Router(ce1): proc failed: rc 127 pid 52994 args: /usr/bin/nsenter --mount=/proc/52472/ns/mnt --net=/proc/52472/ns/net --uts=/proc/52472/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,757 WARNING: ce2: Router(ce2): proc failed: rc 127 pid 53004 args: /usr/bin/nsenter --mount=/proc/52547/ns/mnt --net=/proc/52547/ns/net --uts=/proc/52547/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,878 WARNING: ce3: Router(ce3): proc failed: rc 127 pid 53014 args: /usr/bin/nsenter --mount=/proc/52622/ns/mnt --net=/proc/52622/ns/net --uts=/proc/52622/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:51,997 WARNING: ce4: Router(ce4): proc failed: rc 127 pid 53024 args: /usr/bin/nsenter --mount=/proc/52697/ns/mnt --net=/proc/52697/ns/net --uts=/proc/52697/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:52,109 WARNING: ce5: Router(ce5): proc failed: rc 127 pid 53034 args: /usr/bin/nsenter --mount=/proc/52772/ns/mnt --net=/proc/52772/ns/net --uts=/proc/52772/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/setup.sh: No such file or directory stderr: *empty* 2024-07-21 08:01:52,225 WARNING: ce6: Router(ce6): proc failed: rc 127 pid 53044 args: /usr/bin/nsenter --mount=/proc/52847/ns/mnt --net=/proc/52847/ns/net --uts=/proc/52847/ns/uts -F /bin/bash -c /bin/bash /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/setup.sh stdout: /bin/bash: /media/workspace/frr/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/setup.sh: No such file or directory stderr: *empty* ```` This occurs because the topotest attempts to execute the `setup.sh` file, and the file does not exist. Let's fix the issue by checking if the `setup.sh` file exists and executing it only if it does. Signed-off-by: Carmine Scarpitta --- .../test_bgp_srv6l3vpn_to_bgp_vrf3.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py index 92a30788fc4b..2400cd285349 100644 --- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py +++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py @@ -53,7 +53,8 @@ def setup_module(mod): tgen = Topogen(build_topo, mod.__name__) tgen.start_topology() for rname, router in tgen.routers().items(): - router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) + if os.path.exists("{}/{}/setup.sh".format(CWD, rname)): + router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname)) router.load_config( TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) ) From 1f24bbe1813ff2a3e89dbfb27fec2b9d1daa6776 Mon Sep 17 00:00:00 2001 From: sri-mohan1 Date: Wed, 17 Jul 2024 12:32:53 +0530 Subject: [PATCH 431/472] bgpd: changes for code maintainability these changes are for improving the code maintainability and readability Signed-off-by: sri-mohan1 --- bgpd/bgpd.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 476a01b8ef08..ec329d0c5487 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -2283,7 +2283,7 @@ static void peer_group2peer_config_copy_af(struct peer_group *group, flags_tmp = conf->af_flags[afi][safi] & ~pflags_ovrd; flags_tmp ^= conf->af_flags_invert[afi][safi] ^ peer->af_flags_invert[afi][safi]; - flags_tmp &= ~pflags_ovrd; + UNSET_FLAG(flags_tmp, pflags_ovrd); UNSET_FLAG(peer->af_flags[afi][safi], ~pflags_ovrd); SET_FLAG(peer->af_flags[afi][safi], flags_tmp); @@ -2523,10 +2523,10 @@ int peer_activate(struct peer *peer, afi_t afi, safi_t safi) group = peer->group; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) { - ret |= peer_activate_af(tmp_peer, afi, safi); + SET_FLAG(ret, peer_activate_af(tmp_peer, afi, safi)); } } else { - ret |= peer_activate_af(peer, afi, safi); + SET_FLAG(ret, peer_activate_af(peer, afi, safi)); } /* If this is the first peer to be activated for this @@ -2625,10 +2625,11 @@ int peer_deactivate(struct peer *peer, afi_t afi, safi_t safi) group = peer->group; for (ALL_LIST_ELEMENTS(group->peer, node, nnode, tmp_peer)) { - ret |= non_peergroup_deactivate_af(tmp_peer, afi, safi); + SET_FLAG(ret, non_peergroup_deactivate_af(tmp_peer, afi, + safi)); } } else { - ret |= non_peergroup_deactivate_af(peer, afi, safi); + SET_FLAG(ret, non_peergroup_deactivate_af(peer, afi, safi)); } bgp = peer->bgp; @@ -2930,9 +2931,9 @@ static void peer_group2peer_config_copy(struct peer_group *group, peer->gtsm_hops = conf->gtsm_hops; /* peer flags apply */ - flags_tmp = conf->flags & ~peer->flags_override; + flags_tmp = CHECK_FLAG(conf->flags, ~peer->flags_override); flags_tmp ^= conf->flags_invert ^ peer->flags_invert; - flags_tmp &= ~peer->flags_override; + UNSET_FLAG(flags_tmp, peer->flags_override); UNSET_FLAG(peer->flags, ~peer->flags_override); SET_FLAG(peer->flags, flags_tmp); @@ -4758,7 +4759,7 @@ static int peer_flag_action_set(const struct peer_flag_action *action_list, if (match->flag == 0) break; - if (match->flag & flag) { + if (CHECK_FLAG(match->flag, flag)) { found = 1; if (match->type == peer_change_reset_in) @@ -5085,15 +5086,17 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, ptype = peer_sort(peer); /* Special check for reflector client. */ - if (flag & PEER_FLAG_REFLECTOR_CLIENT && ptype != BGP_PEER_IBGP) + if (CHECK_FLAG(flag, PEER_FLAG_REFLECTOR_CLIENT) && + ptype != BGP_PEER_IBGP) return BGP_ERR_NOT_INTERNAL_PEER; /* Special check for remove-private-AS. */ - if (flag & PEER_FLAG_REMOVE_PRIVATE_AS && ptype == BGP_PEER_IBGP) + if (CHECK_FLAG(flag, PEER_FLAG_REMOVE_PRIVATE_AS) && + ptype == BGP_PEER_IBGP) return BGP_ERR_REMOVE_PRIVATE_AS; /* as-override is not allowed for IBGP peers */ - if (flag & PEER_FLAG_AS_OVERRIDE && ptype == BGP_PEER_IBGP) + if (CHECK_FLAG(flag, PEER_FLAG_AS_OVERRIDE) && ptype == BGP_PEER_IBGP) return BGP_ERR_AS_OVERRIDE; /* Handle flag updates where desired state matches current state. */ @@ -5144,7 +5147,7 @@ static int peer_af_flag_modify(struct peer *peer, afi_t afi, safi_t safi, * If the peer is a route server client let's not * muck with the nexthop on the way out the door */ - if (flag & PEER_FLAG_RSERVER_CLIENT) { + if (CHECK_FLAG(flag, PEER_FLAG_RSERVER_CLIENT)) { if (set) SET_FLAG(peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED); From ed832b70ec0ea7ad0cf22a844de2151592b5b0e8 Mon Sep 17 00:00:00 2001 From: Y Bharath Date: Mon, 22 Jul 2024 16:47:54 +0530 Subject: [PATCH 432/472] yang: Added missed prefix to the yang file Corrected warning by including the module Signed-off-by: y-bharath14 --- yang/ietf/frr-deviations-ietf-routing.yang | 3 +++ 1 file changed, 3 insertions(+) diff --git a/yang/ietf/frr-deviations-ietf-routing.yang b/yang/ietf/frr-deviations-ietf-routing.yang index 15ceb6b92918..5c0ae30beadc 100644 --- a/yang/ietf/frr-deviations-ietf-routing.yang +++ b/yang/ietf/frr-deviations-ietf-routing.yang @@ -6,6 +6,9 @@ module frr-deviations-ietf-routing { import ietf-routing { prefix ietf-routing; } + import ietf-rip { + prefix ietf-rip; + } organization "FRRouting"; From 7afd7d99f2fa39be073625c630d46f96e5dd66a5 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Mon, 22 Jul 2024 07:52:10 -0400 Subject: [PATCH 433/472] lib: move non-error from __log_err to __dbg Additionally, print `errmsg_if_any` in successful debug messages if non-NULL. fixes #16386 #16043 Signed-off-by: Christian Hopps --- lib/vty.c | 15 +++++++++------ mgmtd/mgmt_txn.c | 6 +++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/vty.c b/lib/vty.c index 0dcd118a97a0..ecb5383a53b2 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -3591,8 +3591,9 @@ static void vty_mgmt_set_config_result_notified( vty_out(vty, "%s\n", errmsg_if_any); } else { debug_fe_client("SET_CONFIG request for client 0x%" PRIx64 - " req-id %" PRIu64 " was successfull", - client_id, req_id); + " req-id %" PRIu64 " was successfull%s%s", + client_id, req_id, errmsg_if_any ? ": " : "", + errmsg_if_any ?: ""); } if (implicit_commit) { @@ -3624,8 +3625,9 @@ static void vty_mgmt_commit_config_result_notified( vty_out(vty, "%s\n", errmsg_if_any); } else { debug_fe_client("COMMIT_CONFIG request for client 0x%" PRIx64 - " req-id %" PRIu64 " was successfull", - client_id, req_id); + " req-id %" PRIu64 " was successfull%s%s", + client_id, req_id, errmsg_if_any ? ": " : "", + errmsg_if_any ?: ""); if (errmsg_if_any) vty_out(vty, "MGMTD: %s\n", errmsg_if_any); } @@ -3656,8 +3658,9 @@ static int vty_mgmt_get_data_result_notified( } debug_fe_client("GET_DATA request succeeded, client 0x%" PRIx64 - " req-id %" PRIu64, - client_id, req_id); + " req-id %" PRIu64 "%s%s", + client_id, req_id, errmsg_if_any ? ": " : "", + errmsg_if_any ?: ""); if (req_id != mgmt_last_req_id) { mgmt_last_req_id = req_id; diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c index 0a80b3bbf7f3..0f0cccbbd43a 100644 --- a/mgmtd/mgmt_txn.c +++ b/mgmtd/mgmt_txn.c @@ -980,8 +980,8 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req, } if (!chg_clients) - __log_err("No connected daemon is interested in XPATH %s", - xpath); + __dbg("Daemons interested in XPATH are not currently connected: %s", + xpath); cmtcfg_req->clients |= chg_clients; @@ -992,7 +992,7 @@ static int mgmt_txn_create_config_batches(struct mgmt_txn_req *txn_req, if (!num_chgs) { (void)mgmt_txn_send_commit_cfg_reply(txn_req->txn, MGMTD_NO_CFG_CHANGES, - "No changes found to commit!"); + "No connected daemons interested in changes"); return -1; } From 7b0b8a8b089d20841bde03eb009a7d1db929fa75 Mon Sep 17 00:00:00 2001 From: Jafar Al-Gharaibeh Date: Mon, 22 Jul 2024 11:19:50 -0500 Subject: [PATCH 434/472] pimd: fix compile warnings Signed-off-by: Jafar Al-Gharaibeh --- pimd/pim_cmd.c | 14 +++++++------- pimd/pim_cmd_common.c | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 2b8d3e56e521..92214eced4ae 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1457,7 +1457,7 @@ static void clear_interfaces(struct pim_instance *pim) static void pim_cli_legacy_mesh_group_behavior(struct vty *vty, const char *gname) { - char xpath_value[XPATH_MAXLEN]; + char xpath_value[XPATH_MAXLEN + 26]; char xpath_member_value[XPATH_MAXLEN]; const struct lyd_node *member_dnode; @@ -4314,7 +4314,7 @@ DEFPY (no_pim_ssm_prefix_list_name, "Name of a prefix-list\n") { const struct lyd_node *ssm_plist_dnode; - char ssm_plist_xpath[XPATH_MAXLEN]; + char ssm_plist_xpath[XPATH_MAXLEN + 16]; const char *ssm_plist_name; snprintf(ssm_plist_xpath, sizeof(ssm_plist_xpath), "%s/ssm-prefix-list", @@ -4350,7 +4350,7 @@ DEFPY_ATTR(no_ip_pim_ssm_prefix_list_name, CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) { const struct lyd_node *ssm_plist_dnode; - char ssm_plist_xpath[XPATH_MAXLEN]; + char ssm_plist_xpath[XPATH_MAXLEN + 16]; const char *ssm_plist_name; int ret = CMD_WARNING_CONFIG_FAILED; const char *vrfname; @@ -6574,7 +6574,7 @@ DEFPY(no_pim_msdp_mesh_group_member, "Mesh group member\n" "Peer IP address\n") { - char xpath_value[XPATH_MAXLEN]; + char xpath_value[XPATH_MAXLEN + 26]; char xpath_member_value[XPATH_MAXLEN]; /* Get mesh group base XPath. */ @@ -6620,7 +6620,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group_member, "Peer IP address\n", CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) { - char xpath_value[XPATH_MAXLEN]; + char xpath_value[XPATH_MAXLEN + 26]; char xpath_member_value[XPATH_MAXLEN]; int ret = CMD_WARNING_CONFIG_FAILED; const char *vrfname; @@ -6852,7 +6852,7 @@ DEFPY(no_pim_msdp_mesh_group, "Delete MSDP mesh-group\n" "Mesh group name\n") { - char xpath_value[XPATH_MAXLEN]; + char xpath_value[XPATH_MAXLEN + 26]; /* Get mesh group base XPath. */ snprintf(xpath_value, sizeof(xpath_value), @@ -6873,7 +6873,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group, "Mesh group name\n", CMD_ATTR_HIDDEN | CMD_ATTR_DEPRECATED) { - char xpath_value[XPATH_MAXLEN]; + char xpath_value[XPATH_MAXLEN + 26]; int ret = CMD_SUCCESS; const char *vrfname; char xpath[XPATH_MAXLEN]; diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c index c6cb28c097b9..d1368ff1ffe4 100644 --- a/pimd/pim_cmd_common.c +++ b/pimd/pim_cmd_common.c @@ -100,8 +100,8 @@ int pim_process_no_join_prune_cmd(struct vty *vty) int pim_process_spt_switchover_infinity_cmd(struct vty *vty) { - char spt_plist_xpath[XPATH_MAXLEN]; - char spt_action_xpath[XPATH_MAXLEN]; + char spt_plist_xpath[XPATH_MAXLEN + 40]; + char spt_action_xpath[XPATH_MAXLEN + 26]; snprintf(spt_plist_xpath, sizeof(spt_plist_xpath), "%s/spt-switchover/spt-infinity-prefix-list", VTY_CURR_XPATH); @@ -522,7 +522,7 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str, const char *group_str) { char group_xpath[XPATH_MAXLEN]; - char rp_xpath[XPATH_MAXLEN]; + char rp_xpath[XPATH_MAXLEN + 47]; int printed; const struct lyd_node *group_dnode; @@ -568,8 +568,8 @@ int pim_process_rp_plist_cmd(struct vty *vty, const char *rp_str, int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str, const char *prefix_list) { - char rp_xpath[XPATH_MAXLEN]; - char plist_xpath[XPATH_MAXLEN]; + char rp_xpath[XPATH_MAXLEN + 47]; + char plist_xpath[XPATH_MAXLEN + 1070]; const struct lyd_node *plist_dnode; const char *plist; From 40965e599975b019bbe6f4b1dfb3ff22d8980876 Mon Sep 17 00:00:00 2001 From: Rajasekar Raja Date: Mon, 22 Jul 2024 10:13:19 -0700 Subject: [PATCH 435/472] bgpd: backpressure - Avoid use after free Coverity complains there is a use after free (1598495 and 1598496) At this point, most likely dest->refcount cannot go 1 and free up the dest, but there might be some code path where this can happen. Fixing this with a simple order change (no harm fix). Ticket :#4001204 Signed-off-by: Rajasekar Raja --- bgpd/bgp_evpn.c | 2 +- bgpd/bgpd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index baf1d4ca6de7..7706a3eca41a 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -6339,9 +6339,9 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) dest = dest_next) { dest_next = zebra_announce_next(&bm->zebra_announce_head, dest); if (dest->za_vpn == vpn) { + zebra_announce_del(&bm->zebra_announce_head, dest); bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); - zebra_announce_del(&bm->zebra_announce_head, dest); } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index ec329d0c5487..043a6e201c17 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -3954,9 +3954,9 @@ int bgp_delete(struct bgp *bgp) dest_next = zebra_announce_next(&bm->zebra_announce_head, dest); dest_table = bgp_dest_table(dest); if (dest_table->bgp == bgp) { + zebra_announce_del(&bm->zebra_announce_head, dest); bgp_path_info_unlock(dest->za_bgp_pi); bgp_dest_unlock_node(dest); - zebra_announce_del(&bm->zebra_announce_head, dest); } } From 8916953b534f64a7545860ad5b4b36dc2544f33a Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Tue, 23 Jul 2024 10:21:42 -0700 Subject: [PATCH 436/472] build: fix a few python string escape warnings When using a regex (or anything that uses `\?` escapes) in python, raw strings (`r"content"`) should be used so python doesn't consume the escapes itself. Otherwise we get either broken behavior and/or `SyntaxWarning: invalid escape sequence '\['` Signed-off-by: David Lamparter --- doc/developer/conf.py | 2 +- doc/manpages/conf.py | 2 +- doc/user/conf.py | 2 +- python/firstheader.py | 2 +- python/makefile.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 6a3ffe16380e..76dd1e4f289e 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -96,7 +96,7 @@ # extract version information, installation location, other stuff we need to # use when building final documents -val = re.compile('^S\["([^"]+)"\]="(.*)"$') +val = re.compile(r'^S\["([^"]+)"\]="(.*)"$') try: with open("../../config.status", "r") as cfgstatus: for ln in cfgstatus.readlines(): diff --git a/doc/manpages/conf.py b/doc/manpages/conf.py index 73dea094ae9f..995885b22039 100644 --- a/doc/manpages/conf.py +++ b/doc/manpages/conf.py @@ -91,7 +91,7 @@ # extract version information, installation location, other stuff we need to # use when building final documents -val = re.compile('^S\["([^"]+)"\]="(.*)"$') +val = re.compile(r'^S\["([^"]+)"\]="(.*)"$') try: with open("../../config.status", "r") as cfgstatus: for ln in cfgstatus.readlines(): diff --git a/doc/user/conf.py b/doc/user/conf.py index 395875520d7f..18f048bc0836 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -96,7 +96,7 @@ # extract version information, installation location, other stuff we need to # use when building final documents -val = re.compile('^S\["([^"]+)"\]="(.*)"$') +val = re.compile(r'^S\["([^"]+)"\]="(.*)"$') try: with open("../../config.status", "r") as cfgstatus: for ln in cfgstatus.readlines(): diff --git a/python/firstheader.py b/python/firstheader.py index 06e28958452e..1a3cadfd5e89 100644 --- a/python/firstheader.py +++ b/python/firstheader.py @@ -15,7 +15,7 @@ argp.add_argument("--warn-empty", action="store_const", const=True) argp.add_argument("--pipe", action="store_const", const=True) -include_re = re.compile('^#\s*include\s+["<]([^ ">]+)[">]', re.M) +include_re = re.compile(r'^#\s*include\s+["<]([^ ">]+)[">]', re.M) ignore = [ lambda fn: fn.startswith("tools/"), diff --git a/python/makefile.py b/python/makefile.py index 573871fb68c7..45f032296f3b 100644 --- a/python/makefile.py +++ b/python/makefile.py @@ -91,7 +91,7 @@ autoderp = "#AUTODERP# " out_lines = [] bcdeps = [] -make_rule_re = re.compile("^([^:\s]+):\s*([^:\s]+)\s*($|\n)") +make_rule_re = re.compile(r"^([^:\s]+):\s*([^:\s]+)\s*($|\n)") while lines: line = lines.pop(0) From be9a6fc0ea8180a4aaa558c5402ea543427e2e7e Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Tue, 23 Jul 2024 17:42:07 -0400 Subject: [PATCH 437/472] lib: mgmtd: fix too early daemon detach of mgmtd Correct FRR startup counts on a daemon's vty socket to be open when the parent process exits. The parent process waits for `frr_check_detach()` to be called by the child before exiting. The problem is when the `FRR_MANUAL_VTY_START` flag is set the vty socket was not opened but `frr_check_detach()` was called anyway. Instead add a bool option for `frr_check_detach()` to be called when the socket is opened with `frr_vty_serv_start()`, and do so when "manually" calling said function (i.e., when FRR_MANUAL_VTY_START is set). The `FRR_MANUAL_VTY_START` flag is only set by mgmtd. The reason we wait to open the vty socket is so that mgmtd can parse the various daemon specific config files it has taken over, after the event loop has started, but before we receive any possible new config from `vtysh`. fixes #16362 Signed-off-by: Christian Hopps --- lib/libfrr.c | 30 +++++++++++++++++------------- lib/libfrr.h | 2 +- lib/vty.c | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/libfrr.c b/lib/libfrr.c index 338a7d0340f7..328c6ec8b21b 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -1051,7 +1051,17 @@ void frr_config_fork(void) zlog_tls_buffer_init(); } -void frr_vty_serv_start(void) +static void frr_check_detach(void) +{ + if (nodetach_term || nodetach_daemon) + return; + + if (daemon_ctl_sock != -1) + close(daemon_ctl_sock); + daemon_ctl_sock = -1; +} + +void frr_vty_serv_start(bool check_detach) { /* allow explicit override of vty_path in the future * (not currently set anywhere) */ @@ -1074,6 +1084,9 @@ void frr_vty_serv_start(void) } vty_serv_start(di->vty_addr, di->vty_port, di->vty_path); + + if (check_detach) + frr_check_detach(); } void frr_vty_serv_stop(void) @@ -1084,16 +1097,6 @@ void frr_vty_serv_stop(void) unlink(di->vty_path); } -static void frr_check_detach(void) -{ - if (nodetach_term || nodetach_daemon) - return; - - if (daemon_ctl_sock != -1) - close(daemon_ctl_sock); - daemon_ctl_sock = -1; -} - static void frr_terminal_close(int isexit) { int nullfd; @@ -1179,7 +1182,7 @@ void frr_run(struct event_loop *master) char instanceinfo[64] = ""; if (!(di->flags & FRR_MANUAL_VTY_START)) - frr_vty_serv_start(); + frr_vty_serv_start(false); if (di->instance) snprintf(instanceinfo, sizeof(instanceinfo), "instance %u ", @@ -1217,7 +1220,8 @@ void frr_run(struct event_loop *master) close(nullfd); } - frr_check_detach(); + if (!(di->flags & FRR_MANUAL_VTY_START)) + frr_check_detach(); } /* end fixed stderr startup logging */ diff --git a/lib/libfrr.h b/lib/libfrr.h index 8018672c1ae7..3248670c8348 100644 --- a/lib/libfrr.h +++ b/lib/libfrr.h @@ -202,7 +202,7 @@ extern void frr_config_fork(void); extern void frr_run(struct event_loop *master); extern void frr_detach(void); -extern void frr_vty_serv_start(void); +extern void frr_vty_serv_start(bool check_detach); extern void frr_vty_serv_stop(void); extern bool frr_zclient_addr(struct sockaddr_storage *sa, socklen_t *sa_len, diff --git a/lib/vty.c b/lib/vty.c index ecb5383a53b2..d0bbf0e61a5c 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -3502,7 +3502,7 @@ static void vty_mgmt_server_connected(struct mgmt_fe_client *client, /* Start or stop listening for vty connections */ if (connected) - frr_vty_serv_start(); + frr_vty_serv_start(true); else frr_vty_serv_stop(); } From 91e67abb610d6d39d304c24b2233a38b8c26e08a Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 24 Jul 2024 14:30:32 +0300 Subject: [PATCH 438/472] tests: Delay initial OPEN after we do `clear bgp` Under some circumstances it might happen that the session is quickly UP in the middle of `clear bgp ...` and `shutdown`. That leads to session be UP, and the stale routes being cleared quickly. Signed-off-by: Donatas Abraitis --- tests/topotests/bgp_gr_notification/r1/bgpd.conf | 2 +- tests/topotests/bgp_gr_notification/r2/bgpd.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/topotests/bgp_gr_notification/r1/bgpd.conf b/tests/topotests/bgp_gr_notification/r1/bgpd.conf index 6119f6743629..0af042f6be59 100644 --- a/tests/topotests/bgp_gr_notification/r1/bgpd.conf +++ b/tests/topotests/bgp_gr_notification/r1/bgpd.conf @@ -3,7 +3,7 @@ router bgp 65001 bgp graceful-restart neighbor 192.168.255.2 remote-as external neighbor 192.168.255.2 timers 1 3 - neighbor 192.168.255.2 timers connect 1 + neighbor 192.168.255.2 timers delayopen 10 address-family ipv4 redistribute connected exit-address-family diff --git a/tests/topotests/bgp_gr_notification/r2/bgpd.conf b/tests/topotests/bgp_gr_notification/r2/bgpd.conf index 05e17f056488..8325e21d2c1e 100644 --- a/tests/topotests/bgp_gr_notification/r2/bgpd.conf +++ b/tests/topotests/bgp_gr_notification/r2/bgpd.conf @@ -4,7 +4,7 @@ router bgp 65002 bgp graceful-restart neighbor 192.168.255.1 remote-as external neighbor 192.168.255.1 timers 1 3 - neighbor 192.168.255.1 timers connect 1 + neighbor 192.168.255.1 timers delayopen 10 address-family ipv4 redistribute connected exit-address-family From 45f80de734db1ecc677096f743d0f8cacdb6528d Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Wed, 24 Jul 2024 15:30:43 +0300 Subject: [PATCH 439/472] bgpd: Pass a connection struct directly for EVENT_OFF() Signed-off-by: Donatas Abraitis --- bgpd/bgp_fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 76624fee9e43..b67cf3b8743e 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -1482,7 +1482,7 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) EVENT_OFF(connection->t_connect); EVENT_OFF(connection->t_holdtime); EVENT_OFF(connection->t_routeadv); - EVENT_OFF(peer->connection->t_delayopen); + EVENT_OFF(connection->t_delayopen); /* Clear input and output buffer. */ frr_with_mutex (&connection->io_mtx) { From 0a68626e48e0786c043562bb029e99f69b43fb6d Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:38:04 +0200 Subject: [PATCH 440/472] zebra: Remove duplicate `#include ` Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index e82b781c6fea..0ea2ba3dac7a 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include From c432aa0bb4f8c3f4e2b75c23dfb017e7250c934f Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:38:27 +0200 Subject: [PATCH 441/472] zebra: Remove duplicate `#include ` Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 0ea2ba3dac7a..4e0cc8d1474d 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include From 22aa0ffb81762f3b58e10cba6fd86f2843c1d844 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:38:55 +0200 Subject: [PATCH 442/472] zebra: Remove duplicate `#include ` Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index 4e0cc8d1474d..d305e5ce1b58 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -20,7 +20,6 @@ #include "zebra/ge_netlink.h" #include #include -#include #include #include From 4ca8332922ce6242a926439349c6796c0cb76e67 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:39:14 +0200 Subject: [PATCH 443/472] zebra: Remove duplicate `#include ` Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index d305e5ce1b58..d0892aba0316 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -19,7 +19,6 @@ #include "zebra/zebra_errors.h" #include "zebra/ge_netlink.h" #include -#include #include #include From 8b206b0cd7067ada1206e5733d1972309d55c33e Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:39:34 +0200 Subject: [PATCH 444/472] zebra: Remove duplicate `#include ` Signed-off-by: Carmine Scarpitta --- zebra/zebra_srv6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c index d0892aba0316..082d4609aacd 100644 --- a/zebra/zebra_srv6.c +++ b/zebra/zebra_srv6.c @@ -18,7 +18,6 @@ #include "zebra/zebra_srv6.h" #include "zebra/zebra_errors.h" #include "zebra/ge_netlink.h" -#include #include #include From bcf7bc1ce8f93505a52c39d914a0916ffdcf4d2f Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:41:09 +0200 Subject: [PATCH 445/472] zebra: Remove duplicate `#include "zebra/debug.h"` Signed-off-by: Carmine Scarpitta --- zebra/dplane_fpm_nl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 28c481d1d873..f6c20fdad867 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -42,7 +42,6 @@ #include "zebra/zebra_evpn_mac.h" #include "zebra/kernel_netlink.h" #include "zebra/rt_netlink.h" -#include "zebra/debug.h" #include "fpm/fpm.h" #include "zebra/dplane_fpm_nl_clippy.c" From e2cb3ab5c6d3c512b853fffe1b986dc0aa40e9b0 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:41:29 +0200 Subject: [PATCH 446/472] zebra: Remove duplicate `#include "zebra/interface.h"` Signed-off-by: Carmine Scarpitta --- zebra/dplane_fpm_nl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index f6c20fdad867..09080aa6164d 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -36,7 +36,6 @@ #include "zebra/zebra_dplane.h" #include "zebra/zebra_mpls.h" #include "zebra/zebra_router.h" -#include "zebra/interface.h" #include "zebra/zebra_vxlan_private.h" #include "zebra/zebra_evpn.h" #include "zebra/zebra_evpn_mac.h" From 846bbcba0d3496d66b5b03625022634c87d88568 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 24 Jul 2024 23:50:02 +0200 Subject: [PATCH 447/472] zebra: Remove duplicate `#include "zebra/interface.h"` Signed-off-by: Carmine Scarpitta --- zebra/interface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/zebra/interface.c b/zebra/interface.c index b3adc4483ee9..03b710e1a0f9 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -32,7 +32,6 @@ #include "zebra/zebra_ptm.h" #include "zebra/rt_netlink.h" #include "zebra/if_netlink.h" -#include "zebra/interface.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_errors.h" #include "zebra/zebra_evpn_mh.h" From 7b91b0b3caa4ce3dc05e454c3bc7ea5494ed4519 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 25 Jul 2024 11:52:45 +0300 Subject: [PATCH 448/472] doc: Add RFC 5701 to the supported RFCs list Signed-off-by: Donatas Abraitis --- doc/user/about.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/user/about.rst b/doc/user/about.rst index 7d30a86154a0..ba80a324d3bb 100644 --- a/doc/user/about.rst +++ b/doc/user/about.rst @@ -323,6 +323,8 @@ BGP :t:`Dissemination of Flow Specification Rules. P. Marques, N. Sheth, R. Raszuk, B. Greene, J. Mauch, D. McPherson. August 2009.` - :rfc:`5668` :t:`4-Octet AS Specific BGP Extended Community. Y. Rekhter, S. Sangli, D. Tappan October 2009.` +- :rfc:`5701` + :t:`IPv6 Address Specific BGP Extended Community Attribute. Y. Rekhter. 2009.` - :rfc:`6286` :t:`Autonomous-System-Wide Unique BGP Identifier for BGP-4. E. Chen, J. Yuan. June 2011.` - :rfc:`6472` From 743b16938455efd44f6e59b42d8800c3881f9889 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 25 Jul 2024 13:06:46 +0300 Subject: [PATCH 449/472] bgpd: Set the last_reset if we change the password also ``` donatas.net(config-router)# do show ip bgp summary failed IPv4 Unicast Summary: BGP router identifier 1.1.1.1, local AS number 65001 VRF default vrf-id 0 BGP table version 0 RIB entries 0, using 0 bytes of memory Peers 1, using 24 KiB of memory Neighbor EstdCnt DropCnt ResetTime Reason 127.0.0.1 2 2 00:02:02 Password config change (GoBGP/3.26.0) Displayed neighbors 1 Total number of neighbors 1 ``` Signed-off-by: Donatas Abraitis --- bgpd/bgp_fsm.c | 1 + bgpd/bgpd.c | 2 ++ bgpd/bgpd.h | 1 + 3 files changed, 4 insertions(+) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index b67cf3b8743e..e911c2d18ecb 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -602,6 +602,7 @@ const char *const peer_down_str[] = { "Socket Error", "Admin. shutdown (RTT)", "Suppress Fib Turned On or Off", + "Password config change", }; static void bgp_graceful_restart_timer_off(struct peer_connection *connection, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 043a6e201c17..a59a9b6b0f0b 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -6790,6 +6790,7 @@ int peer_password_set(struct peer *peer, const char *password) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + peer->last_reset = PEER_DOWN_PASSWORD_CHANGE; /* Send notification or reset peer depending on state. */ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, @@ -6827,6 +6828,7 @@ int peer_password_set(struct peer *peer, const char *password) XFREE(MTYPE_PEER_PASSWORD, member->password); member->password = XSTRDUP(MTYPE_PEER_PASSWORD, password); + member->last_reset = PEER_DOWN_PASSWORD_CHANGE; /* Send notification or reset peer depending on state. */ if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 95ddba4cddf0..6e6358bac78b 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1819,6 +1819,7 @@ struct peer { #define PEER_DOWN_SOCKET_ERROR 34U /* Some socket error happened */ #define PEER_DOWN_RTT_SHUTDOWN 35U /* Automatically shutdown due to RTT */ #define PEER_DOWN_SUPPRESS_FIB_PENDING 36U /* Suppress fib pending changed */ +#define PEER_DOWN_PASSWORD_CHANGE 37U /* neighbor password command */ /* * Remember to update peer_down_str in bgp_fsm.c when you add * a new value to the last_reset reason From fa9bd07ae5e93479ff4e7b81791393ab883cc722 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 25 Jul 2024 13:22:27 +0300 Subject: [PATCH 450/472] bgpd: Keep the last reset reason before we reset the peer If we send a notification, there is no point setting the last_reset, because bgp_notify_send() sets last_reset to PEER_DOWN_NOTIFY_SEND (almost everywhere). Signed-off-by: Donatas Abraitis --- bgpd/bgp_fsm.c | 14 +++--- bgpd/bgp_vty.c | 17 ++++--- bgpd/bgpd.c | 121 ++++++++++++++++++++++++------------------------- 3 files changed, 75 insertions(+), 77 deletions(-) diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index e911c2d18ecb..1eeb14115519 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -2740,14 +2740,15 @@ static void bgp_gr_update_mode_of_all_peers(struct bgp *bgp, peer, peer->peer_gr_new_status_flag, peer->flags); + peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; + /* Reset session to match with behavior for other peer * configs that require the session to be re-setup. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(peer); } } @@ -2968,14 +2969,15 @@ unsigned int bgp_peer_gr_action(struct peer *peer, enum peer_mode old_state, bgp_peer_move_to_gr_mode(peer, new_state); if (session_reset) { + peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; + /* Reset session to match with behavior for other peer * configs that require the session to be re-setup. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(peer); } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index bce820237792..1ecbba0ab5c5 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2928,11 +2928,10 @@ DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd, * with aspath containing AS_SET or AS_CONFED_SET. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_AS_SETS_REJECT; + peer->last_reset = PEER_DOWN_AS_SETS_REJECT; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } } return CMD_SUCCESS; @@ -2954,11 +2953,10 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd, * with aspath containing AS_SET or AS_CONFED_SET. */ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_AS_SETS_REJECT; + peer->last_reset = PEER_DOWN_AS_SETS_REJECT; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } } return CMD_SUCCESS; @@ -5107,12 +5105,13 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if, else peer_flag_unset(peer, PEER_FLAG_IFPEER_V6ONLY); + peer->last_reset = PEER_DOWN_V6ONLY_CHANGE; + /* v6only flag changed. Reset bgp seesion */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_V6ONLY_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(peer); } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index a59a9b6b0f0b..b32a4640f02b 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -306,11 +306,11 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id, for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { IPV4_ADDR_COPY(&peer->local_id, id); - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_RID_CHANGE; + peer->last_reset = PEER_DOWN_RID_CHANGE; + + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } } /* EVPN uses router id in RD, update them */ @@ -440,11 +440,12 @@ void bm_wait_for_fib_set(bool set) */ for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, bgp)) { for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + peer->last_reset = PEER_DOWN_SUPPRESS_FIB_PENDING; + if (!BGP_IS_VALID_STATE_FOR_NOTIF( peer->connection->status)) continue; - peer->last_reset = PEER_DOWN_SUPPRESS_FIB_PENDING; bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } @@ -496,10 +497,11 @@ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set) * let's just start over */ for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + peer->last_reset = PEER_DOWN_SUPPRESS_FIB_PENDING; + if (!BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) continue; - peer->last_reset = PEER_DOWN_SUPPRESS_FIB_PENDING; bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } @@ -523,11 +525,11 @@ void bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id) if (peer->sort != BGP_PEER_IBGP) continue; - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_CLID_CHANGE; + peer->last_reset = PEER_DOWN_CLID_CHANGE; + + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } } } @@ -547,11 +549,11 @@ void bgp_cluster_id_unset(struct bgp *bgp) if (peer->sort != BGP_PEER_IBGP) continue; - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_CLID_CHANGE; + peer->last_reset = PEER_DOWN_CLID_CHANGE; + + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } } } @@ -676,14 +678,12 @@ void bgp_confederation_id_unset(struct bgp *bgp) /* We're looking for peers who's AS is not local */ if (peer_sort(peer) != BGP_PEER_IBGP) { peer->local_as = bgp->as; + peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; if (BGP_IS_VALID_STATE_FOR_NOTIF( - peer->connection->status)) { - peer->last_reset = PEER_DOWN_CONFED_ID_CHANGE; + peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } - else bgp_session_reset_safe(peer, &nnode); } @@ -2091,11 +2091,11 @@ void peer_as_change(struct peer *peer, as_t as, enum peer_asn_type as_type, /* Stop peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE; + peer->last_reset = PEER_DOWN_REMOTE_AS_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(peer); } origtype = peer_sort_lookup(peer); @@ -2446,6 +2446,8 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) if (!active && peer_active(peer)) { bgp_timer_set(peer->connection); } else { + peer->last_reset = PEER_DOWN_AF_ACTIVATE; + if (peer_established(peer->connection)) { if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) { peer->afc_adv[afi][safi] = 1; @@ -2458,18 +2460,15 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) false); } } else { - peer->last_reset = PEER_DOWN_AF_ACTIVATE; bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } if (peer->connection->status == OpenSent || - peer->connection->status == OpenConfirm) { - peer->last_reset = PEER_DOWN_AF_ACTIVATE; + peer->connection->status == OpenConfirm) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } /* * If we are turning on a AFI/SAFI locally and we've * started bringing a peer up, we need to tell @@ -2481,11 +2480,9 @@ static int peer_activate_af(struct peer *peer, afi_t afi, safi_t safi) */ other = peer->doppelganger; if (other && (other->connection->status == OpenSent || - other->connection->status == OpenConfirm)) { - other->last_reset = PEER_DOWN_AF_ACTIVATE; + other->connection->status == OpenConfirm)) bgp_notify_send(other->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } } return 0; @@ -2579,6 +2576,8 @@ static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi, } if (peer_established(peer->connection)) { + peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; + if (CHECK_FLAG(peer->cap, PEER_CAP_DYNAMIC_RCV)) { peer->afc_adv[afi][safi] = 0; peer->afc_nego[afi][safi] = 0; @@ -2590,13 +2589,11 @@ static bool non_peergroup_deactivate_af(struct peer *peer, afi_t afi, bgp_clear_route(peer, afi, safi); peer->pcount[afi][safi] = 0; } else { - peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } } else { - peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } @@ -3346,13 +3343,13 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer, SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE); - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_RMAP_BIND; + peer->last_reset = PEER_DOWN_RMAP_BIND; + + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else { + else bgp_session_reset(peer); - } } /* Create a new peer. */ @@ -4790,6 +4787,13 @@ static int peer_flag_action_set(const struct peer_flag_action *action_list, static void peer_flag_modify_action(struct peer *peer, uint64_t flag) { + if (flag == PEER_FLAG_DYNAMIC_CAPABILITY) + peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; + else if (flag == PEER_FLAG_PASSIVE) + peer->last_reset = PEER_DOWN_PASSIVE_CHANGE; + else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK) + peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE; + if (flag == PEER_FLAG_SHUTDOWN) { if (CHECK_FLAG(peer->flags, flag)) { if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) @@ -4838,13 +4842,6 @@ static void peer_flag_modify_action(struct peer *peer, uint64_t flag) BGP_EVENT_ADD(peer->connection, BGP_Stop); } } else if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - if (flag == PEER_FLAG_DYNAMIC_CAPABILITY) - peer->last_reset = PEER_DOWN_CAPABILITY_CHANGE; - else if (flag == PEER_FLAG_PASSIVE) - peer->last_reset = PEER_DOWN_PASSIVE_CHANGE; - else if (flag == PEER_FLAG_DISABLE_CONNECTED_CHECK) - peer->last_reset = PEER_DOWN_MULTIHOP_CHANGE; - bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); } else @@ -5564,12 +5561,12 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(peer); /* Apply new source configuration to BFD session. */ @@ -5601,13 +5598,13 @@ int peer_update_source_if_set(struct peer *peer, const char *ifname) member->update_if = XSTRDUP(MTYPE_PEER_UPDATE_SOURCE, ifname); sockunion_free(member->update_source); member->update_source = NULL; + member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { - member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(member); /* Apply new source configuration to BFD session. */ @@ -5635,12 +5632,12 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(peer); /* Apply new source configuration to BFD session. */ @@ -5671,13 +5668,13 @@ void peer_update_source_addr_set(struct peer *peer, const union sockunion *su) SET_FLAG(member->flags, PEER_FLAG_UPDATE_SOURCE); member->update_source = sockunion_dup(su); XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if); + member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { - member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(member); /* Apply new source configuration to BFD session. */ @@ -5723,12 +5720,12 @@ void peer_update_source_unset(struct peer *peer) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(peer); /* Apply new source configuration to BFD session. */ @@ -5758,13 +5755,13 @@ void peer_update_source_unset(struct peer *peer) sockunion_free(member->update_source); member->update_source = NULL; XFREE(MTYPE_PEER_UPDATE_SOURCE, member->update_if); + member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { - member->last_reset = PEER_DOWN_UPDATE_SOURCE_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(member); /* Apply new source configuration to BFD session. */ @@ -6730,12 +6727,12 @@ int peer_local_as_unset(struct peer *peer) /* Check if handling a regular peer. */ if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { + peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; /* Send notification or stop peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) { - peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->connection->status)) bgp_notify_send(peer->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else BGP_EVENT_ADD(peer->connection, BGP_Stop); /* Skip peer-group mechanics for regular peers. */ @@ -6757,13 +6754,13 @@ int peer_local_as_unset(struct peer *peer) UNSET_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS); member->change_local_as = 0; XFREE(MTYPE_BGP_NAME, member->change_local_as_pretty); + member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; /* Send notification or stop peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) { - member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; + if (BGP_IS_VALID_STATE_FOR_NOTIF(member->connection->status)) bgp_notify_send(member->connection, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else + else bgp_session_reset(member); } From b1b1c922a519af3c2af1eed5790ec6ac7fe27da5 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 25 Jul 2024 13:41:23 +0300 Subject: [PATCH 451/472] bgpd: Do not increment treat-as-withdraw counters if debug is enabled Increment only if we really treat the UPDATE as withdrawn. Signed-off-by: Donatas Abraitis --- bgpd/bgp_packet.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 0fb59a94c283..842fd1734ad3 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -2390,13 +2390,13 @@ static int bgp_update_receive(struct peer_connection *connection, ret = bgp_dump_attr(&attr, peer->rcvd_attr_str, sizeof(peer->rcvd_attr_str)); - peer->stat_upd_7606++; - - if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW) + if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW) { + peer->stat_upd_7606++; flog_err( EC_BGP_UPDATE_RCV, "%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route.", peer); + } if (ret && bgp_debug_update(peer, NULL, NULL, 1) && BGP_DEBUG(update, UPDATE_DETAIL)) { From c4b4c242ec8cfcdb23f0f90faaa0ff76577e1364 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 25 Jul 2024 07:50:32 -0400 Subject: [PATCH 452/472] pimd: Fix msdp setting of sa->rp The code is clearly incorrect. After consultation with the original author this is the decided change. Signed-off-by: Donald Sharp --- pimd/pim_msdp.c | 8 +++----- tests/topotests/msdp_topo1/test_msdp_topo1.py | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 623c14bb0391..ea8c84cca556 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -411,12 +411,10 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp, pim_addr_to_prefix(&grp, sa->sg.grp); rp_info = pim_rp_find_match_group(pim, &grp); if (rp_info) { - sa->rp = rp_info->rp.rpf_addr; - } else - { - sa->rp = pim->msdp.originator_id; + sa->rp = rp_info->rp.rpf_addr; + } else { + sa->rp = pim->msdp.originator_id; } - sa->rp = pim->msdp.originator_id; pim_msdp_pkt_sa_tx_one(sa); } sa->flags &= ~PIM_MSDP_SAF_STALE; diff --git a/tests/topotests/msdp_topo1/test_msdp_topo1.py b/tests/topotests/msdp_topo1/test_msdp_topo1.py index 08c37617cf76..4b54ef29ffc4 100755 --- a/tests/topotests/msdp_topo1/test_msdp_topo1.py +++ b/tests/topotests/msdp_topo1/test_msdp_topo1.py @@ -359,7 +359,7 @@ def test_msdp(): "192.168.10.100": { "source": "192.168.10.100", "group": "229.1.2.3", - "rp": "192.168.1.1", + "rp": "10.254.254.1", "local": "no", "sptSetup": "no", } @@ -394,7 +394,7 @@ def test_msdp(): "192.168.10.100": { "source": "192.168.10.100", "group": "229.1.2.3", - "rp": "192.168.1.1", + "rp": "10.254.254.1", "local": "no", "sptSetup": "yes", } From 968ae852523381cf727a6491c5e22a02a5de8077 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Thu, 25 Jul 2024 15:07:57 +0300 Subject: [PATCH 453/472] bgpd: Show software version in bgp summary E.g.: ``` $ vtysh -c 'show bgp summary json' | jq '.ipv4Unicast.peers' { "127.0.0.1": { "hostname": "donatas.net", "softwareVersion": "GoBGP/3.26.0", "remoteAs": 65001, "localAs": 65001, "version": 4, "msgRcvd": 12, "msgSent": 16, "tableVersion": 0, "outq": 0, "inq": 0, "peerUptime": "00:00:10", "peerUptimeMsec": 10000, "peerUptimeEstablishedEpoch": 1721908563, "pfxRcd": 0, "pfxSnt": 0, "state": "Established", "peerState": "OK", "connectionsEstablished": 1, "connectionsDropped": 0, "idType": "ipv4" }, "127.0.0.3": { "hostname": "putin-xujlo", "domainname": "donatas.net", "softwareVersion": "ExaBGP/5.0.0-20240725+main-a56c70e84a", "remoteAs": 65003, "localAs": 65001, "version": 4, "msgRcvd": 3, "msgSent": 7, "tableVersion": 0, "outq": 0, "inq": 0, "peerUptime": "00:00:13", "peerUptimeMsec": 13000, "peerUptimeEstablishedEpoch": 1721908560, "pfxRcd": 0, "pfxSnt": 0, "state": "Established", "peerState": "OK", "connectionsEstablished": 1, "connectionsDropped": 0, "idType": "ipv4" } } ``` Signed-off-by: Donatas Abraitis --- bgpd/bgp_vty.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index bce820237792..2c02abd0d8fd 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -12329,6 +12329,12 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_string_add(json_peer, "domainname", peer->domainname); + json_object_string_add(json_peer, + "softwareVersion", + peer->soft_version + ? peer->soft_version + : "n/a"); + asn_asn2json(json_peer, "remoteAs", peer->as, bgp->asnotation); asn_asn2json(json_peer, "localAs", From 88a9aa9c6bec8049b36212fa3eb48b357b03b83a Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Tue, 16 Jul 2024 15:50:16 -0300 Subject: [PATCH 454/472] bfdd: remove control socket obsolete code Let's remove the obsolete BFD control socket. If the functionality is needed then YANG/northbound notifications / getting should be used instead. Signed-off-by: Rafael Zalamena --- bfdd/bfd.c | 78 +-- bfdd/bfd.h | 158 +++--- bfdd/bfdctl.h | 157 ------ bfdd/bfdd.c | 27 +- bfdd/bfdd_vty.c | 15 +- bfdd/config.c | 592 ----------------------- bfdd/control.c | 844 --------------------------------- bfdd/dplane.c | 2 +- bfdd/ptm_adapter.c | 9 +- bfdd/subdir.am | 3 - snapcraft/scripts/bfdd-service | 3 +- snapcraft/snapcraft.yaml.in | 2 +- 12 files changed, 78 insertions(+), 1812 deletions(-) delete mode 100644 bfdd/bfdctl.h delete mode 100644 bfdd/config.c delete mode 100644 bfdd/control.c diff --git a/bfdd/bfd.c b/bfdd/bfd.c index b6b437a7919c..eb9c3003135f 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -256,19 +256,8 @@ void gen_bfd_key(struct bfd_key *key, struct sockaddr_any *peer, struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc) { - struct bfd_session *bs; - struct peer_label *pl; struct bfd_key key; - /* Try to find label first. */ - if (bpc->bpc_has_label) { - pl = pl_find(bpc->bpc_label); - if (pl != NULL) { - bs = pl->pl_bs; - return bs; - } - } - /* Otherwise fallback to peer/local hash lookup. */ gen_bfd_key(&key, &bpc->bpc_peer, &bpc->bpc_local, bpc->bpc_mhop, bpc->bpc_localif, bpc->bpc_vrfname); @@ -327,10 +316,8 @@ int bfd_session_enable(struct bfd_session *bs) bs->ifp = ifp; /* Attempt to use data plane. */ - if (bglobal.bg_use_dplane && bfd_dplane_add_session(bs) == 0) { - control_notify_config(BCM_NOTIFY_CONFIG_ADD, bs); + if (bglobal.bg_use_dplane && bfd_dplane_add_session(bs) == 0) return 0; - } /* Sanity check: don't leak open sockets. */ if (bs->sock != -1) { @@ -502,7 +489,7 @@ void ptm_bfd_sess_up(struct bfd_session *bfd) /* Start sending control packets with poll bit immediately. */ ptm_bfd_snd(bfd, 0); - control_notify(bfd, bfd->ses_state); + ptm_bfd_notify(bfd, bfd->ses_state); if (old_state != bfd->ses_state) { bfd->stats.session_up++; @@ -538,7 +525,7 @@ void ptm_bfd_sess_dn(struct bfd_session *bfd, uint8_t diag) /* only signal clients when going from up->down state */ if (old_state == PTM_BFD_UP) - control_notify(bfd, PTM_BFD_DOWN); + ptm_bfd_notify(bfd, PTM_BFD_DOWN); /* Stop echo packet transmission if they are active */ if (CHECK_FLAG(bfd->flags, BFD_SESS_FLAG_ECHO_ACTIVE)) @@ -690,38 +677,6 @@ struct bfd_session *bfd_session_new(void) return bs; } -int bfd_session_update_label(struct bfd_session *bs, const char *nlabel) -{ - /* New label treatment: - * - Check if the label is taken; - * - Try to allocate the memory for it and register; - */ - if (bs->pl == NULL) { - if (pl_find(nlabel) != NULL) { - /* Someone is already using it. */ - return -1; - } - - pl_new(nlabel, bs); - - return 0; - } - - /* - * Test label change consistency: - * - Do nothing if it's the same label; - * - Check if the future label is already taken; - * - Change label; - */ - if (strcmp(nlabel, bs->pl->pl_label) == 0) - return -1; - if (pl_find(nlabel) != NULL) - return -1; - - strlcpy(bs->pl->pl_label, nlabel, sizeof(bs->pl->pl_label)); - return 0; -} - static void _bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc) { @@ -750,9 +705,6 @@ static void _bfd_session_update(struct bfd_session *bs, bs->peer_profile.min_echo_tx = bs->timers.desired_min_echo_tx; } - if (bpc->bpc_has_label) - bfd_session_update_label(bs, bpc->bpc_label); - if (bpc->bpc_cbit) SET_FLAG(bs->flags, BFD_SESS_FLAG_CBIT); else @@ -792,8 +744,6 @@ static int bfd_session_update(struct bfd_session *bs, struct bfd_peer_cfg *bpc) _bfd_session_update(bs, bpc); - control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs); - return 0; } @@ -819,8 +769,6 @@ void bfd_session_free(struct bfd_session *bs) if (bso != NULL) bs_observer_del(bso); - pl_free(bs->pl); - XFREE(MTYPE_BFDD_PROFILE, bs->profile_name); XFREE(MTYPE_BFDD_CONFIG, bs); } @@ -917,8 +865,6 @@ struct bfd_session *bs_registrate(struct bfd_session *bfd) if (bglobal.debug_peer_event) zlog_debug("session-new: %s", bs_to_string(bfd)); - control_notify_config(BCM_NOTIFY_CONFIG_ADD, bfd); - return bfd; } @@ -941,8 +887,6 @@ int ptm_bfd_sess_del(struct bfd_peer_cfg *bpc) if (bglobal.debug_peer_event) zlog_debug("%s: %s", __func__, bs_to_string(bs)); - control_notify_config(BCM_NOTIFY_CONFIG_DELETE, bs); - bfd_session_free(bs); return 0; @@ -1166,11 +1110,8 @@ void bs_final_handler(struct bfd_session *bs) * When using demand mode we must disable the detection timer * for lost control packets. */ - if (bs->demand_mode) { - /* Notify watchers about changed timers. */ - control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs); + if (bs->demand_mode) return; - } /* * Calculate transmission time based on new timers. @@ -1189,9 +1130,6 @@ void bs_final_handler(struct bfd_session *bs) /* Apply new transmission timer immediately. */ ptm_bfd_start_xmt_timer(bs, false); - - /* Notify watchers about changed timers. */ - control_notify_config(BCM_NOTIFY_CONFIG_UPDATE, bs); } void bs_set_slow_timers(struct bfd_session *bs) @@ -1261,7 +1199,7 @@ void bfd_set_shutdown(struct bfd_session *bs, bool shutdown) if (bs->bdc) { bs->ses_state = PTM_BFD_ADM_DOWN; bfd_dplane_update_session(bs); - control_notify(bs, bs->ses_state); + ptm_bfd_notify(bs, bs->ses_state); return; } @@ -1273,7 +1211,7 @@ void bfd_set_shutdown(struct bfd_session *bs, bool shutdown) /* Change and notify state change. */ bs->ses_state = PTM_BFD_ADM_DOWN; - control_notify(bs, bs->ses_state); + ptm_bfd_notify(bs, bs->ses_state); /* Don't try to send packets with a disabled session. */ if (bs->sock != -1) @@ -1289,13 +1227,13 @@ void bfd_set_shutdown(struct bfd_session *bs, bool shutdown) if (bs->bdc) { bs->ses_state = PTM_BFD_DOWN; bfd_dplane_update_session(bs); - control_notify(bs, bs->ses_state); + ptm_bfd_notify(bs, bs->ses_state); return; } /* Change and notify state change. */ bs->ses_state = PTM_BFD_DOWN; - control_notify(bs, bs->ses_state); + ptm_bfd_notify(bs, bs->ses_state); /* Enable timers if non passive, otherwise stop them. */ if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_PASSIVE)) { diff --git a/bfdd/bfd.h b/bfdd/bfd.h index be04e655abf0..2f83b245eb28 100644 --- a/bfdd/bfd.h +++ b/bfdd/bfd.h @@ -20,19 +20,73 @@ #include "lib/queue.h" #include "lib/vrf.h" -#include "bfdctl.h" - #ifdef BFD_DEBUG #define BFDD_JSON_CONV_OPTIONS (JSON_C_TO_STRING_PRETTY) #else #define BFDD_JSON_CONV_OPTIONS (0) #endif +#ifndef MAXNAMELEN +#define MAXNAMELEN 32 +#endif + +#define BPC_DEF_DETECTMULTIPLIER 3 +#define BPC_DEF_RECEIVEINTERVAL 300 /* milliseconds */ +#define BPC_DEF_TRANSMITINTERVAL 300 /* milliseconds */ +#define BPC_DEF_ECHORECEIVEINTERVAL 50 /* milliseconds */ +#define BPC_DEF_ECHOTRANSMITINTERVAL 50 /* milliseconds */ + DECLARE_MGROUP(BFDD); -DECLARE_MTYPE(BFDD_CONTROL); -DECLARE_MTYPE(BFDD_NOTIFICATION); +DECLARE_MTYPE(BFDD_CLIENT); +DECLARE_MTYPE(BFDD_CLIENT_NOTIFICATION); + +struct sockaddr_any { + union { + struct sockaddr_in sa_sin; + struct sockaddr_in6 sa_sin6; + }; +}; + +struct bfd_peer_cfg { + bool bpc_mhop; + bool bpc_ipv4; + struct sockaddr_any bpc_peer; + struct sockaddr_any bpc_local; + + bool bpc_has_localif; + char bpc_localif[MAXNAMELEN + 1]; + + bool bpc_has_vrfname; + char bpc_vrfname[MAXNAMELEN + 1]; + + bool bpc_has_detectmultiplier; + uint8_t bpc_detectmultiplier; + + bool bpc_has_recvinterval; + uint64_t bpc_recvinterval; + + bool bpc_has_txinterval; + uint64_t bpc_txinterval; -#define BFDD_SOCK_NAME "%s/bfdd.sock", frr_runstatedir + bool bpc_has_echorecvinterval; + uint64_t bpc_echorecvinterval; + + bool bpc_has_echotxinterval; + uint64_t bpc_echotxinterval; + + bool bpc_has_minimum_ttl; + uint8_t bpc_minimum_ttl; + + bool bpc_echo; + bool bpc_createonly; + bool bpc_shutdown; + + bool bpc_cbit; + bool bpc_passive; + + bool bpc_has_profile; + char bpc_profile[64]; +}; /* bfd Authentication Type. */ #define BFD_AUTH_NULL 0 @@ -246,9 +300,6 @@ struct bfd_profile { /** Profile list type. */ TAILQ_HEAD(bfdproflist, bfd_profile); -/* bfd_session shortcut label forwarding. */ -struct peer_label; - struct bfd_config_timers { uint32_t desired_min_tx; uint32_t required_min_rx; @@ -326,14 +377,6 @@ struct bfd_session { uint64_t rtt[BFD_RTT_SAMPLE]; /* RRT in usec for echo to be looped */ }; -struct peer_label { - TAILQ_ENTRY(peer_label) pl_entry; - - struct bfd_session *pl_bs; - char pl_label[MAXNAMELEN]; -}; -TAILQ_HEAD(pllist, peer_label); - struct bfd_diag_str_list { const char *str; int type; @@ -385,64 +428,6 @@ TAILQ_HEAD(obslist, bfd_session_observer); #define BFD_DEF_ECHO_PORT 3785 #define BFD_DEF_MHOP_DEST_PORT 4784 -/* - * control.c - * - * Daemon control code to speak with local consumers. - */ - -/* See 'bfdctrl.h' for client protocol definitions. */ - -struct bfd_control_buffer { - size_t bcb_left; - size_t bcb_pos; - union { - struct bfd_control_msg *bcb_bcm; - uint8_t *bcb_buf; - }; -}; - -struct bfd_control_queue { - TAILQ_ENTRY(bfd_control_queue) bcq_entry; - - struct bfd_control_buffer bcq_bcb; -}; -TAILQ_HEAD(bcqueue, bfd_control_queue); - -struct bfd_notify_peer { - TAILQ_ENTRY(bfd_notify_peer) bnp_entry; - - struct bfd_session *bnp_bs; -}; -TAILQ_HEAD(bnplist, bfd_notify_peer); - -struct bfd_control_socket { - TAILQ_ENTRY(bfd_control_socket) bcs_entry; - - int bcs_sd; - struct event *bcs_ev; - struct event *bcs_outev; - struct bcqueue bcs_bcqueue; - - /* Notification data */ - uint64_t bcs_notify; - struct bnplist bcs_bnplist; - - enum bc_msg_version bcs_version; - enum bc_msg_type bcs_type; - - /* Message buffering */ - struct bfd_control_buffer bcs_bin; - struct bfd_control_buffer *bcs_bout; -}; -TAILQ_HEAD(bcslist, bfd_control_socket); - -int control_init(const char *path); -void control_shutdown(void); -int control_notify(struct bfd_session *bs, uint8_t notify_state); -int control_notify_config(const char *op, struct bfd_session *bs); -void control_accept(struct event *t); - /* * bfdd.c @@ -468,9 +453,6 @@ TAILQ_HEAD(dplane_queue, bfd_dplane_ctx); struct bfd_global { int bg_csock; struct event *bg_csockev; - struct bcslist bg_bcslist; - - struct pllist bg_pllist; struct obslist bg_obslist; @@ -516,27 +498,6 @@ extern const struct bfd_state_str_list state_list[]; void socket_close(int *s); -/* - * config.c - * - * Contains the code related with loading/reloading configuration. - */ -int parse_config(const char *fname); -int config_request_add(const char *jsonstr); -int config_request_del(const char *jsonstr); -char *config_response(const char *status, const char *error); -char *config_notify(struct bfd_session *bs); -char *config_notify_config(const char *op, struct bfd_session *bs); - -typedef int (*bpc_handle)(struct bfd_peer_cfg *, void *arg); -int config_notify_request(struct bfd_control_socket *bcs, const char *jsonstr, - bpc_handle bh); - -struct peer_label *pl_new(const char *label, struct bfd_session *bs); -struct peer_label *pl_find(const char *label); -void pl_free(struct peer_label *pl); - - /* * logging - alias to zebra log */ @@ -621,7 +582,6 @@ struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, bool is_mhop); struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc); -int bfd_session_update_label(struct bfd_session *bs, const char *nlabel); void bfd_set_polling(struct bfd_session *bs); void bs_state_handler(struct bfd_session *bs, int nstate); void bs_echo_timer_handler(struct bfd_session *bs); diff --git a/bfdd/bfdctl.h b/bfdd/bfdctl.h deleted file mode 100644 index f1f8185c3bbf..000000000000 --- a/bfdd/bfdctl.h +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/********************************************************************* - * Copyright 2017-2018 Network Device Education Foundation, Inc. ("NetDEF") - * - * bfdctl.h: all BFDd control socket protocol definitions. - * - * Authors - * ------- - * Rafael Zalamena - */ - -#ifndef _BFDCTRL_H_ -#define _BFDCTRL_H_ - -#include - -#include -#include - -/* - * Auxiliary definitions - */ -struct sockaddr_any { - union { - struct sockaddr_in sa_sin; - struct sockaddr_in6 sa_sin6; - }; -}; - -#ifndef MAXNAMELEN -#define MAXNAMELEN 32 -#endif - -#define BPC_DEF_DETECTMULTIPLIER 3 -#define BPC_DEF_RECEIVEINTERVAL 300 /* milliseconds */ -#define BPC_DEF_TRANSMITINTERVAL 300 /* milliseconds */ -#define BPC_DEF_ECHORECEIVEINTERVAL 50 /* milliseconds */ -#define BPC_DEF_ECHOTRANSMITINTERVAL 50 /* milliseconds */ - -/* Peer status */ -enum bfd_peer_status { - BPS_SHUTDOWN = 0, /* == PTM_BFD_ADM_DOWN, "adm-down" */ - BPS_DOWN = 1, /* == PTM_BFD_DOWN, "down" */ - BPS_INIT = 2, /* == PTM_BFD_INIT, "init" */ - BPS_UP = 3, /* == PTM_BFD_UP, "up" */ -}; - -struct bfd_peer_cfg { - bool bpc_mhop; - bool bpc_ipv4; - struct sockaddr_any bpc_peer; - struct sockaddr_any bpc_local; - - bool bpc_has_label; - char bpc_label[MAXNAMELEN]; - - bool bpc_has_localif; - char bpc_localif[MAXNAMELEN + 1]; - - bool bpc_has_vrfname; - char bpc_vrfname[MAXNAMELEN + 1]; - - bool bpc_has_detectmultiplier; - uint8_t bpc_detectmultiplier; - - bool bpc_has_recvinterval; - uint64_t bpc_recvinterval; - - bool bpc_has_txinterval; - uint64_t bpc_txinterval; - - bool bpc_has_echorecvinterval; - uint64_t bpc_echorecvinterval; - - bool bpc_has_echotxinterval; - uint64_t bpc_echotxinterval; - - bool bpc_has_minimum_ttl; - uint8_t bpc_minimum_ttl; - - bool bpc_echo; - bool bpc_createonly; - bool bpc_shutdown; - - bool bpc_cbit; - bool bpc_passive; - - bool bpc_has_profile; - char bpc_profile[64]; - - /* Status information */ - enum bfd_peer_status bpc_bps; - uint32_t bpc_id; - uint32_t bpc_remoteid; - uint8_t bpc_diag; - uint8_t bpc_remotediag; - uint8_t bpc_remote_detectmultiplier; - uint64_t bpc_remote_recvinterval; - uint64_t bpc_remote_txinterval; - uint64_t bpc_remote_echointerval; - uint64_t bpc_lastevent; -}; - - -/* - * Protocol definitions - */ -enum bc_msg_version { - BMV_VERSION_1 = 1, -}; - -enum bc_msg_type { - BMT_RESPONSE = 1, - BMT_REQUEST_ADD = 2, - BMT_REQUEST_DEL = 3, - BMT_NOTIFY = 4, - BMT_NOTIFY_ADD = 5, - BMT_NOTIFY_DEL = 6, -}; - -/* Notify flags to use with bcm_notify. */ -#define BCM_NOTIFY_ALL ((uint64_t)-1) -#define BCM_NOTIFY_PEER_STATE (1ULL << 0) -#define BCM_NOTIFY_CONFIG (1ULL << 1) -#define BCM_NOTIFY_NONE 0 - -/* Response 'status' definitions. */ -#define BCM_RESPONSE_OK "ok" -#define BCM_RESPONSE_ERROR "error" - -/* Notify operation. */ -#define BCM_NOTIFY_PEER_STATUS "status" -#define BCM_NOTIFY_CONFIG_ADD "add" -#define BCM_NOTIFY_CONFIG_DELETE "delete" -#define BCM_NOTIFY_CONFIG_UPDATE "update" - -/* Notification special ID. */ -#define BCM_NOTIFY_ID 0 - -struct bfd_control_msg { - /* Total length without the header. */ - uint32_t bcm_length; - /* - * Message request/response id. - * All requests will have a correspondent response with the - * same id. - */ - uint16_t bcm_id; - /* Message type. */ - uint8_t bcm_type; - /* Message version. */ - uint8_t bcm_ver; - /* Message payload. */ - uint8_t bcm_data[0]; -}; - -#endif diff --git a/bfdd/bfdd.c b/bfdd/bfdd.c index 243cf5c12903..c2d8e926bff6 100644 --- a/bfdd/bfdd.c +++ b/bfdd/bfdd.c @@ -28,8 +28,8 @@ * FRR related code. */ DEFINE_MGROUP(BFDD, "Bidirectional Forwarding Detection Daemon"); -DEFINE_MTYPE(BFDD, BFDD_CONTROL, "control socket memory"); -DEFINE_MTYPE(BFDD, BFDD_NOTIFICATION, "control notification data"); +DEFINE_MTYPE(BFDD, BFDD_CLIENT, "BFD client data"); +DEFINE_MTYPE(BFDD, BFDD_CLIENT_NOTIFICATION, "BFD client notification data"); /* Master of threads. */ struct event_loop *master; @@ -67,9 +67,6 @@ static void sigterm_handler(void) /* Stop receiving message from zebra. */ bfdd_zclient_stop(); - /* Shutdown controller to avoid receiving anymore commands. */ - control_shutdown(); - /* Shutdown and free all protocol related memory. */ bfd_shutdown(); @@ -132,10 +129,8 @@ FRR_DAEMON_INFO(bfdd, BFD, ); /* clang-format on */ -#define OPTION_CTLSOCK 1001 #define OPTION_DPLANEADDR 2000 static const struct option longopts[] = { - {"bfdctl", required_argument, NULL, OPTION_CTLSOCK}, {"dplaneaddr", required_argument, NULL, OPTION_DPLANEADDR}, {0} }; @@ -319,7 +314,6 @@ static void bg_init(void) .cap_num_i = 0, }; - TAILQ_INIT(&bglobal.bg_bcslist); TAILQ_INIT(&bglobal.bg_obslist); memcpy(&bglobal.bfdd_privs, &bfdd_privs, @@ -328,8 +322,7 @@ static void bg_init(void) int main(int argc, char *argv[]) { - char ctl_path[512], dplane_addr[512]; - bool ctlsockused = false; + char dplane_addr[512]; int opt; bglobal.bg_use_dplane = false; @@ -339,7 +332,6 @@ int main(int argc, char *argv[]) frr_preinit(&bfdd_di, argc, argv); frr_opt_add("", longopts, - " --bfdctl Specify bfdd control socket\n" " --dplaneaddr Specify BFD data plane address\n"); while (true) { @@ -348,10 +340,6 @@ int main(int argc, char *argv[]) break; switch (opt) { - case OPTION_CTLSOCK: - strlcpy(ctl_path, optarg, sizeof(ctl_path)); - ctlsockused = true; - break; case OPTION_DPLANEADDR: strlcpy(dplane_addr, optarg, sizeof(dplane_addr)); bglobal.bg_use_dplane = true; @@ -362,15 +350,9 @@ int main(int argc, char *argv[]) } } - if (!ctlsockused) - snprintf(ctl_path, sizeof(ctl_path), BFDD_SOCK_NAME); - /* Initialize FRR infrastructure. */ master = frr_init(); - /* Initialize control socket. */ - control_init(ctl_path); - /* Initialize BFD data structures. */ bfd_initialize(); @@ -381,9 +363,6 @@ int main(int argc, char *argv[]) /* Initialize zebra connection. */ bfdd_zclient_init(&bglobal.bfdd_privs); - event_add_read(master, control_accept, NULL, bglobal.bg_csock, - &bglobal.bg_csockev); - /* Install commands. */ bfdd_vty_init(); diff --git a/bfdd/bfdd_vty.c b/bfdd/bfdd_vty.c index 496d5019b5e9..26554e1496b8 100644 --- a/bfdd/bfdd_vty.c +++ b/bfdd/bfdd_vty.c @@ -84,9 +84,6 @@ static void _display_peer_header(struct vty *vty, struct bfd_session *bs) if (bs->key.ifname[0]) vty_out(vty, " interface %s", bs->key.ifname); vty_out(vty, "\n"); - - if (bs->pl) - vty_out(vty, "\t\tlabel: %s\n", bs->pl->pl_label); } static void _display_peer(struct vty *vty, struct bfd_session *bs) @@ -200,9 +197,6 @@ static struct json_object *_peer_json_header(struct bfd_session *bs) if (bs->key.ifname[0]) json_object_string_add(jo, "interface", bs->key.ifname); - if (bs->pl) - json_object_string_add(jo, "label", bs->pl->pl_label); - return jo; } @@ -561,17 +555,11 @@ _find_peer_or_error(struct vty *vty, int argc, struct cmd_token **argv, int idx; bool mhop; struct bfd_session *bs = NULL; - struct peer_label *pl; struct bfd_peer_cfg bpc; struct sockaddr_any psa, lsa, *lsap; char errormsg[128]; - /* Look up the BFD peer. */ - if (label) { - pl = pl_find(label); - if (pl) - bs = pl->pl_bs; - } else if (peer_str) { + if (peer_str) { strtosa(peer_str, &psa); if (local_str) { strtosa(local_str, &lsa); @@ -879,7 +867,6 @@ static int bfd_configure_peer(struct bfd_peer_cfg *bpc, bool mhop, bpc->bpc_txinterval = BPC_DEF_TRANSMITINTERVAL; bpc->bpc_echorecvinterval = BPC_DEF_ECHORECEIVEINTERVAL; bpc->bpc_echotxinterval = BPC_DEF_ECHOTRANSMITINTERVAL; - bpc->bpc_lastevent = monotime(NULL); /* Safety check: when no error buf is provided len must be zero. */ if (ebuf == NULL) diff --git a/bfdd/config.c b/bfdd/config.c deleted file mode 100644 index 22d7d7deee23..000000000000 --- a/bfdd/config.c +++ /dev/null @@ -1,592 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/********************************************************************* - * Copyright 2017-2018 Network Device Education Foundation, Inc. ("NetDEF") - * - * config.c: implements the BFD daemon configuration handling. - * - * Authors - * ------- - * Rafael Zalamena - */ - -#include - -#include - -#include "lib/json.h" - -#include "bfd.h" - -DEFINE_MTYPE_STATIC(BFDD, BFDD_LABEL, "long-lived label memory"); - -/* - * Definitions - */ -enum peer_list_type { - PLT_IPV4, - PLT_IPV6, - PLT_LABEL, -}; - - -/* - * Prototypes - */ -static int parse_config_json(struct json_object *jo, bpc_handle h, void *arg); -static int parse_list(struct json_object *jo, enum peer_list_type plt, - bpc_handle h, void *arg); -static int parse_peer_config(struct json_object *jo, struct bfd_peer_cfg *bpc); -static int parse_peer_label_config(struct json_object *jo, - struct bfd_peer_cfg *bpc); - -static int config_add(struct bfd_peer_cfg *bpc, void *arg); -static int config_del(struct bfd_peer_cfg *bpc, void *arg); - -static int json_object_add_peer(struct json_object *jo, struct bfd_session *bs); - - -/* - * Implementation - */ -static int config_add(struct bfd_peer_cfg *bpc, - void *arg __attribute__((unused))) -{ - return ptm_bfd_sess_new(bpc) == NULL; -} - -static int config_del(struct bfd_peer_cfg *bpc, - void *arg __attribute__((unused))) -{ - return ptm_bfd_sess_del(bpc) != 0; -} - -static int parse_config_json(struct json_object *jo, bpc_handle h, void *arg) -{ - const char *key, *sval; - struct json_object *jo_val; - struct json_object_iterator joi, join; - int error = 0; - - JSON_FOREACH (jo, joi, join) { - key = json_object_iter_peek_name(&joi); - jo_val = json_object_iter_peek_value(&joi); - - if (strcmp(key, "ipv4") == 0) { - error += parse_list(jo_val, PLT_IPV4, h, arg); - } else if (strcmp(key, "ipv6") == 0) { - error += parse_list(jo_val, PLT_IPV6, h, arg); - } else if (strcmp(key, "label") == 0) { - error += parse_list(jo_val, PLT_LABEL, h, arg); - } else { - sval = json_object_get_string(jo_val); - zlog_warn("%s:%d invalid configuration: %s", __func__, - __LINE__, sval); - error++; - } - } - - /* - * Our callers never call free() on json_object and only expect - * the return value, so lets free() it here. - */ - json_object_put(jo); - - return error; -} - -int parse_config(const char *fname) -{ - struct json_object *jo; - - jo = json_object_from_file(fname); - if (jo == NULL) - return -1; - - return parse_config_json(jo, config_add, NULL); -} - -static int parse_list(struct json_object *jo, enum peer_list_type plt, - bpc_handle h, void *arg) -{ - struct json_object *jo_val; - struct bfd_peer_cfg bpc; - int allen, idx; - int error = 0, result; - - allen = json_object_array_length(jo); - for (idx = 0; idx < allen; idx++) { - jo_val = json_object_array_get_idx(jo, idx); - - /* Set defaults. */ - memset(&bpc, 0, sizeof(bpc)); - bpc.bpc_detectmultiplier = BFD_DEFDETECTMULT; - bpc.bpc_recvinterval = BFD_DEFREQUIREDMINRX; - bpc.bpc_txinterval = BFD_DEFDESIREDMINTX; - bpc.bpc_echorecvinterval = BFD_DEF_REQ_MIN_ECHO_RX; - bpc.bpc_echotxinterval = BFD_DEF_DES_MIN_ECHO_TX; - - switch (plt) { - case PLT_IPV4: - zlog_debug("ipv4 peers %d:", allen); - bpc.bpc_ipv4 = true; - break; - case PLT_IPV6: - zlog_debug("ipv6 peers %d:", allen); - bpc.bpc_ipv4 = false; - break; - case PLT_LABEL: - zlog_debug("label peers %d:", allen); - if (parse_peer_label_config(jo_val, &bpc) != 0) { - error++; - continue; - } - break; - - default: - error++; - zlog_err("%s:%d: unsupported peer type", __func__, - __LINE__); - break; - } - - result = parse_peer_config(jo_val, &bpc); - error += result; - if (result == 0) - error += (h(&bpc, arg) != 0); - } - - return error; -} - -static int parse_peer_config(struct json_object *jo, struct bfd_peer_cfg *bpc) -{ - const char *key, *sval; - struct json_object *jo_val; - struct json_object_iterator joi, join; - int family_type = (bpc->bpc_ipv4) ? AF_INET : AF_INET6; - int error = 0; - - zlog_debug(" peer: %s", bpc->bpc_ipv4 ? "ipv4" : "ipv6"); - - JSON_FOREACH (jo, joi, join) { - key = json_object_iter_peek_name(&joi); - jo_val = json_object_iter_peek_value(&joi); - - if (strcmp(key, "multihop") == 0) { - bpc->bpc_mhop = json_object_get_boolean(jo_val); - zlog_debug(" multihop: %s", - bpc->bpc_mhop ? "true" : "false"); - } else if (strcmp(key, "peer-address") == 0) { - sval = json_object_get_string(jo_val); - if (strtosa(sval, &bpc->bpc_peer) != 0 - || bpc->bpc_peer.sa_sin.sin_family != family_type) { - zlog_debug( - "%s:%d failed to parse peer-address '%s'", - __func__, __LINE__, sval); - error++; - } - zlog_debug(" peer-address: %s", sval); - } else if (strcmp(key, "local-address") == 0) { - sval = json_object_get_string(jo_val); - if (strtosa(sval, &bpc->bpc_local) != 0 - || bpc->bpc_local.sa_sin.sin_family - != family_type) { - zlog_debug( - "%s:%d failed to parse local-address '%s'", - __func__, __LINE__, sval); - error++; - } - zlog_debug(" local-address: %s", sval); - } else if (strcmp(key, "local-interface") == 0) { - bpc->bpc_has_localif = true; - sval = json_object_get_string(jo_val); - if (strlcpy(bpc->bpc_localif, sval, - sizeof(bpc->bpc_localif)) - > sizeof(bpc->bpc_localif)) { - zlog_debug( - " local-interface: %s (truncated)", - sval); - error++; - } else { - zlog_debug(" local-interface: %s", sval); - } - } else if (strcmp(key, "vrf-name") == 0) { - bpc->bpc_has_vrfname = true; - sval = json_object_get_string(jo_val); - if (strlcpy(bpc->bpc_vrfname, sval, - sizeof(bpc->bpc_vrfname)) - > sizeof(bpc->bpc_vrfname)) { - zlog_debug(" vrf-name: %s (truncated)", - sval); - error++; - } else { - zlog_debug(" vrf-name: %s", sval); - } - } else if (strcmp(key, "detect-multiplier") == 0) { - bpc->bpc_detectmultiplier = - json_object_get_int64(jo_val); - bpc->bpc_has_detectmultiplier = true; - zlog_debug(" detect-multiplier: %u", - bpc->bpc_detectmultiplier); - } else if (strcmp(key, "receive-interval") == 0) { - bpc->bpc_recvinterval = json_object_get_int64(jo_val); - bpc->bpc_has_recvinterval = true; - zlog_debug(" receive-interval: %" PRIu64, - bpc->bpc_recvinterval); - } else if (strcmp(key, "transmit-interval") == 0) { - bpc->bpc_txinterval = json_object_get_int64(jo_val); - bpc->bpc_has_txinterval = true; - zlog_debug(" transmit-interval: %" PRIu64, - bpc->bpc_txinterval); - } else if (strcmp(key, "echo-receive-interval") == 0) { - bpc->bpc_echorecvinterval = json_object_get_int64(jo_val); - bpc->bpc_has_echorecvinterval = true; - zlog_debug(" echo-receive-interval: %" PRIu64, - bpc->bpc_echorecvinterval); - } else if (strcmp(key, "echo-transmit-interval") == 0) { - bpc->bpc_echotxinterval = json_object_get_int64(jo_val); - bpc->bpc_has_echotxinterval = true; - zlog_debug(" echo-transmit-interval: %" PRIu64, - bpc->bpc_echotxinterval); - } else if (strcmp(key, "create-only") == 0) { - bpc->bpc_createonly = json_object_get_boolean(jo_val); - zlog_debug(" create-only: %s", - bpc->bpc_createonly ? "true" : "false"); - } else if (strcmp(key, "shutdown") == 0) { - bpc->bpc_shutdown = json_object_get_boolean(jo_val); - zlog_debug(" shutdown: %s", - bpc->bpc_shutdown ? "true" : "false"); - } else if (strcmp(key, "echo-mode") == 0) { - bpc->bpc_echo = json_object_get_boolean(jo_val); - zlog_debug(" echo-mode: %s", - bpc->bpc_echo ? "true" : "false"); - } else if (strcmp(key, "label") == 0) { - bpc->bpc_has_label = true; - sval = json_object_get_string(jo_val); - if (strlcpy(bpc->bpc_label, sval, - sizeof(bpc->bpc_label)) - > sizeof(bpc->bpc_label)) { - zlog_debug(" label: %s (truncated)", - sval); - error++; - } else { - zlog_debug(" label: %s", sval); - } - } else { - sval = json_object_get_string(jo_val); - zlog_warn("%s:%d invalid configuration: '%s: %s'", - __func__, __LINE__, key, sval); - error++; - } - } - - if (bpc->bpc_peer.sa_sin.sin_family == 0) { - zlog_debug("%s:%d no peer address provided", __func__, - __LINE__); - error++; - } - - return error; -} - -static int parse_peer_label_config(struct json_object *jo, - struct bfd_peer_cfg *bpc) -{ - struct peer_label *pl; - struct json_object *label; - const char *sval; - - /* Get label and translate it to BFD daemon key. */ - if (!json_object_object_get_ex(jo, "label", &label)) - return 1; - - sval = json_object_get_string(label); - - pl = pl_find(sval); - if (pl == NULL) - return 1; - - zlog_debug(" peer-label: %s", sval); - - /* Translate the label into BFD address keys. */ - bs_to_bpc(pl->pl_bs, bpc); - - return 0; -} - - -/* - * Control socket JSON parsing. - */ -int config_request_add(const char *jsonstr) -{ - struct json_object *jo; - - jo = json_tokener_parse(jsonstr); - if (jo == NULL) - return -1; - - return parse_config_json(jo, config_add, NULL); -} - -int config_request_del(const char *jsonstr) -{ - struct json_object *jo; - - jo = json_tokener_parse(jsonstr); - if (jo == NULL) - return -1; - - return parse_config_json(jo, config_del, NULL); -} - -char *config_response(const char *status, const char *error) -{ - struct json_object *resp, *jo; - char *jsonstr; - - resp = json_object_new_object(); - if (resp == NULL) - return NULL; - - /* Add 'status' response key. */ - jo = json_object_new_string(status); - if (jo == NULL) { - json_object_put(resp); - return NULL; - } - - json_object_object_add(resp, "status", jo); - - /* Add 'error' response key. */ - if (error != NULL) { - jo = json_object_new_string(error); - if (jo == NULL) { - json_object_put(resp); - return NULL; - } - - json_object_object_add(resp, "error", jo); - } - - /* Generate JSON response. */ - jsonstr = XSTRDUP( - MTYPE_BFDD_NOTIFICATION, - json_object_to_json_string_ext(resp, BFDD_JSON_CONV_OPTIONS)); - json_object_put(resp); - - return jsonstr; -} - -char *config_notify(struct bfd_session *bs) -{ - struct json_object *resp; - char *jsonstr; - time_t now; - - resp = json_object_new_object(); - if (resp == NULL) - return NULL; - - json_object_string_add(resp, "op", BCM_NOTIFY_PEER_STATUS); - - json_object_add_peer(resp, bs); - - /* Add status information */ - json_object_int_add(resp, "id", bs->discrs.my_discr); - json_object_int_add(resp, "remote-id", bs->discrs.my_discr); - - switch (bs->ses_state) { - case PTM_BFD_UP: - json_object_string_add(resp, "state", "up"); - - now = monotime(NULL); - json_object_int_add(resp, "uptime", now - bs->uptime.tv_sec); - break; - case PTM_BFD_ADM_DOWN: - json_object_string_add(resp, "state", "adm-down"); - break; - case PTM_BFD_DOWN: - json_object_string_add(resp, "state", "down"); - - now = monotime(NULL); - json_object_int_add(resp, "downtime", - now - bs->downtime.tv_sec); - break; - case PTM_BFD_INIT: - json_object_string_add(resp, "state", "init"); - break; - - default: - json_object_string_add(resp, "state", "unknown"); - break; - } - - json_object_int_add(resp, "diagnostics", bs->local_diag); - json_object_int_add(resp, "remote-diagnostics", bs->remote_diag); - - /* Generate JSON response. */ - jsonstr = XSTRDUP( - MTYPE_BFDD_NOTIFICATION, - json_object_to_json_string_ext(resp, BFDD_JSON_CONV_OPTIONS)); - json_object_put(resp); - - return jsonstr; -} - -char *config_notify_config(const char *op, struct bfd_session *bs) -{ - struct json_object *resp; - char *jsonstr; - - resp = json_object_new_object(); - if (resp == NULL) - return NULL; - - json_object_string_add(resp, "op", op); - - json_object_add_peer(resp, bs); - - /* On peer deletion we don't need to add any additional information. */ - if (strcmp(op, BCM_NOTIFY_CONFIG_DELETE) == 0) - goto skip_config; - - json_object_int_add(resp, "detect-multiplier", bs->detect_mult); - json_object_int_add(resp, "receive-interval", - bs->timers.required_min_rx / 1000); - json_object_int_add(resp, "transmit-interval", - bs->timers.desired_min_tx / 1000); - json_object_int_add(resp, "echo-receive-interval", - bs->timers.required_min_echo_rx / 1000); - json_object_int_add(resp, "echo-transmit-interval", - bs->timers.desired_min_echo_tx / 1000); - - json_object_int_add(resp, "remote-detect-multiplier", - bs->remote_detect_mult); - json_object_int_add(resp, "remote-receive-interval", - bs->remote_timers.required_min_rx / 1000); - json_object_int_add(resp, "remote-transmit-interval", - bs->remote_timers.desired_min_tx / 1000); - json_object_int_add(resp, "remote-echo-receive-interval", - bs->remote_timers.required_min_echo / 1000); - - if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_ECHO)) - json_object_boolean_true_add(resp, "echo-mode"); - else - json_object_boolean_false_add(resp, "echo-mode"); - - if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN)) - json_object_boolean_true_add(resp, "shutdown"); - else - json_object_boolean_false_add(resp, "shutdown"); - -skip_config: - /* Generate JSON response. */ - jsonstr = XSTRDUP( - MTYPE_BFDD_NOTIFICATION, - json_object_to_json_string_ext(resp, BFDD_JSON_CONV_OPTIONS)); - json_object_put(resp); - - return jsonstr; -} - -int config_notify_request(struct bfd_control_socket *bcs, const char *jsonstr, - bpc_handle bh) -{ - struct json_object *jo; - - jo = json_tokener_parse(jsonstr); - if (jo == NULL) - return -1; - - return parse_config_json(jo, bh, bcs); -} - -static int json_object_add_peer(struct json_object *jo, struct bfd_session *bs) -{ - char addr_buf[INET6_ADDRSTRLEN]; - - /* Add peer 'key' information. */ - if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_IPV6)) - json_object_boolean_true_add(jo, "ipv6"); - else - json_object_boolean_false_add(jo, "ipv6"); - - if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH)) { - json_object_boolean_true_add(jo, "multihop"); - json_object_string_add(jo, "peer-address", - inet_ntop(bs->key.family, &bs->key.peer, - addr_buf, sizeof(addr_buf))); - json_object_string_add(jo, "local-address", - inet_ntop(bs->key.family, &bs->key.local, - addr_buf, sizeof(addr_buf))); - if (bs->key.vrfname[0]) - json_object_string_add(jo, "vrf-name", bs->key.vrfname); - } else { - json_object_boolean_false_add(jo, "multihop"); - json_object_string_add(jo, "peer-address", - inet_ntop(bs->key.family, &bs->key.peer, - addr_buf, sizeof(addr_buf))); - if (memcmp(&bs->key.local, &zero_addr, sizeof(bs->key.local))) - json_object_string_add( - jo, "local-address", - inet_ntop(bs->key.family, &bs->key.local, - addr_buf, sizeof(addr_buf))); - if (bs->key.ifname[0]) - json_object_string_add(jo, "local-interface", - bs->key.ifname); - } - - if (bs->pl) - json_object_string_add(jo, "label", bs->pl->pl_label); - - return 0; -} - - -/* - * Label handling - */ -struct peer_label *pl_find(const char *label) -{ - struct peer_label *pl; - - TAILQ_FOREACH (pl, &bglobal.bg_pllist, pl_entry) { - if (strcmp(pl->pl_label, label) != 0) - continue; - - return pl; - } - - return NULL; -} - -struct peer_label *pl_new(const char *label, struct bfd_session *bs) -{ - struct peer_label *pl; - - pl = XCALLOC(MTYPE_BFDD_LABEL, sizeof(*pl)); - - if (strlcpy(pl->pl_label, label, sizeof(pl->pl_label)) - > sizeof(pl->pl_label)) - zlog_warn("%s:%d: label was truncated", __func__, __LINE__); - - pl->pl_bs = bs; - bs->pl = pl; - - TAILQ_INSERT_HEAD(&bglobal.bg_pllist, pl, pl_entry); - - return pl; -} - -void pl_free(struct peer_label *pl) -{ - if (pl == NULL) - return; - - /* Remove the pointer back. */ - pl->pl_bs->pl = NULL; - - TAILQ_REMOVE(&bglobal.bg_pllist, pl, pl_entry); - XFREE(MTYPE_BFDD_LABEL, pl); -} diff --git a/bfdd/control.c b/bfdd/control.c deleted file mode 100644 index 98fd813ef721..000000000000 --- a/bfdd/control.c +++ /dev/null @@ -1,844 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/********************************************************************* - * Copyright 2017-2018 Network Device Education Foundation, Inc. ("NetDEF") - * - * control.c: implements the BFD daemon control socket. It will be used - * to talk with clients daemon/scripts/consumers. - * - * Authors - * ------- - * Rafael Zalamena - */ - -#include - -#include -#include - -#include - -#include "bfd.h" - -/* - * Prototypes - */ -static int sock_set_nonblock(int fd); -struct bfd_control_queue *control_queue_new(struct bfd_control_socket *bcs); -static void control_queue_free(struct bfd_control_socket *bcs, - struct bfd_control_queue *bcq); -static int control_queue_dequeue(struct bfd_control_socket *bcs); -static int control_queue_enqueue(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm); -static int control_queue_enqueue_first(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm); -struct bfd_notify_peer *control_notifypeer_new(struct bfd_control_socket *bcs, - struct bfd_session *bs); -static void control_notifypeer_free(struct bfd_control_socket *bcs, - struct bfd_notify_peer *bnp); -struct bfd_notify_peer *control_notifypeer_find(struct bfd_control_socket *bcs, - struct bfd_session *bs); - - -struct bfd_control_socket *control_new(int sd); -static void control_free(struct bfd_control_socket *bcs); -static void control_reset_buf(struct bfd_control_buffer *bcb); -static void control_read(struct event *t); -static void control_write(struct event *t); - -static void control_handle_request_add(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm); -static void control_handle_request_del(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm); -static int notify_add_cb(struct bfd_peer_cfg *bpc, void *arg); -static int notify_del_cb(struct bfd_peer_cfg *bpc, void *arg); -static void control_handle_notify_add(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm); -static void control_handle_notify_del(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm); -static void _control_handle_notify(struct hash_bucket *hb, void *arg); -static void control_handle_notify(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm); -static void control_response(struct bfd_control_socket *bcs, uint16_t id, - const char *status, const char *error); - -static void _control_notify_config(struct bfd_control_socket *bcs, - const char *op, struct bfd_session *bs); -static void _control_notify(struct bfd_control_socket *bcs, - struct bfd_session *bs); - - -/* - * Functions - */ -static int sock_set_nonblock(int fd) -{ - int flags; - - flags = fcntl(fd, F_GETFL, 0); - if (flags == -1) { - zlog_warn("%s: fcntl F_GETFL: %s", __func__, strerror(errno)); - return -1; - } - - flags |= O_NONBLOCK; - if (fcntl(fd, F_SETFL, flags) == -1) { - zlog_warn("%s: fcntl F_SETFL: %s", __func__, strerror(errno)); - return -1; - } - - return 0; -} - -int control_init(const char *path) -{ - int sd; - mode_t umval; - struct sockaddr_un sun_ = { - .sun_family = AF_UNIX, - }; - - assert(path); - - strlcpy(sun_.sun_path, path, sizeof(sun_.sun_path)); - - /* Remove previously created sockets. */ - unlink(sun_.sun_path); - - sd = socket(AF_UNIX, SOCK_STREAM, PF_UNSPEC); - if (sd == -1) { - zlog_err("%s: socket: %s", __func__, strerror(errno)); - return -1; - } - - umval = umask(0); - if (bind(sd, (struct sockaddr *)&sun_, sizeof(sun_)) == -1) { - zlog_err("%s: bind: %s", __func__, strerror(errno)); - close(sd); - return -1; - } - umask(umval); - - if (listen(sd, SOMAXCONN) == -1) { - zlog_err("%s: listen: %s", __func__, strerror(errno)); - close(sd); - return -1; - } - - sock_set_nonblock(sd); - - bglobal.bg_csock = sd; - - return 0; -} - -void control_shutdown(void) -{ - struct bfd_control_socket *bcs; - - event_cancel(&bglobal.bg_csockev); - - socket_close(&bglobal.bg_csock); - - while (!TAILQ_EMPTY(&bglobal.bg_bcslist)) { - bcs = TAILQ_FIRST(&bglobal.bg_bcslist); - control_free(bcs); - } -} - -void control_accept(struct event *t) -{ - int csock, sd = EVENT_FD(t); - - csock = accept(sd, NULL, 0); - if (csock == -1) { - zlog_warn("%s: accept: %s", __func__, strerror(errno)); - return; - } - - control_new(csock); - - event_add_read(master, control_accept, NULL, sd, &bglobal.bg_csockev); -} - - -/* - * Client handling - */ -struct bfd_control_socket *control_new(int sd) -{ - struct bfd_control_socket *bcs; - - bcs = XCALLOC(MTYPE_BFDD_CONTROL, sizeof(*bcs)); - - /* Disable notifications by default. */ - bcs->bcs_notify = 0; - - bcs->bcs_sd = sd; - event_add_read(master, control_read, bcs, sd, &bcs->bcs_ev); - - TAILQ_INIT(&bcs->bcs_bcqueue); - TAILQ_INIT(&bcs->bcs_bnplist); - TAILQ_INSERT_TAIL(&bglobal.bg_bcslist, bcs, bcs_entry); - - return bcs; -} - -static void control_free(struct bfd_control_socket *bcs) -{ - struct bfd_control_queue *bcq; - struct bfd_notify_peer *bnp; - - event_cancel(&(bcs->bcs_ev)); - event_cancel(&(bcs->bcs_outev)); - - close(bcs->bcs_sd); - - TAILQ_REMOVE(&bglobal.bg_bcslist, bcs, bcs_entry); - - /* Empty output queue. */ - while (!TAILQ_EMPTY(&bcs->bcs_bcqueue)) { - bcq = TAILQ_FIRST(&bcs->bcs_bcqueue); - control_queue_free(bcs, bcq); - } - - /* Empty notification list. */ - while (!TAILQ_EMPTY(&bcs->bcs_bnplist)) { - bnp = TAILQ_FIRST(&bcs->bcs_bnplist); - control_notifypeer_free(bcs, bnp); - } - - control_reset_buf(&bcs->bcs_bin); - XFREE(MTYPE_BFDD_CONTROL, bcs); -} - -struct bfd_notify_peer *control_notifypeer_new(struct bfd_control_socket *bcs, - struct bfd_session *bs) -{ - struct bfd_notify_peer *bnp; - - bnp = control_notifypeer_find(bcs, bs); - if (bnp) - return bnp; - - bnp = XCALLOC(MTYPE_BFDD_CONTROL, sizeof(*bnp)); - - TAILQ_INSERT_TAIL(&bcs->bcs_bnplist, bnp, bnp_entry); - bnp->bnp_bs = bs; - bs->refcount++; - - return bnp; -} - -static void control_notifypeer_free(struct bfd_control_socket *bcs, - struct bfd_notify_peer *bnp) -{ - TAILQ_REMOVE(&bcs->bcs_bnplist, bnp, bnp_entry); - bnp->bnp_bs->refcount--; - XFREE(MTYPE_BFDD_CONTROL, bnp); -} - -struct bfd_notify_peer *control_notifypeer_find(struct bfd_control_socket *bcs, - struct bfd_session *bs) -{ - struct bfd_notify_peer *bnp; - - TAILQ_FOREACH (bnp, &bcs->bcs_bnplist, bnp_entry) { - if (bnp->bnp_bs == bs) - return bnp; - } - - return NULL; -} - -struct bfd_control_queue *control_queue_new(struct bfd_control_socket *bcs) -{ - struct bfd_control_queue *bcq; - - bcq = XCALLOC(MTYPE_BFDD_NOTIFICATION, sizeof(*bcq)); - - control_reset_buf(&bcq->bcq_bcb); - TAILQ_INSERT_TAIL(&bcs->bcs_bcqueue, bcq, bcq_entry); - - return bcq; -} - -static void control_queue_free(struct bfd_control_socket *bcs, - struct bfd_control_queue *bcq) -{ - control_reset_buf(&bcq->bcq_bcb); - TAILQ_REMOVE(&bcs->bcs_bcqueue, bcq, bcq_entry); - XFREE(MTYPE_BFDD_NOTIFICATION, bcq); -} - -static int control_queue_dequeue(struct bfd_control_socket *bcs) -{ - struct bfd_control_queue *bcq; - - /* List is empty, nothing to do. */ - if (TAILQ_EMPTY(&bcs->bcs_bcqueue)) - goto empty_list; - - bcq = TAILQ_FIRST(&bcs->bcs_bcqueue); - control_queue_free(bcs, bcq); - - /* Get the next buffer to send. */ - if (TAILQ_EMPTY(&bcs->bcs_bcqueue)) - goto empty_list; - - bcq = TAILQ_FIRST(&bcs->bcs_bcqueue); - bcs->bcs_bout = &bcq->bcq_bcb; - - bcs->bcs_outev = NULL; - event_add_write(master, control_write, bcs, bcs->bcs_sd, - &bcs->bcs_outev); - - return 1; - -empty_list: - event_cancel(&(bcs->bcs_outev)); - bcs->bcs_bout = NULL; - return 0; -} - -static int control_queue_enqueue(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm) -{ - struct bfd_control_queue *bcq; - struct bfd_control_buffer *bcb; - - bcq = control_queue_new(bcs); - - bcb = &bcq->bcq_bcb; - bcb->bcb_left = sizeof(struct bfd_control_msg) + ntohl(bcm->bcm_length); - bcb->bcb_pos = 0; - bcb->bcb_bcm = bcm; - - /* If this is the first item, then dequeue and start using it. */ - if (bcs->bcs_bout == NULL) { - bcs->bcs_bout = bcb; - - /* New messages, active write events. */ - event_add_write(master, control_write, bcs, bcs->bcs_sd, - &bcs->bcs_outev); - } - - return 0; -} - -static int control_queue_enqueue_first(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm) -{ - struct bfd_control_queue *bcq, *bcqn; - struct bfd_control_buffer *bcb; - - /* Enqueue it somewhere. */ - if (control_queue_enqueue(bcs, bcm) == -1) - return -1; - - /* - * The item is either the first or the last. So we must first - * check the best case where the item is already the first. - */ - bcq = TAILQ_FIRST(&bcs->bcs_bcqueue); - bcb = &bcq->bcq_bcb; - if (bcm == bcb->bcb_bcm) - return 0; - - /* - * The item was not the first, so it is the last. We'll try to - * assign it to the head of the queue, however if there is a - * transfer in progress, then we have to make the item as the - * next one. - * - * Interrupting the transfer of in progress message will cause - * the client to lose track of the message position/data. - */ - bcqn = TAILQ_LAST(&bcs->bcs_bcqueue, bcqueue); - TAILQ_REMOVE(&bcs->bcs_bcqueue, bcqn, bcq_entry); - if (bcb->bcb_pos != 0) { - /* - * First position is already being sent, insert into - * second position. - */ - TAILQ_INSERT_AFTER(&bcs->bcs_bcqueue, bcq, bcqn, bcq_entry); - } else { - /* - * Old message didn't start being sent, we still have - * time to put this one in the head of the queue. - */ - TAILQ_INSERT_HEAD(&bcs->bcs_bcqueue, bcqn, bcq_entry); - bcb = &bcqn->bcq_bcb; - bcs->bcs_bout = bcb; - } - - return 0; -} - -static void control_reset_buf(struct bfd_control_buffer *bcb) -{ - /* Get ride of old data. */ - XFREE(MTYPE_BFDD_NOTIFICATION, bcb->bcb_buf); - bcb->bcb_pos = 0; - bcb->bcb_left = 0; -} - -static void control_read(struct event *t) -{ - struct bfd_control_socket *bcs = EVENT_ARG(t); - struct bfd_control_buffer *bcb = &bcs->bcs_bin; - int sd = bcs->bcs_sd; - struct bfd_control_msg bcm; - ssize_t bread; - size_t plen; - - /* - * Check if we have already downloaded message content, if so then skip - * to - * download the rest of it and process. - * - * Otherwise download a new message header and allocate the necessary - * memory. - */ - if (bcb->bcb_buf != NULL) - goto skip_header; - - bread = read(sd, &bcm, sizeof(bcm)); - if (bread == 0) { - control_free(bcs); - return; - } - if (bread < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - goto schedule_next_read; - - zlog_warn("%s: read: %s", __func__, strerror(errno)); - control_free(bcs); - return; - } - - /* Validate header fields. */ - plen = ntohl(bcm.bcm_length); - if (plen < 2) { - zlog_debug("%s: client closed due small message length: %d", - __func__, bcm.bcm_length); - control_free(bcs); - return; - } - -#define FRR_BFD_MAXLEN 10 * 1024 - - if (plen > FRR_BFD_MAXLEN) { - zlog_debug("%s: client closed, invalid message length: %d", - __func__, bcm.bcm_length); - control_free(bcs); - return; - } - - if (bcm.bcm_ver != BMV_VERSION_1) { - zlog_debug("%s: client closed due bad version: %d", __func__, - bcm.bcm_ver); - control_free(bcs); - return; - } - - /* Prepare the buffer to load the message. */ - bcs->bcs_version = bcm.bcm_ver; - bcs->bcs_type = bcm.bcm_type; - - bcb->bcb_pos = sizeof(bcm); - bcb->bcb_left = plen; - bcb->bcb_buf = XMALLOC(MTYPE_BFDD_NOTIFICATION, - sizeof(bcm) + bcb->bcb_left + 1); - if (bcb->bcb_buf == NULL) { - zlog_warn("%s: not enough memory for message size: %zu", - __func__, bcb->bcb_left); - control_free(bcs); - return; - } - - memcpy(bcb->bcb_buf, &bcm, sizeof(bcm)); - - /* Terminate data string with NULL for later processing. */ - bcb->bcb_buf[sizeof(bcm) + bcb->bcb_left] = 0; - -skip_header: - /* Download the remaining data of the message and process it. */ - bread = read(sd, &bcb->bcb_buf[bcb->bcb_pos], bcb->bcb_left); - if (bread == 0) { - control_free(bcs); - return; - } - if (bread < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) - goto schedule_next_read; - - zlog_warn("%s: read: %s", __func__, strerror(errno)); - control_free(bcs); - return; - } - - bcb->bcb_pos += bread; - bcb->bcb_left -= bread; - /* We need more data, return to wait more. */ - if (bcb->bcb_left > 0) - goto schedule_next_read; - - switch (bcb->bcb_bcm->bcm_type) { - case BMT_REQUEST_ADD: - control_handle_request_add(bcs, bcb->bcb_bcm); - break; - case BMT_REQUEST_DEL: - control_handle_request_del(bcs, bcb->bcb_bcm); - break; - case BMT_NOTIFY: - control_handle_notify(bcs, bcb->bcb_bcm); - break; - case BMT_NOTIFY_ADD: - control_handle_notify_add(bcs, bcb->bcb_bcm); - break; - case BMT_NOTIFY_DEL: - control_handle_notify_del(bcs, bcb->bcb_bcm); - break; - - default: - zlog_debug("%s: unhandled message type: %d", __func__, - bcb->bcb_bcm->bcm_type); - control_response(bcs, bcb->bcb_bcm->bcm_id, BCM_RESPONSE_ERROR, - "invalid message type"); - break; - } - - bcs->bcs_version = 0; - bcs->bcs_type = 0; - control_reset_buf(bcb); - -schedule_next_read: - bcs->bcs_ev = NULL; - event_add_read(master, control_read, bcs, sd, &bcs->bcs_ev); -} - -static void control_write(struct event *t) -{ - struct bfd_control_socket *bcs = EVENT_ARG(t); - struct bfd_control_buffer *bcb = bcs->bcs_bout; - int sd = bcs->bcs_sd; - ssize_t bwrite; - - bwrite = write(sd, &bcb->bcb_buf[bcb->bcb_pos], bcb->bcb_left); - if (bwrite == 0) { - control_free(bcs); - return; - } - if (bwrite < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { - bcs->bcs_outev = NULL; - event_add_write(master, control_write, bcs, bcs->bcs_sd, - &bcs->bcs_outev); - return; - } - - zlog_warn("%s: write: %s", __func__, strerror(errno)); - control_free(bcs); - return; - } - - bcb->bcb_pos += bwrite; - bcb->bcb_left -= bwrite; - if (bcb->bcb_left > 0) { - bcs->bcs_outev = NULL; - event_add_write(master, control_write, bcs, bcs->bcs_sd, - &bcs->bcs_outev); - return; - } - - control_queue_dequeue(bcs); -} - - -/* - * Message processing - */ -static void control_handle_request_add(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm) -{ - const char *json = (const char *)bcm->bcm_data; - - if (config_request_add(json) == 0) - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_OK, NULL); - else - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_ERROR, - "request add failed"); -} - -static void control_handle_request_del(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm) -{ - const char *json = (const char *)bcm->bcm_data; - - if (config_request_del(json) == 0) - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_OK, NULL); - else - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_ERROR, - "request del failed"); -} - -static struct bfd_session *_notify_find_peer(struct bfd_peer_cfg *bpc) -{ - struct peer_label *pl; - - if (bpc->bpc_has_label) { - pl = pl_find(bpc->bpc_label); - if (pl) - return pl->pl_bs; - } - - return bs_peer_find(bpc); -} - -static void _control_handle_notify(struct hash_bucket *hb, void *arg) -{ - struct bfd_control_socket *bcs = arg; - struct bfd_session *bs = hb->data; - - /* Notify peer configuration. */ - if (bcs->bcs_notify & BCM_NOTIFY_CONFIG) - _control_notify_config(bcs, BCM_NOTIFY_CONFIG_ADD, bs); - - /* Notify peer status. */ - if (bcs->bcs_notify & BCM_NOTIFY_PEER_STATE) - _control_notify(bcs, bs); -} - -static void control_handle_notify(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm) -{ - memcpy(&bcs->bcs_notify, bcm->bcm_data, sizeof(bcs->bcs_notify)); - - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_OK, NULL); - - /* - * If peer asked for notification configuration, send everything that - * was configured until the moment to sync up. - */ - if (bcs->bcs_notify & (BCM_NOTIFY_CONFIG | BCM_NOTIFY_PEER_STATE)) - bfd_id_iterate(_control_handle_notify, bcs); -} - -static int notify_add_cb(struct bfd_peer_cfg *bpc, void *arg) -{ - struct bfd_control_socket *bcs = arg; - struct bfd_session *bs = _notify_find_peer(bpc); - - if (bs == NULL) - return -1; - - control_notifypeer_new(bcs, bs); - - /* Notify peer status. */ - _control_notify(bcs, bs); - - return 0; -} - -static int notify_del_cb(struct bfd_peer_cfg *bpc, void *arg) -{ - struct bfd_control_socket *bcs = arg; - struct bfd_session *bs = _notify_find_peer(bpc); - struct bfd_notify_peer *bnp; - - if (bs == NULL) - return -1; - - bnp = control_notifypeer_find(bcs, bs); - if (bnp) - control_notifypeer_free(bcs, bnp); - - return 0; -} - -static void control_handle_notify_add(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm) -{ - const char *json = (const char *)bcm->bcm_data; - - if (config_notify_request(bcs, json, notify_add_cb) == 0) { - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_OK, NULL); - return; - } - - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_ERROR, - "failed to parse notify data"); -} - -static void control_handle_notify_del(struct bfd_control_socket *bcs, - struct bfd_control_msg *bcm) -{ - const char *json = (const char *)bcm->bcm_data; - - if (config_notify_request(bcs, json, notify_del_cb) == 0) { - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_OK, NULL); - return; - } - - control_response(bcs, bcm->bcm_id, BCM_RESPONSE_ERROR, - "failed to parse notify data"); -} - - -/* - * Internal functions used by the BFD daemon. - */ -static void control_response(struct bfd_control_socket *bcs, uint16_t id, - const char *status, const char *error) -{ - struct bfd_control_msg *bcm; - char *jsonstr; - size_t jsonstrlen; - - /* Generate JSON response. */ - jsonstr = config_response(status, error); - if (jsonstr == NULL) { - zlog_warn("%s: config_response: failed to get JSON str", - __func__); - return; - } - - /* Allocate data and answer. */ - jsonstrlen = strlen(jsonstr); - bcm = XMALLOC(MTYPE_BFDD_NOTIFICATION, - sizeof(struct bfd_control_msg) + jsonstrlen); - - bcm->bcm_length = htonl(jsonstrlen); - bcm->bcm_ver = BMV_VERSION_1; - bcm->bcm_type = BMT_RESPONSE; - bcm->bcm_id = id; - memcpy(bcm->bcm_data, jsonstr, jsonstrlen); - XFREE(MTYPE_BFDD_NOTIFICATION, jsonstr); - - control_queue_enqueue_first(bcs, bcm); -} - -static void _control_notify(struct bfd_control_socket *bcs, - struct bfd_session *bs) -{ - struct bfd_control_msg *bcm; - char *jsonstr; - size_t jsonstrlen; - - /* Generate JSON response. */ - jsonstr = config_notify(bs); - if (jsonstr == NULL) { - zlog_warn("%s: config_notify: failed to get JSON str", - __func__); - return; - } - - /* Allocate data and answer. */ - jsonstrlen = strlen(jsonstr); - bcm = XMALLOC(MTYPE_BFDD_NOTIFICATION, - sizeof(struct bfd_control_msg) + jsonstrlen); - - bcm->bcm_length = htonl(jsonstrlen); - bcm->bcm_ver = BMV_VERSION_1; - bcm->bcm_type = BMT_NOTIFY; - bcm->bcm_id = htons(BCM_NOTIFY_ID); - memcpy(bcm->bcm_data, jsonstr, jsonstrlen); - XFREE(MTYPE_BFDD_NOTIFICATION, jsonstr); - - control_queue_enqueue(bcs, bcm); -} - -int control_notify(struct bfd_session *bs, uint8_t notify_state) -{ - struct bfd_control_socket *bcs; - struct bfd_notify_peer *bnp; - - /* Notify zebra listeners as well. */ - ptm_bfd_notify(bs, notify_state); - - /* - * PERFORMANCE: reuse the bfd_control_msg allocated data for - * all control sockets to avoid wasting memory. - */ - TAILQ_FOREACH (bcs, &bglobal.bg_bcslist, bcs_entry) { - /* - * Test for all notifications first, then search for - * specific peers. - */ - if ((bcs->bcs_notify & BCM_NOTIFY_PEER_STATE) == 0) { - bnp = control_notifypeer_find(bcs, bs); - /* - * If the notification is not configured here, - * don't send it. - */ - if (bnp == NULL) - continue; - } - - _control_notify(bcs, bs); - } - - return 0; -} - -static void _control_notify_config(struct bfd_control_socket *bcs, - const char *op, struct bfd_session *bs) -{ - struct bfd_control_msg *bcm; - char *jsonstr; - size_t jsonstrlen; - - /* Generate JSON response. */ - jsonstr = config_notify_config(op, bs); - if (jsonstr == NULL) { - zlog_warn("%s: config_notify_config: failed to get JSON str", - __func__); - return; - } - - /* Allocate data and answer. */ - jsonstrlen = strlen(jsonstr); - bcm = XMALLOC(MTYPE_BFDD_NOTIFICATION, - sizeof(struct bfd_control_msg) + jsonstrlen); - - bcm->bcm_length = htonl(jsonstrlen); - bcm->bcm_ver = BMV_VERSION_1; - bcm->bcm_type = BMT_NOTIFY; - bcm->bcm_id = htons(BCM_NOTIFY_ID); - memcpy(bcm->bcm_data, jsonstr, jsonstrlen); - XFREE(MTYPE_BFDD_NOTIFICATION, jsonstr); - - control_queue_enqueue(bcs, bcm); -} - -int control_notify_config(const char *op, struct bfd_session *bs) -{ - struct bfd_control_socket *bcs; - struct bfd_notify_peer *bnp; - - /* Remove the control sockets notification for this peer. */ - if (strcmp(op, BCM_NOTIFY_CONFIG_DELETE) == 0 && bs->refcount > 0) { - TAILQ_FOREACH (bcs, &bglobal.bg_bcslist, bcs_entry) { - bnp = control_notifypeer_find(bcs, bs); - if (bnp) - control_notifypeer_free(bcs, bnp); - } - } - - /* - * PERFORMANCE: reuse the bfd_control_msg allocated data for - * all control sockets to avoid wasting memory. - */ - TAILQ_FOREACH (bcs, &bglobal.bg_bcslist, bcs_entry) { - /* - * Test for all notifications first, then search for - * specific peers. - */ - if ((bcs->bcs_notify & BCM_NOTIFY_CONFIG) == 0) - continue; - - _control_notify_config(bcs, op, bs); - } - - return 0; -} diff --git a/bfdd/dplane.c b/bfdd/dplane.c index d8539812e097..7f55f3407302 100644 --- a/bfdd/dplane.c +++ b/bfdd/dplane.c @@ -354,7 +354,7 @@ bfd_dplane_session_state_change(struct bfd_dplane_ctx *bdc, bs->remote_timers.required_min_echo = ntohl(state->required_echo_rx); /* Notify and update counters. */ - control_notify(bs, bs->ses_state); + ptm_bfd_notify(bs, bs->ses_state); /* No state change. */ if (old_state == bs->ses_state) diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index b5ab2ef1d0db..f6ebefb7becb 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -148,7 +148,6 @@ static void _ptm_bfd_session_del(struct bfd_session *bs, uint8_t diag) "ptm-del-session: [%s] session refcount is zero but it was configured by CLI", bs_to_string(bs)); } else { - control_notify_config(BCM_NOTIFY_CONFIG_DELETE, bs); bfd_session_free(bs); } } @@ -892,7 +891,7 @@ static struct ptm_client *pc_new(uint32_t pid) return pc; /* Allocate the client data and save it. */ - pc = XCALLOC(MTYPE_BFDD_CONTROL, sizeof(*pc)); + pc = XCALLOC(MTYPE_BFDD_CLIENT, sizeof(*pc)); pc->pc_pid = pid; TAILQ_INSERT_HEAD(&pcqueue, pc, pc_entry); @@ -910,7 +909,7 @@ static void pc_free(struct ptm_client *pc) pcn_free(pcn); } - XFREE(MTYPE_BFDD_CONTROL, pc); + XFREE(MTYPE_BFDD_CLIENT, pc); } static void pc_free_all(void) @@ -934,7 +933,7 @@ static struct ptm_client_notification *pcn_new(struct ptm_client *pc, return pcn; /* Save the client notification data. */ - pcn = XCALLOC(MTYPE_BFDD_NOTIFICATION, sizeof(*pcn)); + pcn = XCALLOC(MTYPE_BFDD_CLIENT_NOTIFICATION, sizeof(*pcn)); TAILQ_INSERT_HEAD(&pc->pc_pcnqueue, pcn, pcn_entry); pcn->pcn_pc = pc; @@ -982,5 +981,5 @@ static void pcn_free(struct ptm_client_notification *pcn) pcn->pcn_pc = NULL; TAILQ_REMOVE(&pc->pc_pcnqueue, pcn, pcn_entry); - XFREE(MTYPE_BFDD_NOTIFICATION, pcn); + XFREE(MTYPE_BFDD_CLIENT_NOTIFICATION, pcn); } diff --git a/bfdd/subdir.am b/bfdd/subdir.am index b86a18967e19..5d2d8fda5cc6 100644 --- a/bfdd/subdir.am +++ b/bfdd/subdir.am @@ -17,8 +17,6 @@ bfdd_libbfd_a_SOURCES = \ bfdd/bfdd_vty.c \ bfdd/bfdd_cli.c \ bfdd/bfd_packet.c \ - bfdd/config.c \ - bfdd/control.c \ bfdd/dplane.c \ bfdd/event.c \ bfdd/ptm_adapter.c \ @@ -37,7 +35,6 @@ clippy_scan += \ # end noinst_HEADERS += \ - bfdd/bfdctl.h \ bfdd/bfdd_nb.h \ bfdd/bfd.h \ # end diff --git a/snapcraft/scripts/bfdd-service b/snapcraft/scripts/bfdd-service index f94a7abb4bd9..5e41d1ae6d1a 100644 --- a/snapcraft/scripts/bfdd-service +++ b/snapcraft/scripts/bfdd-service @@ -9,6 +9,5 @@ exec $SNAP/sbin/bfdd \ -f $SNAP_DATA/bfdd.conf \ --pid_file $SNAP_DATA/bfdd.pid \ --socket $SNAP_DATA/zsock \ - --vty_socket $SNAP_DATA \ - --bfdctl $SNAP_DATA/bfdd.sock + --vty_socket $SNAP_DATA diff --git a/snapcraft/snapcraft.yaml.in b/snapcraft/snapcraft.yaml.in index d90236f7a20b..eea9bfc0ee66 100644 --- a/snapcraft/snapcraft.yaml.in +++ b/snapcraft/snapcraft.yaml.in @@ -249,7 +249,7 @@ apps: - network-bind - network-control bfdd-debug: - command: sbin/bfdd -f $SNAP_DATA/bfdd.conf --pid_file $SNAP_DATA/bfdd.pid --socket $SNAP_DATA/zsock --vty_socket $SNAP_DATA --bfdctl $SNAP_DATA/bfdd.sock + command: sbin/bfdd -f $SNAP_DATA/bfdd.conf --pid_file $SNAP_DATA/bfdd.pid --socket $SNAP_DATA/zsock --vty_socket $SNAP_DATA plugs: - network - network-bind From 5340fcf144b8041cf3a979c91814c9de81bec9d4 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Wed, 24 Jul 2024 11:19:40 -0300 Subject: [PATCH 455/472] doc: missing distributed BFD man page bit Signed-off-by: Rafael Zalamena --- doc/manpages/bfd-options.rst | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/doc/manpages/bfd-options.rst b/doc/manpages/bfd-options.rst index e335ed120bde..9cd43aa2fc76 100644 --- a/doc/manpages/bfd-options.rst +++ b/doc/manpages/bfd-options.rst @@ -1,10 +1,39 @@ -BFD SOCKET ----------- +BFD +--- -The following option controls the BFD daemon control socket location. +The following options controls the BFD daemon auxiliary sockets. .. option:: --bfdctl bfd-control-socket Opens the BFD daemon control socket located at the pointed location. (default: |INSTALL_PREFIX_STATE|/bfdd.sock) + +.. option:: --dplaneaddr :
[<:port>] + + Configure the distributed BFD data plane listening socket bind address. + + One would expect the data plane to run in the same machine as FRR, so + the suggested configuration would be: + + ``--dplaneaddr unix:/var/run/frr/bfdd_dplane.sock`` + + Or using IPv4: + + ``--dplaneaddr ipv4:127.0.0.1`` + + Or using IPv6: + + ``--dplaneaddr ipv6:[::1]`` + + It is also possible to specify a port (for IPv4/IPv6 only): + + ``--dplaneaddr ipv6:[::1]:50701`` + + (if ommited the default port is ``50700``). + + It is also possible to operate in client mode (instead of listening for + connections). To connect to a data plane server append the letter 'c' to + the protocol, example: + + ``--dplaneaddr ipv4c:127.0.0.1`` From c4867fe2f2af19a18f9313b99ca4338a72bed81f Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Wed, 24 Jul 2024 11:42:11 -0300 Subject: [PATCH 456/472] doc: remove BFD control socket documentation Signed-off-by: Rafael Zalamena --- doc/manpages/bfd-options.rst | 6 ------ doc/user/bfd.rst | 13 ------------- 2 files changed, 19 deletions(-) diff --git a/doc/manpages/bfd-options.rst b/doc/manpages/bfd-options.rst index 9cd43aa2fc76..2bad5f1521ad 100644 --- a/doc/manpages/bfd-options.rst +++ b/doc/manpages/bfd-options.rst @@ -3,12 +3,6 @@ BFD The following options controls the BFD daemon auxiliary sockets. -.. option:: --bfdctl bfd-control-socket - - Opens the BFD daemon control socket located at the pointed location. - - (default: |INSTALL_PREFIX_STATE|/bfdd.sock) - .. option:: --dplaneaddr :
[<:port>] Configure the distributed BFD data plane listening socket bind address. diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst index b2127e89552a..5c5584e28f18 100644 --- a/doc/user/bfd.rst +++ b/doc/user/bfd.rst @@ -45,19 +45,6 @@ may also be specified (:ref:`common-invocation-options`). .. program:: bfdd -.. option:: --bfdctl - - Set the BFD daemon control socket location. If using a non-default - socket location:: - - /usr/lib/frr/bfdd --bfdctl /tmp/bfdd.sock - - - The default UNIX socket location is |INSTALL_PREFIX_STATE|/bfdd.sock - - This option overrides the location addition that the -N option provides - to the bfdd.sock - .. option:: --dplaneaddr :
[<:port>] Configure the distributed BFD data plane listening socket bind address. From 67e2718e1cd050a26e368e9f7ce409ae80faf131 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 26 Jul 2024 09:40:10 +0200 Subject: [PATCH 457/472] lib: remove duplicated flex_algos_free prototype Remove duplicated flex_algos_free prototype Signed-off-by: Louis Scalbert --- lib/flex_algo.h | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/flex_algo.h b/lib/flex_algo.h index e617e7cae849..ee1f617e2953 100644 --- a/lib/flex_algo.h +++ b/lib/flex_algo.h @@ -117,7 +117,6 @@ struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos, uint8_t algorithm, void *arg); struct flex_algo *flex_algo_lookup(struct flex_algos *flex_algos, uint8_t algorithm); -void flex_algos_free(struct flex_algos *flex_algos); bool flex_algo_definition_cmp(struct flex_algo *fa1, struct flex_algo *fa2); void flex_algo_delete(struct flex_algos *flex_algos, uint8_t algorithm); bool flex_algo_id_valid(uint16_t algorithm); From 9c0e668050b2ae77257cdcb780d444edb78c036b Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 26 Jul 2024 09:28:40 +0200 Subject: [PATCH 458/472] isisd: move flex_algo_delete into flex_algo_destroy Move flex_algo_delete() content into isis_instance_flex_algo_destroy() because it is called only once. Rename _flex_algo_delete to flex_algo_free() Cosmetic change. Signed-off-by: Louis Scalbert --- isisd/isis_nb_config.c | 8 +++++++- lib/flex_algo.c | 21 ++------------------- lib/flex_algo.h | 2 +- 3 files changed, 10 insertions(+), 21 deletions(-) diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 8926b624ea02..f67b28cd7cfa 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -2875,6 +2875,8 @@ int isis_instance_flex_algo_create(struct nb_cb_create_args *args) int isis_instance_flex_algo_destroy(struct nb_cb_destroy_args *args) { + struct listnode *node, *nnode; + struct flex_algo *fa; struct isis_area *area; uint32_t algorithm; @@ -2883,7 +2885,11 @@ int isis_instance_flex_algo_destroy(struct nb_cb_destroy_args *args) switch (args->event) { case NB_EV_APPLY: - flex_algo_delete(area->flex_algos, algorithm); + for (ALL_LIST_ELEMENTS(area->flex_algos->flex_algos, node, + nnode, fa)) { + if (fa->algorithm == algorithm) + flex_algo_free(area->flex_algos, fa); + } lsp_regenerate_schedule(area, area->is_type, 0); break; case NB_EV_VALIDATE: diff --git a/lib/flex_algo.c b/lib/flex_algo.c index f48117ff1b15..ab0eef67cb3b 100644 --- a/lib/flex_algo.c +++ b/lib/flex_algo.c @@ -20,9 +20,6 @@ DEFINE_MTYPE_STATIC(LIB, FLEX_ALGO_DATABASE, "Flex-Algo database"); DEFINE_MTYPE_STATIC(LIB, FLEX_ALGO, "Flex-Algo algorithm information"); -static void _flex_algo_delete(struct flex_algos *flex_algos, - struct flex_algo *fa); - struct flex_algos *flex_algos_alloc(flex_algo_allocator_t allocator, flex_algo_releaser_t releaser) { @@ -42,7 +39,7 @@ void flex_algos_free(struct flex_algos *flex_algos) struct flex_algo *fa; for (ALL_LIST_ELEMENTS(flex_algos->flex_algos, node, nnode, fa)) - _flex_algo_delete(flex_algos, fa); + flex_algo_free(flex_algos, fa); list_delete(&flex_algos->flex_algos); XFREE(MTYPE_FLEX_ALGO_DATABASE, flex_algos); } @@ -63,8 +60,7 @@ struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos, return fa; } -static void _flex_algo_delete(struct flex_algos *flex_algos, - struct flex_algo *fa) +void flex_algo_free(struct flex_algos *flex_algos, struct flex_algo *fa) { if (flex_algos->releaser) flex_algos->releaser(fa->data); @@ -75,19 +71,6 @@ static void _flex_algo_delete(struct flex_algos *flex_algos, XFREE(MTYPE_FLEX_ALGO, fa); } - -void flex_algo_delete(struct flex_algos *flex_algos, uint8_t algorithm) -{ - struct listnode *node, *nnode; - struct flex_algo *fa; - - for (ALL_LIST_ELEMENTS(flex_algos->flex_algos, node, nnode, fa)) { - if (fa->algorithm != algorithm) - continue; - _flex_algo_delete(flex_algos, fa); - } -} - /** * @brief Look up the local flex-algo object by its algorithm number. * @param algorithm flex-algo algorithm number diff --git a/lib/flex_algo.h b/lib/flex_algo.h index ee1f617e2953..54b37783e609 100644 --- a/lib/flex_algo.h +++ b/lib/flex_algo.h @@ -115,10 +115,10 @@ struct flex_algos *flex_algos_alloc(flex_algo_allocator_t allocator, void flex_algos_free(struct flex_algos *flex_algos); struct flex_algo *flex_algo_alloc(struct flex_algos *flex_algos, uint8_t algorithm, void *arg); +void flex_algo_free(struct flex_algos *flex_algos, struct flex_algo *fa); struct flex_algo *flex_algo_lookup(struct flex_algos *flex_algos, uint8_t algorithm); bool flex_algo_definition_cmp(struct flex_algo *fa1, struct flex_algo *fa2); -void flex_algo_delete(struct flex_algos *flex_algos, uint8_t algorithm); bool flex_algo_id_valid(uint16_t algorithm); char *flex_algo_metric_type_print(char *type_str, size_t sz, enum flex_algo_metric_type metric_type); From ae27101e6ff8b636f02254ba0aa2217239d896e1 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Thu, 25 Jul 2024 09:34:10 +0200 Subject: [PATCH 459/472] isisd: fix building asla at first flex-algo config When an color affinity is set on an interface before configuring the flex-algorithm, the ASLA (Application Specific Link-Attribute) sub-TLV is not build. Flex-algo fails to build the paths when a affinity constraint is required because of the lacking of information contained in ASLA. There are no problems when the configuration order is reversed. For example: > affinity-map red bit-position 1 > > interface eth2 > link-params > affinity red > > router isis 1 > mpls-te on > flex-algo 129 > dataplane sr-mpls > advertise-definition > affinity include-any green In isis_link_params_update_asla(), the ASLA sub-TLV is not build when the list of flex-algos is empty. Update ASLA when the first flex-algorithm is configured. Fixes: 893882ee20 ("isisd: add isis flex-algo configuration backend") Signed-off-by: Louis Scalbert --- isisd/isis_nb_config.c | 11 ++++++++++- isisd/isis_te.c | 4 ++-- isisd/isis_te.h | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index f67b28cd7cfa..66b66194c881 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -2838,7 +2838,9 @@ int isis_instance_flex_algo_create(struct nb_cb_create_args *args) { struct isis_area *area; struct flex_algo *fa; - bool advertise; + bool advertise, update_te; + struct isis_circuit *circuit; + struct listnode *node; uint32_t algorithm; uint32_t priority = FLEX_ALGO_PRIO_DEFAULT; struct isis_flex_algo_alloc_arg arg; @@ -2851,6 +2853,7 @@ int isis_instance_flex_algo_create(struct nb_cb_create_args *args) area = nb_running_get_entry(args->dnode, NULL, true); arg.algorithm = algorithm; arg.area = area; + update_te = list_isempty(area->flex_algos->flex_algos); fa = flex_algo_alloc(area->flex_algos, algorithm, &arg); fa->priority = priority; fa->advertise_definition = advertise; @@ -2862,6 +2865,12 @@ int isis_instance_flex_algo_create(struct nb_cb_create_args *args) admin_group_allow_explicit_zero( &fa->admin_group_include_all); } + if (update_te) { + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, + circuit)) + isis_link_params_update_asla(circuit, + circuit->interface); + } lsp_regenerate_schedule(area, area->is_type, 0); break; case NB_EV_VALIDATE: diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 3683f7455821..fead826fcdca 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -164,8 +164,8 @@ void isis_mpls_te_term(struct isis_area *area) XFREE(MTYPE_ISIS_MPLS_TE, area->mta); } -static void isis_link_params_update_asla(struct isis_circuit *circuit, - struct interface *ifp) +void isis_link_params_update_asla(struct isis_circuit *circuit, + struct interface *ifp) { struct isis_asla_subtlvs *asla; struct listnode *node, *nnode; diff --git a/isisd/isis_te.h b/isisd/isis_te.h index bf1dc2b9bbbd..326e50479df0 100644 --- a/isisd/isis_te.h +++ b/isisd/isis_te.h @@ -112,6 +112,8 @@ void isis_mpls_te_init(void); void isis_mpls_te_create(struct isis_area *area); void isis_mpls_te_disable(struct isis_area *area); void isis_mpls_te_term(struct isis_area *area); +void isis_link_params_update_asla(struct isis_circuit *circuit, + struct interface *ifp); void isis_link_params_update(struct isis_circuit *, struct interface *); int isis_mpls_te_update(struct interface *); void isis_te_lsp_event(struct isis_lsp *lsp, enum lsp_event event); From e3634cb7c53a280d023fbdd0bf055f13356e0a8e Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Fri, 26 Jul 2024 09:56:14 +0200 Subject: [PATCH 460/472] isisd: free asla at last flex-algo unconfiguration Free ASLA when the last flex-algo is unconfigured. Signed-off-by: Louis Scalbert --- isisd/isis_nb_config.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index 66b66194c881..2b47d5cbeb38 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -2884,6 +2884,7 @@ int isis_instance_flex_algo_create(struct nb_cb_create_args *args) int isis_instance_flex_algo_destroy(struct nb_cb_destroy_args *args) { + struct isis_circuit *circuit; struct listnode *node, *nnode; struct flex_algo *fa; struct isis_area *area; @@ -2899,6 +2900,12 @@ int isis_instance_flex_algo_destroy(struct nb_cb_destroy_args *args) if (fa->algorithm == algorithm) flex_algo_free(area->flex_algos, fa); } + if (list_isempty(area->flex_algos->flex_algos)) { + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, + circuit)) + isis_link_params_update_asla(circuit, + circuit->interface); + } lsp_regenerate_schedule(area, area->is_type, 0); break; case NB_EV_VALIDATE: From c682ddd1002070179735ec8dfd3087a61fea84df Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 23 Jul 2024 10:31:02 -0400 Subject: [PATCH 461/472] tests: Increase timing of bgp_duplicate_nexthop a) Make timers more aggressive for this test b) Double run_and_expect time for one sub test. These two changes cause this test to pass regularly for me when this test used to fail regularly for me. Signed-off-by: Donald Sharp --- tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf | 1 + tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf | 1 + tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf | 1 + tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf | 1 + .../bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf index 31f06dbb9031..8084962587dd 100644 --- a/tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf +++ b/tests/topotests/bgp_duplicate_nexthop/r1/bgpd.conf @@ -1,5 +1,6 @@ router bgp 64500 bgp router-id 192.0.2.1 + timers bgp 3 9 no bgp ebgp-requires-policy neighbor rrserver peer-group neighbor rrserver remote-as 64500 diff --git a/tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf index 2b03f51a2376..7312dba40769 100644 --- a/tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf +++ b/tests/topotests/bgp_duplicate_nexthop/r3/bgpd.conf @@ -1,4 +1,5 @@ router bgp 64500 view one + timers bgp 3 9 bgp router-id 192.0.2.3 neighbor rr peer-group neighbor rr remote-as 64500 diff --git a/tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf index 272183b1ac83..e46d7c5ed4c3 100644 --- a/tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf +++ b/tests/topotests/bgp_duplicate_nexthop/r5/bgpd.conf @@ -1,4 +1,5 @@ router bgp 64500 + timers bgp 3 9 bgp router-id 192.0.2.5 no bgp ebgp-requires-policy no bgp network import-check diff --git a/tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf b/tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf index 68bd36eb8a80..3aa9adb18bdb 100644 --- a/tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf +++ b/tests/topotests/bgp_duplicate_nexthop/r6/bgpd.conf @@ -1,4 +1,5 @@ router bgp 64500 + timers bgp 3 9 bgp router-id 192.0.2.6 no bgp ebgp-requires-policy no bgp network import-check diff --git a/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py index 83fae71bf59f..b458c64e33f0 100644 --- a/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py +++ b/tests/topotests/bgp_duplicate_nexthop/test_bgp_duplicate_nexthop.py @@ -212,7 +212,7 @@ def check_ipv4_prefix_with_multiple_nexthops(prefix, multipath=True): test_func = functools.partial( ip_check_path_selection, tgen.gears["r1"], prefix, expected ) - _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + _, result = topotest.run_and_expect(test_func, None, count=120, wait=0.5) assert ( result is None ), f"Failed to check that {prefix} uses the IGP label 16055 and 16006" From 6914cceea2ac6c9caed6cd7035e7c163ebc9d6ce Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 26 Jul 2024 14:02:31 -0400 Subject: [PATCH 462/472] tests: Fix test_bgp_vpnv4_per_nexthop_label.py to handle timing changes So the test script is making changes to a vpn configuration by changing something fundamental about the vpn. This is causing a window where routes we are interested in are: present ( from pre-change ) then withdrawn ( the test change causes this ) then present ( with the new data ) The test code was trying to test for this by checking to see if the prefix was there, but due to timing issues it's not always there when we look for it. Modify the test to get the vpn table version prior to the change( as that it should not be moving around ) and then change the test for the prefix to look for a version that is later than the vpn's table version. Then we know that it is *after* everything has stabilized again. Signed-off-by: Donald Sharp --- .../test_bgp_vpnv4_per_nexthop_label.py | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py index cf1d3cb2b8d8..8a41b55ffb5a 100644 --- a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py @@ -151,17 +151,24 @@ def teardown_module(_mod): tgen.stop_topology() -def check_bgp_vpnv4_prefix_presence(router, prefix): +def check_bgp_vpnv4_prefix_presence(router, prefix, table_version): "Check the presence of a prefix" tgen = get_topogen() dump = router.vtysh_cmd("show bgp ipv4 vpn {} json".format(prefix), isjson=True) if not dump: return "{}, prefix ipv4 vpn {} is not installed yet".format(router.name, prefix) + + for _, paths in dump.items(): + for path in paths["paths"]: + new_version = path["version"] + if new_version <= table_version: + return "{}, prefix ipv4 vpn {} has not been updated yet".format(router.name, prefix) + return None -def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=None): +def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=None, table_version=0): """ Dump and check that vpnv4 entries have the same MPLS label value * 'router': the router to check @@ -173,7 +180,7 @@ def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=N stored_label_inited = False for prefix in group: - test_func = functools.partial(check_bgp_vpnv4_prefix_presence, router, prefix) + test_func = functools.partial(check_bgp_vpnv4_prefix_presence, router, prefix, table_version) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, prefix ipv4 vpn {} is not installed yet".format( router.name, prefix @@ -218,7 +225,7 @@ def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=N ) -def bgp_vpnv4_table_check_all(router, label_list=None, same=False): +def bgp_vpnv4_table_check_all(router, label_list=None, same=False, table_version=0): """ Dump and check that vpnv4 entries are correctly configured with specific label values * 'router': the router to check @@ -236,6 +243,7 @@ def bgp_vpnv4_table_check_all(router, label_list=None, same=False): + PREFIXES_REDIST + PREFIXES_CONNECTED, label_list=label_list, + table_version=table_version ) else: for group in ( @@ -245,7 +253,7 @@ def bgp_vpnv4_table_check_all(router, label_list=None, same=False): PREFIXES_REDIST, PREFIXES_CONNECTED, ): - bgp_vpnv4_table_check(router, group=group, label_list=label_list) + bgp_vpnv4_table_check(router, group=group, label_list=label_list, table_version=table_version) def check_show_mpls_table(router, blacklist=None, label_list=None, whitelist=None): @@ -349,6 +357,9 @@ def check_show_mpls_table_entry_label_not_found(router, inlabel): return "not good" return None +def get_table_version(router): + table = router.vtysh_cmd("show bgp ipv4 vpn json", isjson=True) + return table["tableVersion"] def mpls_entry_get_interface(router, label): """ @@ -686,6 +697,7 @@ def test_changing_default_label_value(): old_len != 1 ), "r1, number of labels used should be greater than 1, oberved {} ".format(old_len) + table_version = get_table_version(router) logger.info("r1, vrf1, changing the default MPLS label value to export to 222") router.vtysh_cmd( "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nlabel vpn export 222\n", @@ -705,7 +717,7 @@ def test_changing_default_label_value(): # check label repartition is ok logger.info("r1, vpnv4 table, check the number of labels used after modification") label_list = set() - bgp_vpnv4_table_check_all(router, label_list) + bgp_vpnv4_table_check_all(router, label_list, table_version=table_version) new_len = len(label_list) assert ( old_len == new_len @@ -734,6 +746,7 @@ def test_unconfigure_allocation_mode_nexthop(): logger.info("Unconfiguring allocation mode per nexthop") router = tgen.gears["r1"] + table_version = get_table_version(router) router.vtysh_cmd( "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nno label vpn export allocation-mode per-nexthop\n", isjson=False, @@ -752,7 +765,7 @@ def test_unconfigure_allocation_mode_nexthop(): # Check vpnv4 routes from r1 logger.info("Checking vpnv4 routes on r1") label_list = set() - bgp_vpnv4_table_check_all(router, label_list=label_list, same=True) + bgp_vpnv4_table_check_all(router, label_list=label_list, same=True, table_version=table_version) assert len(label_list) == 1, "r1, multiple Label values found for vpnv4 updates" new_label = label_list.pop() @@ -782,6 +795,8 @@ def test_reconfigure_allocation_mode_nexthop(): logger.info("Reconfiguring allocation mode per nexthop") router = tgen.gears["r1"] + + table_version = get_table_version(router) router.vtysh_cmd( "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv4 unicast\nlabel vpn export allocation-mode per-nexthop\n", isjson=False, @@ -800,7 +815,7 @@ def test_reconfigure_allocation_mode_nexthop(): # Check vpnv4 routes from r1 logger.info("Checking vpnv4 routes on r1") label_list = set() - bgp_vpnv4_table_check_all(router, label_list=label_list) + bgp_vpnv4_table_check_all(router, label_list=label_list, table_version=table_version) assert len(label_list) != 1, "r1, only 1 label values found for vpnv4 updates" # Check mpls table with all values From 77a296cb0898b1839ef4a86a7ad1a4b7d33270e8 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 26 Jul 2024 14:15:40 -0400 Subject: [PATCH 463/472] tests: Fix test_bgp_vpnv6_per_nexthop_label.py to handle timing changes So the test script is making changes to a vpn configuration by changing something fundamental about the vpn. This is causing a window where routes we are interested in are: present ( from pre-change ) then withdrawn ( the test change causes this ) then present ( with the new data ) The test code was trying to test for this by checking to see if the prefix was there, but due to timing issues it's not always there when we look for it. Modify the test to get the vpn table version prior to the change( as that it should not be moving around ) and then change the test for the prefix to look for a version that is later than the vpn's table version. Then we know that it is *after* everything has stabilized again. Signed-off-by: Donald Sharp --- .../test_bgp_vpnv6_per_nexthop_label.py | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py index f8d26427ebbb..8f10b3bc7e22 100644 --- a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py @@ -150,17 +150,24 @@ def teardown_module(_mod): tgen.stop_topology() -def check_bgp_vpnv6_prefix_presence(router, prefix): +def check_bgp_vpnv6_prefix_presence(router, prefix, table_version): "Check the presence of a prefix" tgen = get_topogen() dump = router.vtysh_cmd("show bgp ipv6 vpn {} json".format(prefix), isjson=True) if not dump: return "{}, prefix ipv6 vpn {} is not installed yet".format(router.name, prefix) + + for _, paths in dump.items(): + for path in paths["paths"]: + new_version = path["version"] + if new_version <= table_version: + return "{}, prefix ipv6 vpn {} has not been updated yet".format(router.name, prefix) + return None -def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=None): +def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=None, table_version=0): """ Dump and check that vpnv6 entries have the same MPLS label value * 'router': the router to check @@ -172,7 +179,7 @@ def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=N stored_label_inited = False for prefix in group: - test_func = functools.partial(check_bgp_vpnv6_prefix_presence, router, prefix) + test_func = functools.partial(check_bgp_vpnv6_prefix_presence, router, prefix, table_version) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, prefix ipv6 vpn {} is not installed yet".format( router.name, prefix @@ -214,7 +221,7 @@ def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=N ) -def bgp_vpnv6_table_check_all(router, label_list=None, same=False): +def bgp_vpnv6_table_check_all(router, label_list=None, same=False, table_version=0): """ Dump and check that vpnv6 entries are correctly configured with specific label values * 'router': the router to check @@ -231,6 +238,7 @@ def bgp_vpnv6_table_check_all(router, label_list=None, same=False): + PREFIXES_REDIST_R14 + PREFIXES_CONNECTED, label_list=label_list, + table_version=table_version ) else: for group in ( @@ -239,7 +247,7 @@ def bgp_vpnv6_table_check_all(router, label_list=None, same=False): PREFIXES_REDIST_R14, PREFIXES_CONNECTED, ): - bgp_vpnv6_table_check(router, group=group, label_list=label_list) + bgp_vpnv6_table_check(router, group=group, label_list=label_list, table_version=table_version) def check_show_mpls_table(router, blacklist=None, label_list=None, whitelist=None): @@ -345,6 +353,11 @@ def check_show_mpls_table_entry_label_not_found(router, inlabel): return None +def get_table_version(router): + table = router.vtysh_cmd("show bgp ipv6 vpn json", isjson=True) + return table["tableVersion"] + + def mpls_entry_get_interface(router, label): """ Assert that the label is in MPLS table @@ -691,6 +704,7 @@ def test_changing_default_label_value(): old_len != 1 ), "r1, number of labels used should be greater than 1, oberved {} ".format(old_len) + table_version = get_table_version(router) logger.info("r1, vrf1, changing the default MPLS label value to export to 222") router.vtysh_cmd( "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\nlabel vpn export 222\n", @@ -710,7 +724,7 @@ def test_changing_default_label_value(): # check label repartition is ok logger.info("r1, VPNv6 table, check the number of labels used after modification") label_list = set() - bgp_vpnv6_table_check_all(router, label_list) + bgp_vpnv6_table_check_all(router, label_list, table_version=table_version) new_len = len(label_list) assert ( old_len == new_len @@ -786,6 +800,7 @@ def test_reconfigure_allocation_mode_nexthop(): logger.info("Reconfiguring allocation mode per nexthop") router = tgen.gears["r1"] + table_version = get_table_version(router) dump = router.vtysh_cmd( "configure terminal\nrouter bgp 65500 vrf vrf1\naddress-family ipv6 unicast\nlabel vpn export allocation-mode per-nexthop\n", isjson=False, @@ -804,7 +819,7 @@ def test_reconfigure_allocation_mode_nexthop(): # Check vpnv6 routes from r1 logger.info("Checking VPNv6 routes on r1") label_list = set() - bgp_vpnv6_table_check_all(router, label_list=label_list) + bgp_vpnv6_table_check_all(router, label_list=label_list, table_version=table_version) assert len(label_list) != 1, "r1, only 1 label values found for VPNv6 updates" # Check mpls table with all values From ce3cea38dd624af75a1298dd42ff3ddb7a7d0134 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 26 Jul 2024 14:16:36 -0400 Subject: [PATCH 464/472] tests: Run black on bgp_vpnv[4|6]_per_nexthop_label I did not have my formatting right, let's get it right for these two. Signed-off-by: Donald Sharp --- .../test_bgp_vpnv4_per_nexthop_label.py | 28 ++++++++++++++----- .../test_bgp_vpnv6_per_nexthop_label.py | 22 +++++++++++---- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py index 8a41b55ffb5a..146687d5881b 100644 --- a/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv4_per_nexthop_label/test_bgp_vpnv4_per_nexthop_label.py @@ -163,12 +163,16 @@ def check_bgp_vpnv4_prefix_presence(router, prefix, table_version): for path in paths["paths"]: new_version = path["version"] if new_version <= table_version: - return "{}, prefix ipv4 vpn {} has not been updated yet".format(router.name, prefix) + return "{}, prefix ipv4 vpn {} has not been updated yet".format( + router.name, prefix + ) return None -def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=None, table_version=0): +def bgp_vpnv4_table_check( + router, group, label_list=None, label_value_expected=None, table_version=0 +): """ Dump and check that vpnv4 entries have the same MPLS label value * 'router': the router to check @@ -180,7 +184,9 @@ def bgp_vpnv4_table_check(router, group, label_list=None, label_value_expected=N stored_label_inited = False for prefix in group: - test_func = functools.partial(check_bgp_vpnv4_prefix_presence, router, prefix, table_version) + test_func = functools.partial( + check_bgp_vpnv4_prefix_presence, router, prefix, table_version + ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, prefix ipv4 vpn {} is not installed yet".format( router.name, prefix @@ -243,7 +249,7 @@ def bgp_vpnv4_table_check_all(router, label_list=None, same=False, table_version + PREFIXES_REDIST + PREFIXES_CONNECTED, label_list=label_list, - table_version=table_version + table_version=table_version, ) else: for group in ( @@ -253,7 +259,9 @@ def bgp_vpnv4_table_check_all(router, label_list=None, same=False, table_version PREFIXES_REDIST, PREFIXES_CONNECTED, ): - bgp_vpnv4_table_check(router, group=group, label_list=label_list, table_version=table_version) + bgp_vpnv4_table_check( + router, group=group, label_list=label_list, table_version=table_version + ) def check_show_mpls_table(router, blacklist=None, label_list=None, whitelist=None): @@ -357,10 +365,12 @@ def check_show_mpls_table_entry_label_not_found(router, inlabel): return "not good" return None + def get_table_version(router): table = router.vtysh_cmd("show bgp ipv4 vpn json", isjson=True) return table["tableVersion"] + def mpls_entry_get_interface(router, label): """ Assert that the label is in MPLS table @@ -765,7 +775,9 @@ def test_unconfigure_allocation_mode_nexthop(): # Check vpnv4 routes from r1 logger.info("Checking vpnv4 routes on r1") label_list = set() - bgp_vpnv4_table_check_all(router, label_list=label_list, same=True, table_version=table_version) + bgp_vpnv4_table_check_all( + router, label_list=label_list, same=True, table_version=table_version + ) assert len(label_list) == 1, "r1, multiple Label values found for vpnv4 updates" new_label = label_list.pop() @@ -815,7 +827,9 @@ def test_reconfigure_allocation_mode_nexthop(): # Check vpnv4 routes from r1 logger.info("Checking vpnv4 routes on r1") label_list = set() - bgp_vpnv4_table_check_all(router, label_list=label_list, table_version=table_version) + bgp_vpnv4_table_check_all( + router, label_list=label_list, table_version=table_version + ) assert len(label_list) != 1, "r1, only 1 label values found for vpnv4 updates" # Check mpls table with all values diff --git a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py index 8f10b3bc7e22..5fef6e9e6062 100644 --- a/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py +++ b/tests/topotests/bgp_vpnv6_per_nexthop_label/test_bgp_vpnv6_per_nexthop_label.py @@ -162,12 +162,16 @@ def check_bgp_vpnv6_prefix_presence(router, prefix, table_version): for path in paths["paths"]: new_version = path["version"] if new_version <= table_version: - return "{}, prefix ipv6 vpn {} has not been updated yet".format(router.name, prefix) + return "{}, prefix ipv6 vpn {} has not been updated yet".format( + router.name, prefix + ) return None -def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=None, table_version=0): +def bgp_vpnv6_table_check( + router, group, label_list=None, label_value_expected=None, table_version=0 +): """ Dump and check that vpnv6 entries have the same MPLS label value * 'router': the router to check @@ -179,7 +183,9 @@ def bgp_vpnv6_table_check(router, group, label_list=None, label_value_expected=N stored_label_inited = False for prefix in group: - test_func = functools.partial(check_bgp_vpnv6_prefix_presence, router, prefix, table_version) + test_func = functools.partial( + check_bgp_vpnv6_prefix_presence, router, prefix, table_version + ) success, _ = topotest.run_and_expect(test_func, None, count=10, wait=0.5) assert success, "{}, prefix ipv6 vpn {} is not installed yet".format( router.name, prefix @@ -238,7 +244,7 @@ def bgp_vpnv6_table_check_all(router, label_list=None, same=False, table_version + PREFIXES_REDIST_R14 + PREFIXES_CONNECTED, label_list=label_list, - table_version=table_version + table_version=table_version, ) else: for group in ( @@ -247,7 +253,9 @@ def bgp_vpnv6_table_check_all(router, label_list=None, same=False, table_version PREFIXES_REDIST_R14, PREFIXES_CONNECTED, ): - bgp_vpnv6_table_check(router, group=group, label_list=label_list, table_version=table_version) + bgp_vpnv6_table_check( + router, group=group, label_list=label_list, table_version=table_version + ) def check_show_mpls_table(router, blacklist=None, label_list=None, whitelist=None): @@ -819,7 +827,9 @@ def test_reconfigure_allocation_mode_nexthop(): # Check vpnv6 routes from r1 logger.info("Checking VPNv6 routes on r1") label_list = set() - bgp_vpnv6_table_check_all(router, label_list=label_list, table_version=table_version) + bgp_vpnv6_table_check_all( + router, label_list=label_list, table_version=table_version + ) assert len(label_list) != 1, "r1, only 1 label values found for VPNv6 updates" # Check mpls table with all values From 7c20ffaaba228fe5a6893d49caf50ec1df1ec142 Mon Sep 17 00:00:00 2001 From: Dave LeRoy Date: Thu, 25 Jul 2024 11:58:22 -0700 Subject: [PATCH 465/472] nhrpd: fixes duplicate auth extension When an NHRP server was forwarding a message, it was copying all extensions from the originally received packet. The authentication extension must be regenerated hop by hop per RFC2332. The copied auth extension had an incorrect length. This fix checks for the auth extension when copying extensions and omits the original packet auth and instead regenerates a new auth extension. Fix bug #16466 Signed-off-by: Dave LeRoy --- nhrpd/nhrp_peer.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c index 0407b86be8a9..3495317d4cb6 100644 --- a/nhrpd/nhrp_peer.c +++ b/nhrpd/nhrp_peer.c @@ -959,9 +959,12 @@ static void nhrp_peer_forward(struct nhrp_peer *p, if (type == NHRP_EXTENSION_END) break; - dst = nhrp_ext_push(zb, hdr, htons(ext->type)); - if (!dst) - goto err; + dst = NULL; + if (type != NHRP_EXTENSION_AUTHENTICATION) { + dst = nhrp_ext_push(zb, hdr, htons(ext->type)); + if (!dst) + goto err; + } switch (type) { case NHRP_EXTENSION_FORWARD_TRANSIT_NHS: @@ -1047,12 +1050,11 @@ static void nhrp_peer_forward(struct nhrp_peer *p, } break; case NHRP_EXTENSION_AUTHENTICATION: - /* At this point, received packet has been authenticated. - * Just need to regenerate auth extension before forwarding. - * This will be done below in nhrp_packet_complete_auth(). + /* Extensions can be copied from original packet except + * authentication extension which must be regenerated + * hop by hop. */ break; - default: if (htons(ext->type) & NHRP_EXTENSION_FLAG_COMPULSORY) /* FIXME: RFC says to just copy, but not @@ -1068,7 +1070,8 @@ static void nhrp_peer_forward(struct nhrp_peer *p, zbuf_copy(zb, &extpl, len); break; } - nhrp_ext_complete(zb, dst); + if (dst) + nhrp_ext_complete(zb, dst); } nhrp_packet_complete_auth(zb, hdr, pp->ifp, true); From bfae003b62a9dde706ab55250ebda7ea3cb1e676 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 3 May 2021 08:37:51 -0300 Subject: [PATCH 466/472] yang: MSDP SA filtering support Add option to configure MSDP peer SA incoming/outgoing filtering. Signed-off-by: Rafael Zalamena --- yang/frr-pim.yang | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/yang/frr-pim.yang b/yang/frr-pim.yang index 732a38a9e3ae..cc8d6445aa6b 100644 --- a/yang/frr-pim.yang +++ b/yang/frr-pim.yang @@ -5,6 +5,10 @@ module frr-pim { prefix frr-pim; + import frr-filter { + prefix frr-filter; + } + import frr-interface { prefix frr-interface; } @@ -267,6 +271,18 @@ module frr-pim { description "MSDP source IP address."; } + + leaf sa-filter-in { + type frr-filter:access-list-name; + description + "Access list name used to filter the incoming SAs exchanged."; + } + + leaf sa-filter-out { + type frr-filter:access-list-name; + description + "Access list name used to filter the outgoing SAs exchanged."; + } } container mlag { From be3bfe5daa721acc0182d6c3f003a9d9d80e6612 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 3 May 2021 10:25:52 -0300 Subject: [PATCH 467/472] pimd: MSDP SA filtering Implement MSDP peer incoming/outgoing SA filter. Note ---- Cisco extended access list has a special meaning: the first address is the source address to filter. Example: ! The rules below filter some LAN prefix to be leaked out access-list filter-lan-source deny ip 192.168.0.0 0.0.255.255 224.0.0.0 0.255.255.255 access-list filter-lan-source permit any router pim msdp peer 192.168.0.1 sa-filter filter-lan-source out ! The rules below filter some special management group from being ! learned access-list filter-management-group deny 230.0.0.0 0.255.255.255 access-list filter-management-group permit any router pim msdp peer 192.168.0.1 sa-filter filter-management-group in Signed-off-by: Rafael Zalamena --- pimd/pim_cmd.c | 65 ++++++++++++++++ pimd/pim_msdp.c | 9 +++ pimd/pim_msdp.h | 5 ++ pimd/pim_msdp_packet.c | 164 +++++++++++++++++++++++++++++++++++------ pimd/pim_msdp_packet.h | 2 + pimd/pim_nb.c | 14 ++++ pimd/pim_nb.h | 4 + pimd/pim_nb_config.c | 88 ++++++++++++++++++++++ 8 files changed, 327 insertions(+), 24 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 92214eced4ae..1e3e090868b0 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -6486,6 +6486,69 @@ DEFPY_ATTR(no_ip_pim_msdp_peer, return ret; } +DEFPY(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd, + "msdp peer A.B.C.D$peer sa-filter ACL_NAME$acl_name $dir", + CFG_MSDP_STR + "Configure MSDP peer\n" + "MSDP Peer address\n" + "SA access-list filter\n" + "SA access-list name\n" + "Filter incoming SAs\n" + "Filter outgoing SAs\n") +{ + const struct lyd_node *peer_node; + char xpath[XPATH_MAXLEN + 24]; + + snprintf(xpath, sizeof(xpath), "%s/msdp-peer[peer-ip='%s']", + VTY_CURR_XPATH, peer_str); + peer_node = yang_dnode_get(vty->candidate_config->dnode, xpath); + if (peer_node == NULL) { + vty_out(vty, "%% MSDP peer %s not yet configured\n", peer_str); + return CMD_SUCCESS; + } + + if (strcmp(dir, "in") == 0) + nb_cli_enqueue_change(vty, "./sa-filter-in", NB_OP_MODIFY, + acl_name); + else + nb_cli_enqueue_change(vty, "./sa-filter-out", NB_OP_MODIFY, + acl_name); + + return nb_cli_apply_changes(vty, "%s", xpath); +} + +DEFPY(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd, + "no msdp peer A.B.C.D$peer sa-filter ACL_NAME $dir", + NO_STR + CFG_MSDP_STR + "Configure MSDP peer\n" + "MSDP Peer address\n" + "SA access-list filter\n" + "SA access-list name\n" + "Filter incoming SAs\n" + "Filter outgoing SAs\n") +{ + const struct lyd_node *peer_node; + char xpath[XPATH_MAXLEN + 24]; + + snprintf(xpath, sizeof(xpath), "%s/msdp-peer[peer-ip='%s']", + VTY_CURR_XPATH, peer_str); + peer_node = yang_dnode_get(vty->candidate_config->dnode, xpath); + if (peer_node == NULL) { + vty_out(vty, "%% MSDP peer %s not yet configured\n", peer_str); + return CMD_SUCCESS; + } + + if (strcmp(dir, "in") == 0) + nb_cli_enqueue_change(vty, "./sa-filter-in", NB_OP_DESTROY, + NULL); + else + nb_cli_enqueue_change(vty, "./sa-filter-out", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, "%s", xpath); +} + DEFPY(pim_msdp_mesh_group_member, pim_msdp_mesh_group_member_cmd, "msdp mesh-group WORD$gname member A.B.C.D$maddr", @@ -8259,6 +8322,8 @@ void pim_cmd_init(void) install_element(PIM_NODE, &no_pim_msdp_peer_cmd); install_element(PIM_NODE, &pim_msdp_timers_cmd); install_element(PIM_NODE, &no_pim_msdp_timers_cmd); + install_element(PIM_NODE, &msdp_peer_sa_filter_cmd); + install_element(PIM_NODE, &no_ip_msdp_peer_sa_filter_cmd); install_element(PIM_NODE, &pim_msdp_mesh_group_member_cmd); install_element(PIM_NODE, &no_pim_msdp_mesh_group_member_cmd); install_element(PIM_NODE, &pim_msdp_mesh_group_source_cmd); diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 3393cebdd2df..0bb2d93a3a0b 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -1317,6 +1317,15 @@ bool pim_msdp_peer_config_write(struct vty *vty, struct pim_instance *pim) vty_out(vty, " msdp peer %pI4 source %pI4\n", &mp->peer, &mp->local); + + if (mp->acl_in) + vty_out(vty, " msdp peer %pI4 sa-filter %s in\n", + &mp->peer, mp->acl_in); + + if (mp->acl_out) + vty_out(vty, " msdp peer %pI4 sa-filter %s out\n", + &mp->peer, mp->acl_out); + written = true; } diff --git a/pimd/pim_msdp.h b/pimd/pim_msdp.h index 80ca003dc595..a45726cb85a6 100644 --- a/pimd/pim_msdp.h +++ b/pimd/pim_msdp.h @@ -138,6 +138,11 @@ struct pim_msdp_peer { /* timestamps */ int64_t uptime; + + /** SA input access list name. */ + char *acl_in; + /** SA output access list name. */ + char *acl_out; }; struct pim_msdp_mg_mbr { diff --git a/pimd/pim_msdp_packet.c b/pimd/pim_msdp_packet.c index 4324a96bef89..27f4966a1cc3 100644 --- a/pimd/pim_msdp_packet.c +++ b/pimd/pim_msdp_packet.c @@ -6,7 +6,9 @@ #include #include +#include #include +#include #include #include "frrevent.h" #include @@ -322,8 +324,8 @@ void pim_msdp_pkt_ka_tx(struct pim_msdp_peer *mp) pim_msdp_pkt_send(mp, s); } -static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_instance *pim, - struct pim_msdp_peer *mp) +static void pim_msdp_pkt_sa_push(struct pim_instance *pim, + struct pim_msdp_peer *mp) { struct stream *s; @@ -338,25 +340,6 @@ static void pim_msdp_pkt_sa_push_to_one_peer(struct pim_instance *pim, } } -/* push the stream into the obuf fifo of all the peers */ -static void pim_msdp_pkt_sa_push(struct pim_instance *pim, - struct pim_msdp_peer *mp) -{ - struct listnode *mpnode; - - if (mp) { - pim_msdp_pkt_sa_push_to_one_peer(pim, mp); - } else { - for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, mpnode, mp)) { - if (PIM_DEBUG_MSDP_INTERNAL) { - zlog_debug("MSDP peer %s pim_msdp_pkt_sa_push", - mp->key_str); - } - pim_msdp_pkt_sa_push_to_one_peer(pim, mp); - } - } -} - static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt, struct in_addr rp) { @@ -384,6 +367,90 @@ static void pim_msdp_pkt_sa_fill_one(struct pim_msdp_sa *sa) stream_put_ipv4(sa->pim->msdp.work_obuf, sa->sg.src.s_addr); } +static bool msdp_cisco_match(const struct filter *filter, + const struct in_addr *source, + const struct in_addr *group) +{ + const struct filter_cisco *cfilter = &filter->u.cfilter; + uint32_t source_addr; + uint32_t group_addr; + + group_addr = group->s_addr & ~cfilter->mask_mask.s_addr; + + if (cfilter->extended) { + source_addr = source->s_addr & ~cfilter->addr_mask.s_addr; + if (group_addr == cfilter->mask.s_addr && + source_addr == cfilter->addr.s_addr) + return true; + } else if (group_addr == cfilter->addr.s_addr) + return true; + + return false; +} + +static enum filter_type msdp_access_list_apply(struct access_list *access, + const struct in_addr *source, + const struct in_addr *group) +{ + struct filter *filter; + struct prefix group_prefix; + + if (access == NULL) + return FILTER_DENY; + + for (filter = access->head; filter; filter = filter->next) { + if (filter->cisco) { + if (msdp_cisco_match(filter, source, group)) + return filter->type; + } else { + group_prefix.family = AF_INET; + group_prefix.prefixlen = IPV4_MAX_BITLEN; + group_prefix.u.prefix4.s_addr = group->s_addr; + if (access_list_apply(access, &group_prefix)) + return filter->type; + } + } + + return FILTER_DENY; +} + +bool msdp_peer_sa_filter(const struct pim_msdp_peer *mp, + const struct pim_msdp_sa *sa) +{ + struct access_list *acl; + + /* No output filter configured, just quit. */ + if (mp->acl_out == NULL) + return false; + + /* Find access list and test it. */ + acl = access_list_lookup(AFI_IP, mp->acl_out); + if (msdp_access_list_apply(acl, &sa->sg.src, &sa->sg.grp) == FILTER_DENY) + return true; + + return false; +} + +/** Count the number of SAs to be sent for a specific peer. */ +static size_t pim_msdp_peer_sa_count(const struct pim_instance *pim, + const struct pim_msdp_peer *peer) +{ + const struct pim_msdp_sa *sa; + const struct listnode *node; + size_t sa_count = 0; + + for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, node, sa)) { + if (!CHECK_FLAG(sa->flags, PIM_MSDP_SAF_LOCAL)) + continue; + if (msdp_peer_sa_filter(peer, sa)) + continue; + + sa_count++; + } + + return sa_count; +} + static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, struct pim_msdp_peer *mp) { @@ -393,7 +460,7 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, struct prefix group_all; struct in_addr rp; int sa_count; - int local_cnt = pim->msdp.local_cnt; + int local_cnt = pim_msdp_peer_sa_count(pim, mp); sa_count = 0; if (PIM_DEBUG_MSDP_INTERNAL) { @@ -418,6 +485,15 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim, * peers */ continue; } + + if (msdp_peer_sa_filter(mp, sa)) { + if (PIM_DEBUG_MSDP_EVENTS) + zlog_debug("MSDP peer %pI4 filter SA out %s", + &mp->peer, sa->sg_str); + + continue; + } + /* add sa into scratch pad */ pim_msdp_pkt_sa_fill_one(sa); ++sa_count; @@ -457,15 +533,32 @@ static void pim_msdp_pkt_sa_tx_done(struct pim_instance *pim) void pim_msdp_pkt_sa_tx(struct pim_instance *pim) { - pim_msdp_pkt_sa_gen(pim, NULL /* mp */); + struct pim_msdp_peer *mp; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(pim->msdp.peer_list, node, mp)) + pim_msdp_pkt_sa_gen(pim, mp); + pim_msdp_pkt_sa_tx_done(pim); } void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa) { + struct pim_msdp_peer *mp; + struct listnode *node; + pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */, sa->rp); pim_msdp_pkt_sa_fill_one(sa); - pim_msdp_pkt_sa_push(sa->pim, NULL); + for (ALL_LIST_ELEMENTS_RO(sa->pim->msdp.peer_list, node, mp)) { + if (msdp_peer_sa_filter(mp, sa)) { + if (PIM_DEBUG_MSDP_EVENTS) + zlog_debug("MSDP peer %pI4 filter SA out %s", + &mp->peer, sa->sg_str); + continue; + } + + pim_msdp_pkt_sa_push(sa->pim, mp); + } pim_msdp_pkt_sa_tx_done(sa->pim); } @@ -487,6 +580,15 @@ void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp, /* Fills the message contents. */ sa.pim = mp->pim; sa.sg = sg; + + /* Don't push it if filtered. */ + if (msdp_peer_sa_filter(mp, &sa)) { + if (PIM_DEBUG_MSDP_EVENTS) + zlog_debug("MSDP peer %pI4 filter SA out (%pI4, %pI4)", + &mp->peer, &sa.sg.src, &sa.sg.grp); + return; + } + pim_msdp_pkt_sa_fill_one(&sa); /* Pushes the message. */ @@ -511,6 +613,7 @@ static void pim_msdp_pkt_ka_rx(struct pim_msdp_peer *mp, int len) static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) { + struct access_list *acl; int prefix_len; pim_sgaddr sg; struct listnode *peer_node; @@ -534,6 +637,19 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp) if (PIM_DEBUG_MSDP_PACKETS) { zlog_debug(" sg %pSG", &sg); } + + /* Filter incoming SA with configured access list. */ + if (mp->acl_in) { + acl = access_list_lookup(AFI_IP, mp->acl_in); + if (msdp_access_list_apply(acl, &sg.src, &sg.grp) == + FILTER_DENY) { + if (PIM_DEBUG_MSDP_EVENTS) + zlog_debug("MSDP peer %pI4 filter SA in (%pI4, %pI4)", + &mp->peer, &sg.src, &sg.grp); + return; + } + } + pim_msdp_sa_ref(mp->pim, mp, &sg, rp); /* Forwards the SA to the peers that are not in the RPF to the RP nor in diff --git a/pimd/pim_msdp_packet.h b/pimd/pim_msdp_packet.h index 1584a2453927..3af8d936852d 100644 --- a/pimd/pim_msdp_packet.h +++ b/pimd/pim_msdp_packet.h @@ -57,5 +57,7 @@ void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa); void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp); void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp, struct in_addr rp, pim_sgaddr sg); +bool msdp_peer_sa_filter(const struct pim_msdp_peer *mp, + const struct pim_msdp_sa *sa); #endif diff --git a/pimd/pim_nb.c b/pimd/pim_nb.c index 339935f81a57..6f4e32522093 100644 --- a/pimd/pim_nb.c +++ b/pimd/pim_nb.c @@ -163,6 +163,20 @@ const struct frr_yang_module_info frr_pim_info = { .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify, } }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-in", + .cbs = { + .modify = pim_msdp_peer_sa_filter_in_modify, + .destroy = pim_msdp_peer_sa_filter_in_destroy, + } + }, + { + .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-out", + .cbs = { + .modify = pim_msdp_peer_sa_filter_out_modify, + .destroy = pim_msdp_peer_sa_filter_out_destroy, + } + }, { .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag", .cbs = { diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h index 2d854d73de5e..56153bafbac0 100644 --- a/pimd/pim_nb.h +++ b/pimd/pim_nb.h @@ -65,6 +65,10 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_pim_address_family_msdp_peer_source_ip_modify( struct nb_cb_modify_args *args); +int pim_msdp_peer_sa_filter_in_modify(struct nb_cb_modify_args *args); +int pim_msdp_peer_sa_filter_in_destroy(struct nb_cb_destroy_args *args); +int pim_msdp_peer_sa_filter_out_modify(struct nb_cb_modify_args *args); +int pim_msdp_peer_sa_filter_out_destroy(struct nb_cb_destroy_args *args); int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_create( struct nb_cb_create_args *args); int routing_control_plane_protocols_control_plane_protocol_pim_address_family_mlag_destroy( diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c index be0be8588b30..49bd9a5ce71a 100644 --- a/pimd/pim_nb_config.c +++ b/pimd/pim_nb_config.c @@ -1286,6 +1286,94 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms } #endif /* PIM_IPV != 6 */ +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-in + */ +int pim_msdp_peer_sa_filter_in_modify(struct nb_cb_modify_args *args) +{ + struct pim_msdp_peer *mp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + /* NOTHING */ + break; + case NB_EV_APPLY: + mp = nb_running_get_entry(args->dnode, NULL, true); + XFREE(MTYPE_TMP, mp->acl_in); + mp->acl_in = XSTRDUP(MTYPE_TMP, + yang_dnode_get_string(args->dnode, NULL)); + break; + } + + return NB_OK; +} + +int pim_msdp_peer_sa_filter_in_destroy(struct nb_cb_destroy_args *args) +{ + struct pim_msdp_peer *mp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + /* NOTHING */ + break; + case NB_EV_APPLY: + mp = nb_running_get_entry(args->dnode, NULL, true); + XFREE(MTYPE_TMP, mp->acl_in); + break; + } + + return NB_OK; +} + +/* + * XPath: + * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/msdp-peer/sa-filter-out + */ +int pim_msdp_peer_sa_filter_out_modify(struct nb_cb_modify_args *args) +{ + struct pim_msdp_peer *mp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + /* NOTHING */ + break; + case NB_EV_APPLY: + mp = nb_running_get_entry(args->dnode, NULL, true); + XFREE(MTYPE_TMP, mp->acl_out); + mp->acl_out = XSTRDUP(MTYPE_TMP, + yang_dnode_get_string(args->dnode, NULL)); + break; + } + + return NB_OK; +} + +int pim_msdp_peer_sa_filter_out_destroy(struct nb_cb_destroy_args *args) +{ + struct pim_msdp_peer *mp; + + switch (args->event) { + case NB_EV_VALIDATE: + case NB_EV_PREPARE: + case NB_EV_ABORT: + /* NOTHING */ + break; + case NB_EV_APPLY: + mp = nb_running_get_entry(args->dnode, NULL, true); + XFREE(MTYPE_TMP, mp->acl_out); + break; + } + + return NB_OK; +} + /* * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/mlag */ From ae31d9b17baf69c675eb62db12083758b830d52e Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 3 May 2021 10:34:49 -0300 Subject: [PATCH 468/472] doc: document new MSDP filter command Let user know how to use the MSDP SA filtering command Signed-off-by: Rafael Zalamena --- doc/user/pim.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/user/pim.rst b/doc/user/pim.rst index 90d37b2d7e3e..20a4f1f7abe3 100644 --- a/doc/user/pim.rst +++ b/doc/user/pim.rst @@ -342,7 +342,7 @@ MSDP can be setup in different ways: .. note:: - MSDP default peer and SA filtering is not implemented. + MSDP default peer is not implemented. MSDP configuration is available under 'router pim' @@ -377,6 +377,15 @@ Commands available for MSDP: Create a regular MSDP session with peer using the specified source address. +.. clicmd:: msdp peer A.B.C.D sa-filter ACL_NAME + + Configure incoming or outgoing SA filtering rule. + + .. note:: + + The filtering will only take effect starting from the command + application. + .. _show-pim-information: From 7b650fb8369d180198f6b78e0dd36c9b28c933ed Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Fri, 9 Dec 2022 14:34:13 -0300 Subject: [PATCH 469/472] topotests: test MSDP SA filtering Modify existing MSDP topology to use test SA filtering: - Add new multicast host (so we get two sources for same group) - Test group only filtering - Test source / group filtering Signed-off-by: Rafael Zalamena --- tests/topotests/msdp_topo1/r4/pimd.conf | 13 +++ tests/topotests/msdp_topo1/test_msdp_topo1.py | 84 ++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/tests/topotests/msdp_topo1/r4/pimd.conf b/tests/topotests/msdp_topo1/r4/pimd.conf index 28085913fb9c..46de4fbe384a 100644 --- a/tests/topotests/msdp_topo1/r4/pimd.conf +++ b/tests/topotests/msdp_topo1/r4/pimd.conf @@ -20,3 +20,16 @@ ip msdp peer 192.168.2.1 source 192.168.2.2 ip msdp peer 192.168.3.1 source 192.168.3.2 ip pim rp 10.254.254.4 ip pim join-prune-interval 5 +! +access-list forbidden-multicast seq 5 deny 229.2.1.0 0.0.0.255 +access-list forbidden-multicast seq 1000 permit any +access-list local-only-multicast seq 5 deny 229.3.1.0 0.0.0.255 +access-list local-only-multicast seq 6 deny ip 192.168.4.100 0.0.0.0 229.10.1.0 0.0.0.255 +access-list local-only-multicast seq 1000 permit any +! +router pim + msdp peer 192.168.2.1 sa-filter forbidden-multicast in + msdp peer 192.168.2.1 sa-filter local-only-multicast out + msdp peer 192.168.3.1 sa-filter forbidden-multicast in + msdp peer 192.168.3.1 sa-filter local-only-multicast out +! diff --git a/tests/topotests/msdp_topo1/test_msdp_topo1.py b/tests/topotests/msdp_topo1/test_msdp_topo1.py index 4b54ef29ffc4..ff80052d2665 100755 --- a/tests/topotests/msdp_topo1/test_msdp_topo1.py +++ b/tests/topotests/msdp_topo1/test_msdp_topo1.py @@ -66,7 +66,9 @@ def build_topo(tgen): # Create a host connected and direct at r4: tgen.add_host("h1", "192.168.4.100/24", "via 192.168.4.1") + tgen.add_host("h3", "192.168.4.120/24", "via 192.168.4.1") switch.add_link(tgen.gears["h1"]) + switch.add_link(tgen.gears["h3"]) # Create a host connected and direct at r1: switch = tgen.add_switch("s6") @@ -82,7 +84,6 @@ def setup_module(mod): router_list = tgen.routers() for rname, router in router_list.items(): - daemon_file = "{}/{}/zebra.conf".format(CWD, rname) if os.path.isfile(daemon_file): router.load_config(TopoRouter.RD_ZEBRA, daemon_file) @@ -428,6 +429,87 @@ def test_msdp(): assert val is None, "multicast route convergence failure" +def test_msdp_sa_filter(): + "Start a number of multicast streams and check if filtering works" + + tgen = get_topogen() + + # Flow from r1 -> r4 + for multicast_address in ["229.2.1.1", "229.2.1.2", "229.2.2.1"]: + app_helper.run("h1", [multicast_address, "h1-eth0"]) + app_helper.run("h2", ["--send=0.7", multicast_address, "h2-eth0"]) + + # Flow from r4 -> r1 + for multicast_address in ["229.3.1.1", "229.3.1.2", "229.3.2.1"]: + app_helper.run("h1", ["--send=0.7", multicast_address, "h1-eth0"]) + app_helper.run("h2", [multicast_address, "h2-eth0"]) + + # Flow from r4 -> r1 but with more sources + for multicast_address in ["229.10.1.1", "229.11.1.1"]: + app_helper.run("h1", ["--send=0.7", multicast_address, "h1-eth0"]) + app_helper.run("h2", [multicast_address, "h2-eth0"]) + app_helper.run("h3", ["--send=0.7", multicast_address, "h3-eth0"]) + + # Test that we don't learn any filtered multicast streams. + r4_sa_expected = { + "229.2.1.1": None, + "229.2.1.2": None, + "229.2.2.1": { + "192.168.10.100": { + "local": "no", + "sptSetup": "yes", + } + }, + } + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r4"], + "show ip msdp sa json", + r4_sa_expected, + ) + logger.info("Waiting for r4 MDSP SA data") + _, val = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert val is None, "multicast route convergence failure" + + # Test that we don't send any filtered multicast streams. + r1_sa_expected = { + "229.3.1.1": None, + "229.3.1.2": None, + "229.3.2.1": { + "192.168.4.100": { + "local": "no", + "sptSetup": "yes", + } + }, + "229.10.1.1": { + "192.168.4.100": None, + "192.168.4.120": { + "local": "no", + "sptSetup": "yes", + }, + }, + "229.11.1.1": { + "192.168.4.100": { + "local": "no", + "sptSetup": "yes", + }, + "192.168.4.120": { + "local": "no", + "sptSetup": "yes", + }, + }, + } + test_func = partial( + topotest.router_json_cmp, + tgen.gears["r1"], + "show ip msdp sa json", + r1_sa_expected, + ) + logger.info("Waiting for r1 MDSP SA data") + _, val = topotest.run_and_expect(test_func, None, count=30, wait=1) + assert val is None, "multicast route convergence failure" + + def test_memory_leak(): "Run the memory leak test and report results." tgen = get_topogen() From e64d15b17a4577aefda10a87312baed6876f3586 Mon Sep 17 00:00:00 2001 From: Adriano Marto Reis Date: Sun, 28 Jul 2024 14:34:24 +1000 Subject: [PATCH 470/472] tests: Test MSDP RPF Adding a MSDP test with multiple possible routes. Signed-off-by: "Adriano Marto Reis" --- tests/topotests/msdp_topo2/r1/bgpd.conf | 8 + tests/topotests/msdp_topo2/r1/pimd.conf | 20 + tests/topotests/msdp_topo2/r1/zebra.conf | 14 + tests/topotests/msdp_topo2/r2/bgpd.conf | 8 + tests/topotests/msdp_topo2/r2/pimd.conf | 16 + tests/topotests/msdp_topo2/r2/zebra.conf | 11 + tests/topotests/msdp_topo2/r3/bgpd.conf | 8 + tests/topotests/msdp_topo2/r3/pimd.conf | 16 + tests/topotests/msdp_topo2/r3/zebra.conf | 11 + tests/topotests/msdp_topo2/r4/bgpd.conf | 8 + tests/topotests/msdp_topo2/r4/pimd.conf | 16 + tests/topotests/msdp_topo2/r4/zebra.conf | 11 + tests/topotests/msdp_topo2/r5/bgpd.conf | 8 + tests/topotests/msdp_topo2/r5/pimd.conf | 20 + tests/topotests/msdp_topo2/r5/zebra.conf | 14 + tests/topotests/msdp_topo2/test_msdp_topo2.py | 376 ++++++++++++++++++ 16 files changed, 565 insertions(+) create mode 100644 tests/topotests/msdp_topo2/r1/bgpd.conf create mode 100644 tests/topotests/msdp_topo2/r1/pimd.conf create mode 100644 tests/topotests/msdp_topo2/r1/zebra.conf create mode 100644 tests/topotests/msdp_topo2/r2/bgpd.conf create mode 100644 tests/topotests/msdp_topo2/r2/pimd.conf create mode 100644 tests/topotests/msdp_topo2/r2/zebra.conf create mode 100644 tests/topotests/msdp_topo2/r3/bgpd.conf create mode 100644 tests/topotests/msdp_topo2/r3/pimd.conf create mode 100644 tests/topotests/msdp_topo2/r3/zebra.conf create mode 100644 tests/topotests/msdp_topo2/r4/bgpd.conf create mode 100644 tests/topotests/msdp_topo2/r4/pimd.conf create mode 100644 tests/topotests/msdp_topo2/r4/zebra.conf create mode 100644 tests/topotests/msdp_topo2/r5/bgpd.conf create mode 100644 tests/topotests/msdp_topo2/r5/pimd.conf create mode 100644 tests/topotests/msdp_topo2/r5/zebra.conf create mode 100755 tests/topotests/msdp_topo2/test_msdp_topo2.py diff --git a/tests/topotests/msdp_topo2/r1/bgpd.conf b/tests/topotests/msdp_topo2/r1/bgpd.conf new file mode 100644 index 000000000000..67f04d8eabf9 --- /dev/null +++ b/tests/topotests/msdp_topo2/r1/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65001 + no bgp ebgp-requires-policy + neighbor 192.168.1.2 remote-as 65002 + neighbor 192.168.3.3 remote-as 65003 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/msdp_topo2/r1/pimd.conf b/tests/topotests/msdp_topo2/r1/pimd.conf new file mode 100644 index 000000000000..58a4c21e4030 --- /dev/null +++ b/tests/topotests/msdp_topo2/r1/pimd.conf @@ -0,0 +1,20 @@ +! debug pim +! debug pim zebra +! +interface lo + ip pim + ip pim use-source 10.254.254.1 +! +interface r1-eth0 + ip pim +! +interface r1-eth1 + ip pim +! +interface r1-eth2 + ip pim + ip igmp +! +ip msdp peer 192.168.1.2 source 192.168.1.1 +ip msdp peer 192.168.3.3 source 192.168.3.1 +ip pim rp 10.254.254.1 diff --git a/tests/topotests/msdp_topo2/r1/zebra.conf b/tests/topotests/msdp_topo2/r1/zebra.conf new file mode 100644 index 000000000000..3219fad36da1 --- /dev/null +++ b/tests/topotests/msdp_topo2/r1/zebra.conf @@ -0,0 +1,14 @@ +ip forwarding +! +interface r1-eth0 + ip address 192.168.1.1/24 +! +interface r1-eth1 + ip address 192.168.3.1/24 +! +interface r1-eth2 + ip address 192.168.6.1/24 +! +interface lo + ip address 10.254.254.1/32 +! diff --git a/tests/topotests/msdp_topo2/r2/bgpd.conf b/tests/topotests/msdp_topo2/r2/bgpd.conf new file mode 100644 index 000000000000..b9f316898c7e --- /dev/null +++ b/tests/topotests/msdp_topo2/r2/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65002 + no bgp ebgp-requires-policy + neighbor 192.168.1.1 remote-as 65001 + neighbor 192.168.2.5 remote-as 65005 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/msdp_topo2/r2/pimd.conf b/tests/topotests/msdp_topo2/r2/pimd.conf new file mode 100644 index 000000000000..66e630264c1b --- /dev/null +++ b/tests/topotests/msdp_topo2/r2/pimd.conf @@ -0,0 +1,16 @@ +! debug pim +! debug pim zebra +! +interface lo + ip pim + ip pim use-source 10.254.254.2 +! +interface r2-eth0 + ip pim +! +interface r2-eth1 + ip pim +! +ip msdp peer 192.168.1.1 source 192.168.1.2 +ip msdp peer 192.168.2.5 source 192.168.2.2 +ip pim rp 10.254.254.2 diff --git a/tests/topotests/msdp_topo2/r2/zebra.conf b/tests/topotests/msdp_topo2/r2/zebra.conf new file mode 100644 index 000000000000..740b51a4f074 --- /dev/null +++ b/tests/topotests/msdp_topo2/r2/zebra.conf @@ -0,0 +1,11 @@ +ip forwarding +! +interface r2-eth0 + ip address 192.168.1.2/24 +! +interface r2-eth1 + ip address 192.168.2.2/24 +! +interface lo + ip address 10.254.254.2/32 +! diff --git a/tests/topotests/msdp_topo2/r3/bgpd.conf b/tests/topotests/msdp_topo2/r3/bgpd.conf new file mode 100644 index 000000000000..ecd25b050e19 --- /dev/null +++ b/tests/topotests/msdp_topo2/r3/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65003 + no bgp ebgp-requires-policy + neighbor 192.168.3.1 remote-as 65001 + neighbor 192.168.4.4 remote-as 65004 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/msdp_topo2/r3/pimd.conf b/tests/topotests/msdp_topo2/r3/pimd.conf new file mode 100644 index 000000000000..e8e53268e381 --- /dev/null +++ b/tests/topotests/msdp_topo2/r3/pimd.conf @@ -0,0 +1,16 @@ +! debug pim +! debug pim zebra +! +interface lo + ip pim + ip pim use-source 10.254.254.3 +! +interface r3-eth0 + ip pim +! +interface r3-eth1 + ip pim +! +ip msdp peer 192.168.3.1 source 192.168.3.3 +ip msdp peer 192.168.4.4 source 192.168.4.3 +ip pim rp 10.254.254.3 diff --git a/tests/topotests/msdp_topo2/r3/zebra.conf b/tests/topotests/msdp_topo2/r3/zebra.conf new file mode 100644 index 000000000000..d1be65f636a9 --- /dev/null +++ b/tests/topotests/msdp_topo2/r3/zebra.conf @@ -0,0 +1,11 @@ +ip forwarding +! +interface r3-eth0 + ip address 192.168.3.3/24 +! +interface r3-eth1 + ip address 192.168.4.3/24 +! +interface lo + ip address 10.254.254.3/32 +! diff --git a/tests/topotests/msdp_topo2/r4/bgpd.conf b/tests/topotests/msdp_topo2/r4/bgpd.conf new file mode 100644 index 000000000000..430517bc2b07 --- /dev/null +++ b/tests/topotests/msdp_topo2/r4/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65004 + no bgp ebgp-requires-policy + neighbor 192.168.4.3 remote-as 65003 + neighbor 192.168.5.5 remote-as 65005 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/msdp_topo2/r4/pimd.conf b/tests/topotests/msdp_topo2/r4/pimd.conf new file mode 100644 index 000000000000..32e3c613fa04 --- /dev/null +++ b/tests/topotests/msdp_topo2/r4/pimd.conf @@ -0,0 +1,16 @@ +! debug pim +! debug pim zebra +! +interface lo + ip pim + ip pim use-source 10.254.254.4 +! +interface r4-eth0 + ip pim +! +interface r4-eth1 + ip pim +! +ip msdp peer 192.168.4.3 source 192.168.4.4 +ip msdp peer 192.168.5.5 source 192.168.5.4 +ip pim rp 10.254.254.4 diff --git a/tests/topotests/msdp_topo2/r4/zebra.conf b/tests/topotests/msdp_topo2/r4/zebra.conf new file mode 100644 index 000000000000..045d2e8070a3 --- /dev/null +++ b/tests/topotests/msdp_topo2/r4/zebra.conf @@ -0,0 +1,11 @@ +ip forwarding +! +interface r4-eth0 + ip address 192.168.4.4/24 +! +interface r4-eth1 + ip address 192.168.5.4/24 +! +interface lo + ip address 10.254.254.4/32 +! diff --git a/tests/topotests/msdp_topo2/r5/bgpd.conf b/tests/topotests/msdp_topo2/r5/bgpd.conf new file mode 100644 index 000000000000..053dd3d3efc1 --- /dev/null +++ b/tests/topotests/msdp_topo2/r5/bgpd.conf @@ -0,0 +1,8 @@ +router bgp 65005 + no bgp ebgp-requires-policy + neighbor 192.168.2.2 remote-as 65002 + neighbor 192.168.5.4 remote-as 65004 + address-family ipv4 unicast + redistribute connected + exit-address-family +! diff --git a/tests/topotests/msdp_topo2/r5/pimd.conf b/tests/topotests/msdp_topo2/r5/pimd.conf new file mode 100644 index 000000000000..e6cdd14c8212 --- /dev/null +++ b/tests/topotests/msdp_topo2/r5/pimd.conf @@ -0,0 +1,20 @@ +! debug pim +! debug pim zebra +! +interface lo + ip pim + ip pim use-source 10.254.254.5 +! +interface r5-eth0 + ip pim +! +interface r5-eth1 + ip pim +! +interface r5-eth2 + ip pim + ip igmp +! +ip msdp peer 192.168.2.2 source 192.168.2.5 +ip msdp peer 192.168.5.4 source 192.168.5.5 +ip pim rp 10.254.254.5 diff --git a/tests/topotests/msdp_topo2/r5/zebra.conf b/tests/topotests/msdp_topo2/r5/zebra.conf new file mode 100644 index 000000000000..195e0035100a --- /dev/null +++ b/tests/topotests/msdp_topo2/r5/zebra.conf @@ -0,0 +1,14 @@ +ip forwarding +! +interface r5-eth0 + ip address 192.168.2.5/24 +! +interface r5-eth1 + ip address 192.168.5.5/24 +! +interface r5-eth2 + ip address 192.168.7.5/24 +! +interface lo + ip address 10.254.254.5/32 +! diff --git a/tests/topotests/msdp_topo2/test_msdp_topo2.py b/tests/topotests/msdp_topo2/test_msdp_topo2.py new file mode 100755 index 000000000000..def5368f4172 --- /dev/null +++ b/tests/topotests/msdp_topo2/test_msdp_topo2.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_msdp_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2024 by +# Adriano Marto Reis +# + +""" +test_msdp_topo2.py: Test the FRR PIM MSDP peer. + + ────────────────────► + shortest path + ┌──┐ + ┌───────┤r2├───────┐ +sender │ s1 └──┘ s2 │ receiver + ┌──┐ ┌─┴┐ ┌─┴┐ ┌──┐ + │h1├────┤r1│ │r5├────┤h2│ + └──┘ s6 └─┬┘ └─┬┘ s7 └──┘ + │ ┌──┐ ┌──┐ │ + └───┤r3├────┤r4├───┘ + s3 └──┘ s4 └──┘ s5 +""" + +import os +import sys +import json +from functools import partial +import pytest + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest + +# Required to instantiate the topology builder class. +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +from lib.pim import McastTesterHelper + +pytestmark = [pytest.mark.bgpd, pytest.mark.pimd] + +app_helper = McastTesterHelper() + +MCAST_ADDR = "229.1.2.3" + +def build_topo(tgen): + "Build function" + + for routern in range(1, 6): + 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["r5"]) + + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r3"]) + + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r4"]) + + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["r5"]) + + switch = tgen.add_switch("s6") + tgen.add_host("h1", "192.168.6.100/24", "via 192.168.6.1") + switch.add_link(tgen.gears["h1"]) + switch.add_link(tgen.gears["r1"]) + + switch = tgen.add_switch("s7") + tgen.add_host("h2", "192.168.7.100/24", "via 192.168.7.5") + switch.add_link(tgen.gears["h2"]) + switch.add_link(tgen.gears["r5"]) + + +def setup_module(mod): + "Sets up the pytest environment" + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + for rname, router in router_list.items(): + + daemon_file = "{}/{}/zebra.conf".format(CWD, rname) + if os.path.isfile(daemon_file): + router.load_config(TopoRouter.RD_ZEBRA, daemon_file) + + daemon_file = "{}/{}/bgpd.conf".format(CWD, rname) + if os.path.isfile(daemon_file): + router.load_config(TopoRouter.RD_BGP, daemon_file) + + daemon_file = "{}/{}/pimd.conf".format(CWD, rname) + if os.path.isfile(daemon_file): + router.load_config(TopoRouter.RD_PIM, daemon_file) + + tgen.start_router() + + app_helper.init(tgen) + + +def teardown_module(): + "Teardown the pytest environment" + tgen = get_topogen() + app_helper.cleanup() + tgen.stop_topology() + + +def test_bgp_convergence(): + """ + Wait for BGP protocol convergence + All the loopback addresses (10.254.254.x) must be reachable from all + routers. + """ + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + routes = { + "r1": "10.254.254.1/32", + "r2": "10.254.254.2/32", + "r3": "10.254.254.3/32", + "r4": "10.254.254.4/32", + "r5": "10.254.254.5/32", + } + + for router1 in routes.keys(): + for router2, route in routes.items(): + if router1 != router2: + logger.info("waiting route {} in {}".format(route, router1)) + test_func = partial( + topotest.router_json_cmp, + tgen.gears[router1], + "show ip route json", + {route: [{"protocol": "bgp"}]}, + ) + _, result = topotest.run_and_expect(test_func, None, count=130, wait=1) + assertmsg = '"{}" convergence failure'.format(router1) + assert result is None, assertmsg + + +def test_msdp_peers(): + """ + Waits for the MSPD peer connections to be established. + """ + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + expected_msdp_peers = { + "r1": { + "192.168.1.2": { + "peer": "192.168.1.2", + "local": "192.168.1.1", + "state": "established", + }, + "192.168.3.3": { + "peer": "192.168.3.3", + "local": "192.168.3.1", + "state": "established", + }, + }, + "r2": { + "192.168.1.1": { + "peer": "192.168.1.1", + "local": "192.168.1.2", + "state": "established", + }, + "192.168.2.5": { + "peer": "192.168.2.5", + "local": "192.168.2.2", + "state": "established", + }, + }, + "r3": { + "192.168.3.1": { + "peer": "192.168.3.1", + "local": "192.168.3.3", + "state": "established", + }, + "192.168.4.4": { + "peer": "192.168.4.4", + "local": "192.168.4.3", + "state": "established", + }, + }, + "r4": { + "192.168.4.3": { + "peer": "192.168.4.3", + "local": "192.168.4.4", + "state": "established", + }, + "192.168.5.5": { + "peer": "192.168.5.5", + "local": "192.168.5.4", + "state": "established", + }, + }, + "r5": { + "192.168.2.2": { + "peer": "192.168.2.2", + "local": "192.168.2.5", + "state": "established", + }, + "192.168.5.4": { + "peer": "192.168.5.4", + "local": "192.168.5.5", + "state": "established", + }, + }, + } + + for router, peers in expected_msdp_peers.items(): + logger.info("Waiting for {} msdp peer data".format(router)) + test_function = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ip msdp peer json", + peers, + ) + _, val = topotest.run_and_expect(test_function, None, count=30, wait=1) + assert val is None, "multicast route convergence failure" + + +def test_msdp_sa(): + """ + Waits for the MSDP SA to be propagated. + The MSDP SA must be present on all routers. The MSDP SA must indicate + the original RP. + """ + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.run("h1", ["--send=0.7", MCAST_ADDR, "h1-eth0"]) + app_helper.run("h2", [MCAST_ADDR, "h2-eth0"]) + + expected_sa_r1 = { + MCAST_ADDR: { + "192.168.6.100": { + "source": "192.168.6.100", + "group": MCAST_ADDR, + "rp": "-", + "local": "yes", + } + } + } + + expected_sa_r2_r3_r4_r5 = { + MCAST_ADDR: { + "192.168.6.100": { + "source": "192.168.6.100", + "group": MCAST_ADDR, + "rp": "10.254.254.1", + "local": "no", + } + } + } + + expected_sa = { + "r1": expected_sa_r1, + "r2": expected_sa_r2_r3_r4_r5, + "r3": expected_sa_r2_r3_r4_r5, + "r4": expected_sa_r2_r3_r4_r5, + "r5": expected_sa_r2_r3_r4_r5, + } + + for router, sa in expected_sa.items(): + logger.info("Waiting for {} msdp peer data".format(router)) + test_function = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ip msdp sa json", + sa, + ) + _, val = topotest.run_and_expect(test_function, None, count=30, wait=1) + assert val is None, "multicast route convergence failure" + + +def test_mroute(): + """ + Wait for the multicast routes. + The multicast routes must connect the shortest path between h1 and h2: + h1 ─► r1 ─► r2 ─► r5 ─► h2 + + The routers r3 and r4 must have no multicast routes, as they are not + included in the shortest path between h1 and h2. + """ + + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + app_helper.run("h1", ["--send=0.7", MCAST_ADDR, "h1-eth0"]) + app_helper.run("h2", [MCAST_ADDR, "h2-eth0"]) + + expected_mroutes = { + "r1": { + MCAST_ADDR: { + "192.168.6.100": { + "iif": "r1-eth2", + "oil": { + "r1-eth0": {"source": "192.168.6.100", "group": MCAST_ADDR}, + "r1-eth1": None, + }, + }, + }, + }, + "r2": { + MCAST_ADDR: { + "192.168.6.100": { + "iif": "r2-eth0", + "oil": { + "r2-eth1": {"source": "192.168.6.100", "group": MCAST_ADDR}, + }, + }, + }, + }, + "r3": { + }, + "r4": { + }, + "r5": { + MCAST_ADDR: { + "192.168.6.100": { + "iif": "r5-eth0", + "oil": { + "r5-eth1": None, + "r5-eth2": {"source": "192.168.6.100", "group": MCAST_ADDR}, + }, + }, + }, + }, + } + + for router, mroute in expected_mroutes.items(): + logger.info("Waiting for {} mroute data".format(router)) + test_function = partial( + topotest.router_json_cmp, + tgen.gears[router], + "show ip mroute json", + mroute, + ) + _, val = topotest.run_and_expect(test_function, None, count=30, wait=1) + assert val is None, "mroute convergence failure" + + +def test_memory_leak(): + "Run the memory leak test and report results." + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) From 04f9372409a11a59dafbbf8423f0cf832b99cf0e Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Sun, 28 Jul 2024 14:26:13 +0300 Subject: [PATCH 471/472] bgpd: Do not process VRF import/export to/from auto created VRF instances Fixes the crash: ``` (gdb) bt 0 __pthread_kill_implementation (no_tid=0, signo=11, threadid=124583315603008) at ./nptl/pthread_kill.c:44 1 __pthread_kill_internal (signo=11, threadid=124583315603008) at ./nptl/pthread_kill.c:78 2 __GI___pthread_kill (threadid=124583315603008, signo=signo@entry=11) at ./nptl/pthread_kill.c:89 3 0x0000714ed0242476 in __GI_raise (sig=11) at ../sysdeps/posix/raise.c:26 4 0x0000714ed074cfb7 in core_handler (signo=11, siginfo=0x7ffe6d9792b0, context=0x7ffe6d979180) at lib/sigevent.c:258 5 6 0x000060f55e33ffdd in route_table_get_info (table=0x0) at ./lib/table.h:177 7 0x000060f55e340053 in bgp_dest_table (dest=0x60f56dabb840) at ./bgpd/bgp_table.h:156 8 0x000060f55e340c9f in is_route_injectable_into_vpn (pi=0x60f56dbc4a60) at ./bgpd/bgp_mplsvpn.h:331 9 0x000060f55e34507c in vpn_leak_from_vrf_update (to_bgp=0x60f56da52070, from_bgp=0x60f56da75af0, path_vrf=0x60f56dbc4a60) at bgpd/bgp_mplsvpn.c:1575 10 0x000060f55e346657 in vpn_leak_from_vrf_update_all (to_bgp=0x60f56da52070, from_bgp=0x60f56da75af0, afi=AFI_IP) at bgpd/bgp_mplsvpn.c:2028 11 0x000060f55e340c10 in vpn_leak_postchange (direction=BGP_VPN_POLICY_DIR_TOVPN, afi=AFI_IP, bgp_vpn=0x60f56da52070, bgp_vrf=0x60f56da75af0) at ./bgpd/bgp_mplsvpn.h:310 12 0x000060f55e34a692 in vpn_leak_postchange_all () at bgpd/bgp_mplsvpn.c:3737 13 0x000060f55e3d91fc in router_bgp (self=0x60f55e5cbc20 , vty=0x60f56e2d7660, argc=3, argv=0x60f56da19830) at bgpd/bgp_vty.c:1601 14 0x0000714ed069ddf5 in cmd_execute_command_real (vline=0x60f56da32a80, vty=0x60f56e2d7660, cmd=0x0, up_level=0) at lib/command.c:1002 15 0x0000714ed069df6e in cmd_execute_command (vline=0x60f56da32a80, vty=0x60f56e2d7660, cmd=0x0, vtysh=0) at lib/command.c:1061 16 0x0000714ed069e51e in cmd_execute (vty=0x60f56e2d7660, cmd=0x60f56dbf07d0 "router bgp 100\n", matched=0x0, vtysh=0) at lib/command.c:1227 17 0x0000714ed076faa0 in vty_command (vty=0x60f56e2d7660, buf=0x60f56dbf07d0 "router bgp 100\n") at lib/vty.c:616 18 0x0000714ed07719c4 in vty_execute (vty=0x60f56e2d7660) at lib/vty.c:1379 19 0x0000714ed07740f0 in vtysh_read (thread=0x7ffe6d97c700) at lib/vty.c:2374 20 0x0000714ed07685c4 in event_call (thread=0x7ffe6d97c700) at lib/event.c:1995 21 0x0000714ed06e3351 in frr_run (master=0x60f56d1d2e40) at lib/libfrr.c:1232 22 0x000060f55e2c4b44 in main (argc=7, argv=0x7ffe6d97c978) at bgpd/bgp_main.c:555 (gdb) ``` Fixes https://github.com/FRRouting/frr/issues/16484 Signed-off-by: Donatas Abraitis --- bgpd/bgp_mplsvpn.c | 6 ++++++ bgpd/bgp_vty.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index a1d0a8512c82..b03171b4c865 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -3734,6 +3734,9 @@ void vpn_leak_postchange_all(void) if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF) continue; + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + continue; + vpn_leak_postchange( BGP_VPN_POLICY_DIR_TOVPN, AFI_IP, @@ -3753,6 +3756,9 @@ void vpn_leak_postchange_all(void) if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF) continue; + if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) + continue; + vpn_leak_postchange( BGP_VPN_POLICY_DIR_FROMVPN, AFI_IP, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index ae14abe9e371..828fa711b2f0 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -1703,7 +1703,7 @@ DEFUN (no_router_bgp, continue; if (CHECK_FLAG(tmp_bgp->vrf_flags, BGP_VRF_AUTO)) - continue; + bgp_delete(tmp_bgp); if (CHECK_FLAG( tmp_bgp->af_flags[AFI_IP] From 460703f3e8ce63baf86f8b4f8f54fe5d77d1317c Mon Sep 17 00:00:00 2001 From: "G. Paul Ziemba" Date: Sat, 27 Jul 2024 11:56:54 -0700 Subject: [PATCH 472/472] tests: add wait to RequireVpnRoutes, RequireUnicastRoutes Signed-off-by: G. Paul Ziemba --- tests/topotests/lib/bgprib.py | 112 +++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 22 deletions(-) diff --git a/tests/topotests/lib/bgprib.py b/tests/topotests/lib/bgprib.py index 699c7a4da612..f01a440b9e3b 100644 --- a/tests/topotests/lib/bgprib.py +++ b/tests/topotests/lib/bgprib.py @@ -64,10 +64,9 @@ def routes_include_wanted(self, pfxtbl, want, debug): self.log("missing route: pfx=" + want["p"] + ", nh=" + want["n"]) return 0 - def RequireVpnRoutes(self, target, title, wantroutes, debug=0): + def RequireVpnRoutesOne(self, target, title, wantroutes, debug=0): import json - logstr = "RequireVpnRoutes " + str(wantroutes) # non json form for humans luCommand( target, @@ -86,11 +85,18 @@ def RequireVpnRoutes(self, target, title, wantroutes, debug=0): if re.search(r"^\s*$", ret): # degenerate case: empty json means no routes if len(wantroutes) > 0: - luResult(target, False, title, logstr) - return - luResult(target, True, title, logstr) + return False + return True rib = json.loads(ret) - rds = rib["routes"]["routeDistinguishers"] + try: + rds = rib["routes"]["routeDistinguishers"] + except KeyError as err: + # KeyError: 'routes' probably means missing/bad VRF + # This error also happens if we are too quick and the routing + # table has not been fully populated yet. + if debug: + self.log("KeyError, no routes") + return False for want in wantroutes: found = 0 if debug: @@ -105,11 +111,39 @@ def RequireVpnRoutes(self, target, title, wantroutes, debug=0): found = 1 break if not found: - luResult(target, False, title, logstr) - return - luResult(target, True, title, logstr) + return False + return True + + def RequireVpnRoutes( + self, target, title, wantroutes, debug=0, wait=10, wait_time=0.5 + ): + import time + import math + + logstr = "RequireVpnRoutes " + str(wantroutes) + found = False + n = 0 + startt = time.time() + + # Calculate the amount of `sleep`s we are going to peform. + wait_count = int(math.ceil(wait / wait_time)) + 1 + + while wait_count > 0: + n += 1 + found = self.RequireVpnRoutesOne(target, title, wantroutes, debug) + if found is not False: + break - def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0): + wait_count -= 1 + if wait_count > 0: + time.sleep(wait_time) + + delta = time.time() - startt + self.log("Done after %d loops, time=%s, Found=%s" % (n, delta, found)) + luResult(target, found, title, logstr) + return found + + def RequireUnicastRoutesOne(self, target, afi, vrf, title, wantroutes, debug=0): logstr = "RequireUnicastRoutes %s" % str(wantroutes) vrfstr = "" if vrf != "": @@ -129,9 +163,8 @@ def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0): if re.search(r"^\s*$", ret): # degenerate case: empty json means no routes if len(wantroutes) > 0: - luResult(target, False, title, logstr) - return - luResult(target, True, title, logstr) + return False, "" + return True, "" rib = json.loads(ret) try: table = rib["routes"] @@ -141,25 +174,60 @@ def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0): errstr = "-script ERROR: check if wrong vrf (%s)" % (vrf) else: errstr = "-script ERROR: check if vrf missing" - luResult(target, False, title + errstr, logstr) - return + self.log(errstr) + return False, errstr # if debug: # self.log("table=%s" % table) for want in wantroutes: if debug: self.log("want=%s" % want) if not self.routes_include_wanted(table, want, debug): - luResult(target, False, title, logstr) - return - luResult(target, True, title, logstr) + return False, "" + return True, "" + + def RequireUnicastRoutes( + self, target, afi, vrf, title, wantroutes, debug=0, wait=10, wait_time=0.5 + ): + import time + import math + + logstr = "RequireUnicastRoutes %s" % str(wantroutes) + found = False + n = 0 + startt = time.time() + errstr = "" + + # Calculate the amount of `sleep`s we are going to peform. + wait_count = int(math.ceil(wait / wait_time)) + 1 + + while wait_count > 0: + n += 1 + found, errstr = self.RequireUnicastRoutesOne( + target, afi, vrf, title, wantroutes, debug + ) + if found is not False: + break + + wait_count -= 1 + if wait_count > 0: + time.sleep(wait_time) + + delta = time.time() - startt + self.log("Done after %d loops, time=%s, Found=%s" % (n, delta, found)) + luResult(target, found, title + errstr, logstr) + return found BgpRib = BgpRib() -def bgpribRequireVpnRoutes(target, title, wantroutes, debug=0): - BgpRib.RequireVpnRoutes(target, title, wantroutes, debug) +def bgpribRequireVpnRoutes(target, title, wantroutes, debug=0, wait=10, wait_time=0.5): + BgpRib.RequireVpnRoutes(target, title, wantroutes, debug, wait, wait_time) -def bgpribRequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug=0): - BgpRib.RequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug) +def bgpribRequireUnicastRoutes( + target, afi, vrf, title, wantroutes, debug=0, wait=10, wait_time=0.5 +): + BgpRib.RequireUnicastRoutes( + target, afi, vrf, title, wantroutes, debug, wait, wait_time + )