diff options
47 files changed, 1315 insertions, 228 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 2280aa9097..d349922c52 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -5406,7 +5406,14 @@ enum bgp_attr_parse_ret bgp_attr_ignore(struct peer *peer, uint8_t type) lookup_msg(attr_str, type, NULL), withdraw ? "treat-as-withdraw" : "discard"); - return withdraw ? BGP_ATTR_PARSE_WITHDRAW : BGP_ATTR_PARSE_PROCEED; + /* We don't increment stat_pfx_withdraw here, because it's done in + * bgp_update_receive(). + */ + if (withdraw) + return BGP_ATTR_PARSE_WITHDRAW; + + peer->stat_pfx_discard++; + return BGP_ATTR_PARSE_PROCEED; } bool route_matches_soo(struct bgp_path_info *pi, struct ecommunity *soo) diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c index 5264bea9af..acc49cac94 100644 --- a/bgpd/bgp_bmp.c +++ b/bgpd/bgp_bmp.c @@ -1773,8 +1773,7 @@ static void bmp_stats(struct event *thread) peer->stat_pfx_cluster_loop); bmp_stat_put_u32(s, &count, BMP_STATS_PFX_DUP_WITHDRAW, peer->stat_pfx_dup_withdraw); - bmp_stat_put_u32(s, &count, BMP_STATS_UPD_7606_WITHDRAW, - peer->stat_upd_7606); + bmp_stat_put_u32(s, &count, BMP_STATS_UPD_7606_WITHDRAW, peer->stat_pfx_withdraw); if (bt->stats_send_experimental) bmp_stat_put_u32(s, &count, BMP_STATS_FRR_NH_INVALID, peer->stat_pfx_nh_invalid); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 85cc8f3596..b96c287f86 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -4079,6 +4079,35 @@ void bgp_vpn_leak_export(struct bgp *from_bgp) } } +/* It releases the label from labelpool which + * was previously assigned and unsets the flag based on reset arg + * This also used in vty to release the label and to change the allocation mode as well + */ +void bgp_vpn_release_label(struct bgp *bgp, afi_t afi, bool reset) +{ + if (!CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) + return; + /* + * label has previously been automatically + * assigned by labelpool: release it + * + * NB if tovpn_label == MPLS_LABEL_NONE it + * means the automatic assignment is in flight + * and therefore the labelpool callback must + * detect that the auto label is not needed. + */ + if (bgp->vpn_policy[afi].tovpn_label == MPLS_LABEL_NONE) + return; + if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_LABEL_PER_NEXTHOP)) + return; + + bgp_lp_release(LP_TYPE_VRF, &bgp->vpn_policy[afi], bgp->vpn_policy[afi].tovpn_label); + bgp->vpn_policy[afi].tovpn_label = MPLS_LABEL_NONE; + + if (reset) + UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO); +} + /* The nexthops values are compared to * find in the tree the appropriate cache entry */ diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 39fed66781..18639fc69b 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -352,6 +352,7 @@ extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw, bool is_config); extern void bgp_vpn_leak_unimport(struct bgp *from_bgp); extern void bgp_vpn_leak_export(struct bgp *from_bgp); +extern void bgp_vpn_release_label(struct bgp *bgp, afi_t afi, bool reset); extern bool bgp_mplsvpn_path_uses_valid_mpls_label(struct bgp_path_info *pi); extern int diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index e9cc52449b..c5e390b045 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -2411,7 +2411,7 @@ static int bgp_update_receive(struct peer_connection *connection, sizeof(peer->rcvd_attr_str)); if (attr_parse_ret == BGP_ATTR_PARSE_WITHDRAW) { - peer->stat_upd_7606++; + peer->stat_pfx_withdraw++; flog_err( EC_BGP_UPDATE_RCV, "%pBP rcvd UPDATE with errors in attr(s)!! Withdrawing route.", diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 75427a9052..0f899d9617 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -11975,14 +11975,13 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa continue; } - if (type == bgp_show_type_rpki) { - if (dest_p->family == AF_INET - || dest_p->family == AF_INET6) - rpki_curr_state = hook_call( - bgp_rpki_prefix_status, - pi->peer, pi->attr, dest_p); - if (rpki_target_state != RPKI_NOT_BEING_USED - && rpki_curr_state != rpki_target_state) + if ((dest_p->family == AF_INET || dest_p->family == AF_INET6) && + (detail_routes || detail_json || type == bgp_show_type_rpki)) { + rpki_curr_state = hook_call(bgp_rpki_prefix_status, pi->peer, + pi->attr, dest_p); + if (type == bgp_show_type_rpki && + rpki_target_state != RPKI_NOT_BEING_USED && + rpki_curr_state != rpki_target_state) continue; } @@ -12213,7 +12212,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa route_vty_out_detail(vty, bgp, dest, dest_p, pi, family2afi(dest_p->family), safi, - RPKI_NOT_BEING_USED, json_paths, NULL); + rpki_curr_state, json_paths, NULL); } else { route_vty_out(vty, dest_p, pi, display, safi, json_paths, wide); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 22fbb1bb21..550adf93db 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -9948,26 +9948,9 @@ DEFPY (af_label_vpn_export, UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_LABEL_MANUAL_REG); - } else if (CHECK_FLAG(bgp->vpn_policy[afi].flags, - BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) { + } else if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_LABEL_AUTO)) /* release any previous auto label */ - if (bgp->vpn_policy[afi].tovpn_label != MPLS_LABEL_NONE) { - - /* - * label has previously been automatically - * assigned by labelpool: release it - * - * NB if tovpn_label == MPLS_LABEL_NONE it - * means the automatic assignment is in flight - * and therefore the labelpool callback must - * detect that the auto label is not needed. - */ - - bgp_lp_release(LP_TYPE_VRF, - &bgp->vpn_policy[afi], - bgp->vpn_policy[afi].tovpn_label); - } - } + bgp_vpn_release_label(bgp, afi, false); if (yes) { if (label_auto) { @@ -15481,9 +15464,12 @@ CPP_NOTICE("Remove `gracefulRestartCapability` JSON field") if (use_json) { json_object *json_stat = NULL; + json_object *json_pfx_stat = NULL; + json_stat = json_object_new_object(); - /* Packet counts. */ + json_pfx_stat = json_object_new_object(); + /* Packet counts. */ atomic_size_t outq_count, inq_count; outq_count = atomic_load_explicit(&p->connection->obuf->count, memory_order_relaxed); @@ -15533,6 +15519,16 @@ CPP_NOTICE("Remove `gracefulRestartCapability` JSON field") json_object_int_add(json_stat, "totalSent", PEER_TOTAL_TX(p)); json_object_int_add(json_stat, "totalRecv", PEER_TOTAL_RX(p)); json_object_object_add(json_neigh, "messageStats", json_stat); + + /* Prefix statistics */ + json_object_int_add(json_pfx_stat, "inboundFiltered", p->stat_pfx_filter); + json_object_int_add(json_pfx_stat, "aspathLoop", p->stat_pfx_aspath_loop); + json_object_int_add(json_pfx_stat, "originatorLoop", p->stat_pfx_originator_loop); + json_object_int_add(json_pfx_stat, "clusterLoop", p->stat_pfx_cluster_loop); + json_object_int_add(json_pfx_stat, "invalidNextHop", p->stat_pfx_nh_invalid); + json_object_int_add(json_pfx_stat, "withdrawn", p->stat_pfx_withdraw); + json_object_int_add(json_pfx_stat, "attributesDiscarded", p->stat_pfx_discard); + json_object_object_add(json_neigh, "prefixStats", json_pfx_stat); } else { atomic_size_t outq_count, inq_count, open_out, open_in, notify_out, notify_in, update_out, update_in, @@ -15584,8 +15580,18 @@ CPP_NOTICE("Remove `gracefulRestartCapability` JSON field") refresh_in); vty_out(vty, " Capability: %10zu %10zu\n", dynamic_cap_out, dynamic_cap_in); - vty_out(vty, " Total: %10u %10u\n", - (uint32_t)PEER_TOTAL_TX(p), (uint32_t)PEER_TOTAL_RX(p)); + vty_out(vty, " Total: %10u %10u\n\n", (uint32_t)PEER_TOTAL_TX(p), + (uint32_t)PEER_TOTAL_RX(p)); + + /* Prefix statistics */ + vty_out(vty, " Prefix statistics:\n"); + vty_out(vty, " Inbound filtered: %u\n", p->stat_pfx_filter); + vty_out(vty, " AS-PATH loop: %u\n", p->stat_pfx_aspath_loop); + vty_out(vty, " Originator loop: %u\n", p->stat_pfx_originator_loop); + vty_out(vty, " Cluster loop: %u\n", p->stat_pfx_cluster_loop); + vty_out(vty, " Invalid next-hop: %u\n", p->stat_pfx_nh_invalid); + vty_out(vty, " Withdrawn: %u\n", p->stat_pfx_withdraw); + vty_out(vty, " Attributes discarded: %u\n\n", p->stat_pfx_discard); } if (use_json) { diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index ee8c61db33..2f234e3a5a 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -4037,6 +4037,9 @@ int bgp_delete(struct bgp *bgp) bgp_vpn_leak_unimport(bgp); + bgp_vpn_release_label(bgp, AFI_IP, true); + bgp_vpn_release_label(bgp, AFI_IP6, true); + hook_call(bgp_inst_delete, bgp); FOREACH_AFI_SAFI (afi, safi) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 2d7396ad6c..47214e52e5 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1728,7 +1728,8 @@ struct peer { uint32_t stat_pfx_cluster_loop; uint32_t stat_pfx_nh_invalid; uint32_t stat_pfx_dup_withdraw; - uint32_t stat_upd_7606; /* RFC7606: treat-as-withdraw */ + uint32_t stat_pfx_withdraw; /* RFC7606: treat-as-withdraw */ + uint32_t stat_pfx_discard; /* The number of prefixes with discarded attributes */ uint64_t stat_pfx_loc_rib; /* RFC7854 : Number of routes in Loc-RIB */ uint64_t stat_pfx_adj_rib_in; /* RFC7854 : Number of routes in Adj-RIBs-In */ diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 93f7bbf753..652efee89a 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -2065,12 +2065,6 @@ void cli_show_isis_srv6_locator(struct vty *vty, const struct lyd_node *dnode, vty_out(vty, " locator %s\n", yang_dnode_get_string(dnode, NULL)); } -void cli_show_isis_srv6_locator_end(struct vty *vty, - const struct lyd_node *dnode) -{ - vty_out(vty, " exit\n"); -} - /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/enabled */ @@ -2118,6 +2112,11 @@ void cli_show_isis_srv6_enabled(struct vty *vty, const struct lyd_node *dnode, vty_out(vty, " segment-routing srv6\n"); } +void cli_show_isis_srv6_end(struct vty *vty, const struct lyd_node *dnode) +{ + vty_out(vty, " exit\n"); +} + /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd */ @@ -2248,6 +2247,11 @@ void cli_show_isis_srv6_node_msd(struct vty *vty, const struct lyd_node *dnode, yang_dnode_get_uint8(dnode, "max-end-d")); } +void cli_show_isis_srv6_node_msd_end(struct vty *vty, const struct lyd_node *dnode) +{ + vty_out(vty, " exit\n"); +} + /* * XPath: /frr-isisd:isis/instance/segment-routing-srv6/interface */ diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index 8608d2b9bd..3024bb57ea 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -861,6 +861,12 @@ const struct frr_yang_module_info frr_isisd_info = { }, }, { + .xpath = "/frr-isisd:isis/instance/segment-routing-srv6", + .cbs = { + .cli_show_end = cli_show_isis_srv6_end, + }, + }, + { .xpath = "/frr-isisd:isis/instance/segment-routing-srv6/enabled", .cbs = { .modify = isis_instance_segment_routing_srv6_enabled_modify, @@ -873,7 +879,6 @@ const struct frr_yang_module_info frr_isisd_info = { .modify = isis_instance_segment_routing_srv6_locator_modify, .destroy = isis_instance_segment_routing_srv6_locator_destroy, .cli_show = cli_show_isis_srv6_locator, - .cli_show_end = cli_show_isis_srv6_locator_end, }, }, { @@ -904,6 +909,7 @@ const struct frr_yang_module_info frr_isisd_info = { .xpath = "/frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd", .cbs = { .cli_show = cli_show_isis_srv6_node_msd, + .cli_show_end = cli_show_isis_srv6_node_msd_end, }, }, { diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index 1bf95e3db3..10b3bd4009 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -322,6 +322,7 @@ int isis_instance_flex_algo_affinity_mapping_value_modify( struct nb_cb_modify_args *args); int isis_instance_flex_algo_affinity_mapping_value_destroy( struct nb_cb_destroy_args *args); +void cli_show_isis_srv6_end(struct vty *vty, const struct lyd_node *dnode); int isis_instance_segment_routing_srv6_enabled_modify( struct nb_cb_modify_args *args); void cli_show_isis_srv6_enabled(struct vty *vty, const struct lyd_node *dnode, @@ -332,8 +333,6 @@ int isis_instance_segment_routing_srv6_locator_destroy( struct nb_cb_destroy_args *args); void cli_show_isis_srv6_locator(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); -void cli_show_isis_srv6_locator_end(struct vty *vty, - const struct lyd_node *dnode); int isis_instance_segment_routing_srv6_msd_node_msd_max_segs_left_modify( struct nb_cb_modify_args *args); int isis_instance_segment_routing_srv6_msd_node_msd_max_end_pop_modify( @@ -344,6 +343,7 @@ int isis_instance_segment_routing_srv6_msd_node_msd_max_end_d_modify( struct nb_cb_modify_args *args); void cli_show_isis_srv6_node_msd(struct vty *vty, const struct lyd_node *dnode, bool show_defaults); +void cli_show_isis_srv6_node_msd_end(struct vty *vty, const struct lyd_node *dnode); int isis_instance_segment_routing_srv6_interface_modify( struct nb_cb_modify_args *args); void cli_show_isis_srv6_interface(struct vty *vty, const struct lyd_node *dnode, diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c index 32f28a5774..7f7a5d9a8e 100644 --- a/mgmtd/mgmt_fe_adapter.c +++ b/mgmtd/mgmt_fe_adapter.c @@ -190,7 +190,7 @@ static void mgmt_fe_cleanup_session(struct mgmt_fe_session_ctx **sessionp) assert(session->adapter->refcount > 1); mgmt_fe_adapter_unlock(&session->adapter); } - + darr_free_free(session->notify_xpaths); hash_release(mgmt_fe_sessions, session); XFREE(MTYPE_MGMTD_FE_SESSION, session); *sessionp = NULL; 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 adc92f59fe..c6f1b6193b 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 @@ -142,6 +142,27 @@ def test_bgp_path_attribute_discard(): result is None ), "Failed to discard path attributes (atomic-aggregate, community)" + def _bgp_check_attributes_discarded_stats(): + output = json.loads(r1.vtysh_cmd("show bgp neighbor json")) + expected = { + "10.0.0.254": { + "prefixStats": { + "inboundFiltered": 0, + "aspathLoop": 0, + "originatorLoop": 0, + "clusterLoop": 0, + "invalidNextHop": 0, + "withdrawn": 0, + "attributesDiscarded": 3, + } + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_attributes_discarded_stats) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert result is None, "Discarded path attributes count is not as expected" + def _bgp_check_if_aigp_invalid_attribute_discarded(): output = json.loads(r2.vtysh_cmd("show bgp ipv4 unicast json detail")) expected = { diff --git a/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py b/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py index a9d678a42d..4f6472f3c5 100644 --- a/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py +++ b/tests/topotests/bgp_path_attribute_treat_as_withdraw/test_bgp_path_attribute_treat_as_withdraw.py @@ -134,6 +134,27 @@ def test_bgp_path_attribute_treat_as_withdraw(): _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to withdraw prefixes with atomic-aggregate attribute" + def _bgp_check_attributes_withdrawn_stats(): + output = json.loads(r2.vtysh_cmd("show bgp neighbor json")) + expected = { + "10.0.0.1": { + "prefixStats": { + "inboundFiltered": 0, + "aspathLoop": 0, + "originatorLoop": 0, + "clusterLoop": 0, + "invalidNextHop": 0, + "withdrawn": 1, + "attributesDiscarded": 0, + } + } + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_attributes_withdrawn_stats) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5) + assert result is None, "Withdrawn prefix count is not as expected" + def test_memory_leak(): "Run the memory leak test and report results." diff --git a/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json b/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json new file mode 100644 index 0000000000..016c019d10 --- /dev/null +++ b/tests/topotests/bgp_rpki_topo1/r2/bgp_rpki_valid.json @@ -0,0 +1,70 @@ +{ + "vrfId": 0, + "vrfName": "default", + "tableVersion": 3, + "routerId": "192.0.2.2", + "defaultLocPrf": 100, + "localAS": 65002, + "routes": { + "198.51.100.0/24": [ + { + "origin": "IGP", + "metric": 0, + "valid": true, + "version": 2, + "rpkiValidationState": "valid", + "bestpath": { + "overall": true, + "selectionReason": "First path received" + }, + "nexthops": [ + { + "ip": "192.0.2.1", + "hostname": "r1", + "afi": "ipv4", + "metric": 0, + "accessible": true, + "used": true + } + ], + "peer": { + "peerId": "192.0.2.1", + "routerId": "192.0.2.1", + "hostname": "r1", + "type": "external" + } + } + ], + "203.0.113.0/24": [ + { + "origin": "IGP", + "metric": 0, + "valid": true, + "version": 3, + "rpkiValidationState": "valid", + "bestpath": { + "overall": true, + "selectionReason": "First path received" + }, + "nexthops": [ + { + "ip": "192.0.2.1", + "hostname": "r1", + "afi": "ipv4", + "metric": 0, + "accessible": true, + "used": true + } + ], + "peer": { + "peerId": "192.0.2.1", + "routerId": "192.0.2.1", + "hostname": "r1", + "type": "external" + } + } + ] + }, + "totalRoutes": 3, + "totalPaths": 3 +}
\ No newline at end of file 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 7b40bbdae8..5b775aa6cb 100644 --- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py +++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py @@ -101,6 +101,16 @@ def show_rpki_prefixes(rname, expected, vrf=None): return topotest.json_cmp(output, expected) +def show_rpki_valid(rname, expected, vrf=None): + tgen = get_topogen() + + cmd = "show bgp ipv4 detail json" + + output = json.loads(tgen.gears[rname].vtysh_cmd(cmd)) + + return topotest.json_cmp(output, expected) + + def show_bgp_ipv4_table_rpki(rname, rpki_state, expected, vrf=None): tgen = get_topogen() @@ -123,6 +133,25 @@ def show_bgp_ipv4_table_rpki(rname, rpki_state, expected, vrf=None): return topotest.json_cmp(output, expected) +def test_show_bgp_rpki_prefixes_valid(): + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + for rname in ["r1", "r3"]: + logger.info("{}: checking if rtrd is running".format(rname)) + if rtrd_process[rname].poll() is not None: + pytest.skip(tgen.errors) + + rname = "r2" + expected = open(os.path.join(CWD, "{}/bgp_rpki_valid.json".format(rname))).read() + expected_json = json.loads(expected) + test_func = functools.partial(show_rpki_valid, rname, expected_json) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to see RPKI on {}".format(rname) + + def test_show_bgp_rpki_prefixes(): tgen = get_topogen() diff --git a/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/__init__.py b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/__init__.py diff --git a/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r1/frr.conf b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r1/frr.conf new file mode 100644 index 0000000000..7daf335aab --- /dev/null +++ b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r1/frr.conf @@ -0,0 +1,117 @@ +interface r1-eth1 vrf vrf1 + ip address 173.31.1.1/32 +! +interface r1-eth2 vrf vrf2 + ip address 173.31.1.2/32 +! +interface r1-eth3 vrf vrf3 + ip address 173.31.1.3/32 +! +interface r1-eth4 vrf vrf4 + ip address 173.31.1.4/32 +! +interface r1-eth5 vrf vrf5 + ip address 173.31.1.5/32 +! + +interface r1-eth0 + ip address 192.168.0.1/24 +! + +interface r1-eth6 + ip address 193.170.0.1/24 + +interface lo + ip address 11.11.11.11/32 +! +router ospf + ospf router-id 11.11.11.11 + network 193.170.0.0/24 area 0.0.0.0 + network 11.11.11.11/32 area 0.0.0.0 + redistribute connected +exit +! +mpls ldp + router-id 11.11.11.11 + ! + address-family ipv4 + discovery transport-address 11.11.11.11 + ! + interface r1-eth6 + exit + ! + exit-address-family + ! +exit +! +bgp route-map delay-timer 1 +router bgp 65500 + bgp router-id 192.0.2.1 + no bgp ebgp-requires-policy + neighbor 192.168.0.2 remote-as 65501 + address-family ipv4 unicast + no neighbor 192.168.0.2 activate + exit-address-family + address-family ipv4 vpn + neighbor 192.168.0.2 activate + exit-address-family +! +router bgp 65500 vrf vrf1 + bgp router-id 192.0.2.1 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:1 + rt vpn both 53:1 + export vpn + import vpn + exit-address-family +! +router bgp 65500 vrf vrf2 + bgp router-id 192.0.2.1 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:2 + rt vpn both 53:2 + export vpn + import vpn + exit-address-family +! +router bgp 65500 vrf vrf3 + bgp router-id 192.0.2.1 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:3 + rt vpn both 53:3 + export vpn + import vpn + exit-address-family +! +router bgp 65500 vrf vrf4 + bgp router-id 192.0.2.1 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:4 + rt vpn both 53:4 + export vpn + import vpn + exit-address-family +! +router bgp 65500 vrf vrf5 + bgp router-id 192.0.2.1 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:5 + rt vpn both 53:5 + export vpn + import vpn + exit-address-family +! + +interface r1-eth0 + mpls bgp forwarding +!
\ No newline at end of file diff --git a/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r2/frr.conf b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r2/frr.conf new file mode 100644 index 0000000000..6facebe40e --- /dev/null +++ b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r2/frr.conf @@ -0,0 +1,88 @@ +interface r2-eth1 vrf vrf1 + ip address 173.31.0.1/32 +! +interface r2-eth2 vrf vrf2 + ip address 173.31.0.2/32 +! +interface r2-eth3 vrf vrf3 + ip address 173.31.0.3/32 +! +interface r2-eth4 vrf vrf4 + ip address 173.31.0.4/32 +! +interface r2-eth5 vrf vrf5 + ip address 173.31.0.5/32 +! +interface r2-eth0 + ip address 192.168.0.2/24 +! +router bgp 65501 + bgp router-id 192.0.2.2 + no bgp ebgp-requires-policy + neighbor 192.168.0.1 remote-as 65500 + address-family ipv4 unicast + no neighbor 192.168.0.1 activate + exit-address-family + address-family ipv4 vpn + neighbor 192.168.0.1 activate + exit-address-family +! +router bgp 65501 vrf vrf1 + bgp router-id 192.0.2.2 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:1 + rt vpn both 53:1 + export vpn + import vpn + exit-address-family +! +router bgp 65501 vrf vrf2 + bgp router-id 192.0.2.2 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:2 + rt vpn both 53:2 + export vpn + import vpn + exit-address-family +! +router bgp 65501 vrf vrf3 + bgp router-id 192.0.2.2 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:3 + rt vpn both 53:3 + export vpn + import vpn + exit-address-family +! +router bgp 65501 vrf vrf4 + bgp router-id 192.0.2.2 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:4 + rt vpn both 53:4 + export vpn + import vpn + exit-address-family +! +router bgp 65501 vrf vrf5 + bgp router-id 192.0.2.2 + address-family ipv4 unicast + redistribute connected + label vpn export auto + rd vpn export 445:5 + rt vpn both 53:5 + export vpn + import vpn + exit-address-family +! + +interface r2-eth0 + mpls bgp forwarding +! diff --git a/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r3/frr.conf b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r3/frr.conf new file mode 100644 index 0000000000..8f49cdfe0c --- /dev/null +++ b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/r3/frr.conf @@ -0,0 +1,32 @@ +interface r3-eth0 + ip address 193.170.0.2/24 +! +interface lo + ip address 33.33.33.33/32 +! +interface r3-eth1 + ip address 180.170.0.2/32 +! +interface r3-eth2 + ip address 180.170.0.3/32 +! +router ospf + ospf router-id 33.33.33.33 + network 193.170.0.0/24 area 0.0.0.0 + network 33.33.33.33/32 area 0.0.0.0 + redistribute connected +exit +! +mpls ldp + router-id 33.33.33.33 + ! + address-family ipv4 + discovery transport-address 33.33.33.33 + ! + interface r3-eth0 + exit + ! + exit-address-family + ! +exit +!
\ No newline at end of file diff --git a/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/test_bgp_vpnv4_vpn_auto.py b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/test_bgp_vpnv4_vpn_auto.py new file mode 100644 index 0000000000..ed3cdca2f9 --- /dev/null +++ b/tests/topotests/bgp_vpnv4_ebgp_vpn_auto/test_bgp_vpnv4_vpn_auto.py @@ -0,0 +1,191 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: ISC + +# +# test_bgp_vpnv4_vpn_auto.py +# +# Copyright (c) 2024 by Varun Hegde +# + +""" + test_bgp_vpnv4_vpn_auto.py: Test the FRR BGP daemon with BGP VPN session with label export auto +""" + +import os +import sys +import json +import functools +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.bgpcheck import ( + check_show_bgp_vpn_prefix_found, + check_show_bgp_vpn_prefix_not_found, +) +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 3 routers. + tgen.add_router("r1") + tgen.add_router("r2") + tgen.add_router("r3") + + + for i in range(6): + switch = tgen.add_switch("s{0}".format(i)) + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + #create a singiluar link between R2 -- R3 + switch = tgen.add_switch("s6") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r3"]) + + for i in range(7, 9): + switch = tgen.add_switch("s{0}".format(i)) + switch.add_link(tgen.gears["r3"]) + + + +def _populate_iface(): + tgen = get_topogen() + cmds_list = [ + "ip link add vrf{} type vrf table {}", + "ip link set dev vrf{} up", + "ip link set dev r1-eth{} master vrf{}", + "echo 1 > /proc/sys/net/mpls/conf/r1-eth{}/input", + ] + cmds_list2 = [ + "ip link add vrf{} type vrf table {}", + "ip link set dev vrf{} up", + "ip link set dev r2-eth{} master vrf{}", + "echo 1 > /proc/sys/net/mpls/conf/r2-eth{}/input", + ] + + for i in range(1, 6): + for cmd in cmds_list: + input = cmd.format(i, i) + logger.info("input: " + cmd) + output = tgen.net["r1"].cmd(cmd.format(i, i)) + logger.info("output: " + output) + + for cmd in cmds_list2: + input = cmd.format(i, i) + logger.info("input: " + cmd) + output = tgen.net["r2"].cmd(cmd.format(i, i)) + logger.info("output: " + output) + +def setup_module(mod): + "Sets up the pytest environment" + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + _populate_iface() + + for rname, router in router_list.items(): + router.load_frr_config(os.path.join(CWD, "{}/frr.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_labelpool_release(): + """ + Check that once we remove BGP VPN sesson + label pool structure ( allocated_map ) gets released properly or not + """ + tgen = get_topogen() + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + # Just waiting for BGP VPN session to converge + logger.info("Waiting for BGP VPN sessions to converge and label pools to get initialised") + router = tgen.gears["r1"] + + def _bgp_converge(): + output = json.loads( + router.vtysh_cmd("show bgp labelpool summary json") + ) + expected = {"ledger":5,"inUse":5,"requests":0,"labelChunks":1,"pending":0,"reconnects":1} + 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, "Failed to see BGP Labelpool initialised" + + + # checking the initial label pool chunk's free labels + logger.info("checking the initial label pool chunk's free labels") + expected = [{"first":80,"last":207,"size":128,"numberFree":123}] + test_func = functools.partial( + topotest.router_json_cmp, + router, + "show bgp label chunks json", + expected, + ) + + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = '"{}" JSON output mismatches'.format(router.name) + assert result is None, assertmsg + + + # Test case : check whether label got released or not + logger.info( + "Remove multiple vpn session and check whether label got released or no" + ) + router.vtysh_cmd( + """ + configure terminal + no router bgp 65500 vrf vrf1 + no router bgp 65500 vrf vrf2 + """ + ) + expected = [{"first":80,"last":207,"size":128,"numberFree":125}] + test_func = functools.partial( + topotest.router_json_cmp, + router, + "show bgp label chunks json", + expected, + ) + + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + 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)) diff --git a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-default.json b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-default.json index 948f4e6c23..da2d8e3625 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-default.json +++ b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-default.json @@ -39,7 +39,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -68,7 +68,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -97,7 +97,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -126,7 +126,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -238,7 +238,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -250,7 +252,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -265,7 +267,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -277,7 +281,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -292,7 +296,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -304,7 +310,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -319,7 +325,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -331,7 +339,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -369,7 +377,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -398,7 +406,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -427,7 +435,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -456,7 +464,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -480,7 +488,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -492,7 +502,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -507,7 +517,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -519,7 +531,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -534,7 +546,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -546,7 +560,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -561,7 +575,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -573,7 +589,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -589,3 +605,4 @@ ] } } + diff --git a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-nokey.json b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-nokey.json index 30daecf16e..b4abdde465 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-nokey.json +++ b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-nokey.json @@ -38,8 +38,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight":1 + "fib": [null], + "weight": 1 } ] } @@ -67,8 +67,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight":1 + "fib": [null], + "weight": 1 } ] } @@ -96,8 +96,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight":1 + "fib": [null], + "weight": 1 } ] } @@ -125,8 +125,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -238,7 +238,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -249,8 +251,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight":1 + "fib": [null], + "weight": 1 } ] } @@ -265,7 +267,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -276,8 +280,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight":1 + "fib": [null], + "weight": 1 } ] } @@ -292,7 +296,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -303,8 +309,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -319,7 +325,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -330,8 +338,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -368,8 +376,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -397,8 +405,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -426,8 +434,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -455,8 +463,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -480,7 +488,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -491,8 +501,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -507,7 +517,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -518,8 +530,8 @@ "gateway": "", "interface": "r1-eth0", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -534,7 +546,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -545,8 +559,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -561,7 +575,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -572,8 +588,8 @@ "gateway": "", "interface": "r1-eth1", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -623,8 +639,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -652,8 +668,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -681,8 +697,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -710,8 +726,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -823,7 +839,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -834,8 +852,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -850,7 +868,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -861,8 +881,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -877,7 +897,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -888,8 +910,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -904,7 +926,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -915,8 +939,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -953,8 +977,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -982,8 +1006,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -1011,8 +1035,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -1040,8 +1064,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -1065,7 +1089,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1076,8 +1102,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -1092,7 +1118,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1103,8 +1131,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -1119,7 +1147,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1130,8 +1160,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } @@ -1146,7 +1176,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1157,8 +1189,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null], - "weight": 1 + "fib": [null], + "weight": 1 } ] } diff --git a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-red.json b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-red.json index cfabd49c45..5d61b9865f 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-red.json +++ b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-red.json @@ -38,7 +38,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -66,7 +67,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -94,7 +96,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -122,7 +125,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -234,7 +238,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -245,7 +251,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -260,7 +267,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -271,7 +280,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -286,7 +296,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -297,7 +309,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -312,7 +325,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -323,7 +338,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -360,7 +376,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -388,7 +405,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -416,7 +434,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -444,7 +463,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -468,7 +488,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -479,7 +501,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -494,7 +517,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -505,7 +530,8 @@ "gateway": "", "interface": "r1-eth2", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -520,7 +546,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -531,7 +559,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } @@ -546,7 +575,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -557,7 +588,8 @@ "gateway": "", "interface": "r1-eth3", "active": [null], - "fib": [null] + "fib": [null], + "weight": 1 } ] } diff --git a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra-ribs.json b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra-ribs.json index b1124bd7bb..86e67a9e23 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra-ribs.json +++ b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra-ribs.json @@ -35,7 +35,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -64,7 +64,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -93,7 +93,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -122,7 +122,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -234,7 +234,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -246,7 +248,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -261,7 +263,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -273,7 +277,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -288,7 +292,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -300,7 +306,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -315,7 +321,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -327,7 +335,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -365,7 +373,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -394,7 +402,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -423,7 +431,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -452,7 +460,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -476,7 +484,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -488,7 +498,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -503,7 +513,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -515,7 +527,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -530,7 +542,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -542,7 +556,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -557,7 +571,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -569,7 +585,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } diff --git a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra.json b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra.json index 70c8798b31..86e67a9e23 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra.json +++ b/tests/topotests/mgmt_oper/oper-results/result-lib-vrf-zebra.json @@ -234,7 +234,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -261,7 +263,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -288,7 +292,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -315,7 +321,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -476,7 +484,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -503,7 +513,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -530,7 +542,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -557,7 +571,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/oper-results/result-lib.json b/tests/topotests/mgmt_oper/oper-results/result-lib.json index 0b2a9fa427..b4abdde465 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-lib.json +++ b/tests/topotests/mgmt_oper/oper-results/result-lib.json @@ -39,7 +39,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -68,7 +68,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -97,7 +97,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -126,7 +126,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -238,7 +238,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -250,7 +252,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -265,7 +267,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -277,7 +281,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -292,7 +296,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -304,7 +310,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -319,7 +325,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -331,7 +339,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -369,7 +377,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -398,7 +406,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -427,7 +435,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -456,7 +464,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -480,7 +488,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -492,7 +502,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -507,7 +517,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -519,7 +531,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -534,7 +546,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -546,7 +560,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -561,7 +575,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -573,7 +589,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -624,7 +640,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -653,7 +669,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -682,7 +698,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -711,7 +727,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -823,7 +839,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -835,7 +853,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -850,7 +868,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -862,7 +882,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -877,7 +897,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -889,7 +911,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -904,7 +926,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -916,7 +940,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -954,7 +978,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -983,7 +1007,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -1012,7 +1036,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -1041,7 +1065,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -1065,7 +1089,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1077,7 +1103,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -1092,7 +1118,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1104,7 +1132,7 @@ "interface": "r1-eth2", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -1119,7 +1147,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1131,7 +1161,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -1146,7 +1176,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -1158,7 +1190,7 @@ "interface": "r1-eth3", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } diff --git a/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-ipv4-unicast.json b/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-ipv4-unicast.json index 769c1f73a5..e313a158a3 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-ipv4-unicast.json +++ b/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-ipv4-unicast.json @@ -35,7 +35,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -64,7 +64,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -93,7 +93,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -122,7 +122,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } diff --git a/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-nokeys.json b/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-nokeys.json index c740f592f7..86e67a9e23 100644 --- a/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-nokeys.json +++ b/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-nokeys.json @@ -35,7 +35,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -64,7 +64,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -93,7 +93,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -122,7 +122,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -234,7 +234,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -246,7 +248,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -261,7 +263,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -273,7 +277,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -288,7 +292,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -300,7 +306,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -315,7 +321,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -327,7 +335,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -365,7 +373,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -394,7 +402,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -423,7 +431,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -476,7 +484,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -488,7 +498,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -503,7 +513,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -515,7 +527,7 @@ "interface": "r1-eth0", "active": [null], "fib": [null], - "weight": 1 + "weight": 1 } ] } @@ -530,7 +542,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -542,7 +556,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } @@ -557,7 +571,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -569,7 +585,7 @@ "interface": "r1-eth1", "active": [null], "fib": [null], - "weight":1 + "weight": 1 } ] } diff --git a/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-route-nokey.json b/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-route-nokey.json new file mode 100644 index 0000000000..e313a158a3 --- /dev/null +++ b/tests/topotests/mgmt_oper/oper-results/result-ribs-rib-route-nokey.json @@ -0,0 +1,229 @@ +{ + "frr-vrf:lib": { + "vrf": [ + { + "name": "default", + "frr-zebra:zebra": { + "ribs": { + "rib": [ + { + "afi-safi-name": "frr-routing:ipv4-unicast", + "table-id": 254, + "route": [ + { + "prefix": "0.0.0.0/0" + }, + { + "prefix": "1.1.1.0/24", + "route-entry": [ + { + "protocol": "connected", + "distance": 0, + "metric": 0, + "selected": [null], + "installed": [null], + "internal-flags": 8, + "internal-status": 16, + "uptime": "rubout", + "nexthop-group": { + "id": "rubout", + "nexthop": [ + { + "nh-type": "ifindex", + "vrf": "rubout", + "gateway": "", + "interface": "r1-eth0", + "active": [null], + "fib": [null], + "weight": 1 + } + ] + } + } + ] + }, + { + "prefix": "1.1.1.1/32", + "route-entry": [ + { + "protocol": "local", + "distance": 0, + "metric": 0, + "selected": [null], + "installed": [null], + "internal-flags": 8, + "internal-status": 16, + "uptime": "rubout", + "nexthop-group": { + "id": "rubout", + "nexthop": [ + { + "nh-type": "ifindex", + "vrf": "rubout", + "gateway": "", + "interface": "r1-eth0", + "active": [null], + "fib": [null], + "weight": 1 + } + ] + } + } + ] + }, + { + "prefix": "2.2.2.0/24", + "route-entry": [ + { + "protocol": "connected", + "distance": 0, + "metric": 0, + "selected": [null], + "installed": [null], + "internal-flags": 8, + "internal-status": 16, + "uptime": "rubout", + "nexthop-group": { + "id": "rubout", + "nexthop": [ + { + "nh-type": "ifindex", + "vrf": "rubout", + "gateway": "", + "interface": "r1-eth1", + "active": [null], + "fib": [null], + "weight": 1 + } + ] + } + } + ] + }, + { + "prefix": "2.2.2.1/32", + "route-entry": [ + { + "protocol": "local", + "distance": 0, + "metric": 0, + "selected": [null], + "installed": [null], + "internal-flags": 8, + "internal-status": 16, + "uptime": "rubout", + "nexthop-group": { + "id": "rubout", + "nexthop": [ + { + "nh-type": "ifindex", + "vrf": "rubout", + "gateway": "", + "interface": "r1-eth1", + "active": [null], + "fib": [null], + "weight": 1 + } + ] + } + } + ] + }, + { + "prefix": "11.0.0.0/8", + "route-entry": [ + { + "protocol": "static", + "distance": 1, + "metric": 0, + "selected": [null], + "installed": [null], + "internal-flags": 73, + "internal-status": 16, + "uptime": "rubout", + "nexthop-group": { + "id": "rubout", + "nexthop": [ + { + "nh-type": "blackhole", + "vrf": "rubout", + "gateway": "", + "interface": " ", + "bh-type": "null", + "active": [null], + "fib": [null], + "weight": 1 + } + ] + } + } + ] + }, + { + "prefix": "11.11.11.11/32", + "route-entry": [ + { + "protocol": "static", + "distance": 1, + "metric": 0, + "selected": [null], + "installed": [null], + "internal-flags": 73, + "internal-status": 16, + "uptime": "rubout", + "nexthop-group": { + "id": "rubout", + "nexthop": [ + { + "nh-type": "ip4-ifindex", + "vrf": "rubout", + "gateway": "1.1.1.2", + "interface": "r1-eth0", + "active": [null], + "fib": [null], + "weight": 1 + } + ] + } + } + ] + }, + { + "prefix": "12.12.12.12/32", + "route-entry": [ + { + "protocol": "static", + "distance": 1, + "metric": 0, + "selected": [null], + "installed": [null], + "internal-flags": 73, + "internal-status": 16, + "uptime": "rubout", + "nexthop-group": { + "id": "rubout", + "nexthop": [ + { + "nh-type": "ip4-ifindex", + "vrf": "rubout", + "gateway": "2.2.2.2", + "interface": "r1-eth1", + "active": [null], + "fib": [null], + "weight": 1 + } + ] + } + } + ] + } + ] + } + ] + } + } + } + ] + } +} + diff --git a/tests/topotests/mgmt_oper/oper.py b/tests/topotests/mgmt_oper/oper.py index f54e64ae18..bca452d011 100644 --- a/tests/topotests/mgmt_oper/oper.py +++ b/tests/topotests/mgmt_oper/oper.py @@ -77,7 +77,13 @@ def _do_oper_test(tgen, qr, seconds_left=None): # Don't use this for now. dd_json_cmp = None - expected = open(qr[1], encoding="ascii").read() + if isinstance(qr[1], str): + expected = open(qr[1], encoding="ascii").read() + expected_alt = None + else: + expected = open(qr[1][0], encoding="ascii").read() + expected_alt = open(qr[1][1], encoding="ascii").read() + output = r1.cmd_nostatus(qcmd.format(qr[0], qr[2] if len(qr) > 2 else "")) diag = logging.debug if seconds_left else logging.warning @@ -90,6 +96,7 @@ def _do_oper_test(tgen, qr, seconds_left=None): try: ejson = json.loads(expected) + ejson_alt = json.loads(expected_alt) if expected_alt is not None else None except json.decoder.JSONDecodeError as error: logging.error( "Error decoding json exp result: %s\noutput:\n%s", error, expected @@ -99,6 +106,8 @@ def _do_oper_test(tgen, qr, seconds_left=None): if dd_json_cmp: cmpout = json_cmp(ojson, ejson, exact_match=True) + if cmpout and ejson_alt is not None: + cmpout = json_cmp(ojson, ejson_alt, exact_match=True) if cmpout: diag( "-------DIFF---------\n%s\n---------DIFF----------", @@ -106,6 +115,8 @@ def _do_oper_test(tgen, qr, seconds_left=None): ) else: cmpout = tt_json_cmp(ojson, ejson, exact=True) + if cmpout and ejson_alt is not None: + cmpout = tt_json_cmp(ojson, ejson_alt, exact=True) if cmpout: diag( "-------EXPECT--------\n%s\n------END-EXPECT------", @@ -118,6 +129,7 @@ def _do_oper_test(tgen, qr, seconds_left=None): diag("----diff---\n{}".format(cmpout)) diag("Command: {}".format(qcmd.format(qr[0], qr[2] if len(qr) > 2 else ""))) diag("File: {}".format(qr[1])) + cmpout = str(cmpout) return cmpout @@ -127,7 +139,8 @@ def do_oper_test(tgen, query_results): step(f"Perform query '{qr[0]}'", reset=reset) if reset: reset = False - _do_oper_test(tgen, qr) + ret = _do_oper_test(tgen, qr) + assert ret is None, "Unexpected diff: " + str(ret) def get_ip_networks(super_prefix, count): diff --git a/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-wd-trim-empty-label.json b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-wd-trim-empty-label.json new file mode 100644 index 0000000000..efd7e8c684 --- /dev/null +++ b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-wd-trim-empty-label.json @@ -0,0 +1,3 @@ +{ + "frr-zebra:evpn-mh": {} +} diff --git a/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-wd-trim.json b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-wd-trim.json index efd7e8c684..2c63c08510 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-wd-trim.json +++ b/tests/topotests/mgmt_oper/simple-results/result-intf-eth0-wd-trim.json @@ -1,3 +1,2 @@ { - "frr-zebra:evpn-mh": {} } diff --git a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-default.json b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-default.json index f85b163bd6..19295870d5 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-default.json +++ b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-default.json @@ -121,7 +121,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -148,7 +150,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-nokey.json b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-nokey.json index e2cfec9724..f0bde048f2 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-nokey.json +++ b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-nokey.json @@ -121,7 +121,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -148,7 +150,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -282,7 +286,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -309,7 +315,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-red.json b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-red.json index 3567f35a34..8b632bac66 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-red.json +++ b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-red.json @@ -92,7 +92,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -119,7 +121,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra-ribs.json b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra-ribs.json index d9ca58d25d..678a80ab97 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra-ribs.json +++ b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra-ribs.json @@ -117,7 +117,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -144,7 +146,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra.json b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra.json index d9ca58d25d..678a80ab97 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra.json +++ b/tests/topotests/mgmt_oper/simple-results/result-lib-vrf-zebra.json @@ -117,7 +117,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -144,7 +146,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/simple-results/result-lib.json b/tests/topotests/mgmt_oper/simple-results/result-lib.json index e2cfec9724..f0bde048f2 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-lib.json +++ b/tests/topotests/mgmt_oper/simple-results/result-lib.json @@ -121,7 +121,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -148,7 +150,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -282,7 +286,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -309,7 +315,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/simple-results/result-ribs-rib-nokeys.json b/tests/topotests/mgmt_oper/simple-results/result-ribs-rib-nokeys.json index d9ca58d25d..678a80ab97 100644 --- a/tests/topotests/mgmt_oper/simple-results/result-ribs-rib-nokeys.json +++ b/tests/topotests/mgmt_oper/simple-results/result-ribs-rib-nokeys.json @@ -117,7 +117,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", @@ -144,7 +146,9 @@ "distance": 0, "metric": 0, "selected": [null], + "installed": [null], "internal-flags": 8, + "internal-status": 16, "uptime": "rubout", "nexthop-group": { "id": "rubout", diff --git a/tests/topotests/mgmt_oper/test_oper.py b/tests/topotests/mgmt_oper/test_oper.py index e4ceabf352..23529bc75e 100644 --- a/tests/topotests/mgmt_oper/test_oper.py +++ b/tests/topotests/mgmt_oper/test_oper.py @@ -107,6 +107,7 @@ vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="default"]/frr-zebra:zebra/ri for f in ${resdir}/result-*; do sed -i -e 's/"uptime": ".*"/"uptime": "rubout"/;s/"id": [0-9][0-9]*/"id": "rubout"/' $f + sed -i -e 's/"phy-address": ".*"/"phy-address": "rubout"/' $f sed -i -e 's/"if-index": [0-9][0-9]*/"if-index": "rubout"/' $f sed -i -e 's,"vrf": "[0-9]*","vrf": "rubout",' $f done diff --git a/tests/topotests/mgmt_oper/test_simple.py b/tests/topotests/mgmt_oper/test_simple.py index 2b3d6ff6a5..237f7d57d5 100644 --- a/tests/topotests/mgmt_oper/test_simple.py +++ b/tests/topotests/mgmt_oper/test_simple.py @@ -154,7 +154,11 @@ def test_oper_simple(tgen): ), ( '/frr-interface:lib/interface[name="r1-eth0"]/frr-zebra:zebra/evpn-mh', - "simple-results/result-intf-eth0-wd-trim.json", + ( + # Output is different between libyang2 and libyang3+ + "simple-results/result-intf-eth0-wd-trim.json", + "simple-results/result-intf-eth0-wd-trim-empty-label.json", + ), "with-config exact with-defaults trim", ), ( @@ -181,7 +185,7 @@ vtysh -c 'show mgmt get-data /frr-vrf:lib' > ${resdir}/result-lib.json vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf' > ${resdir}/result-lib-vrf-nokey.json vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="default"]' > ${resdir}/result-lib-vrf-default.json vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="red"]' > ${resdir}/result-lib-vrf-red.json -vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="default"]/frr-zebra:zebra' > ${resdir}/result-lib-vrf-ebra.json +vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="default"]/frr-zebra:zebra' > ${resdir}/result-lib-vrf-zebra.json vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="default"]/frr-zebra:zebra/ribs' > ${resdir}/result-lib-vrf-zebra-ribs.json vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="default"]/frr-zebra:zebra/ribs/rib' > ${resdir}/result-ribs-rib-nokeys.json vtysh -c 'show mgmt get-data /frr-vrf:lib/vrf[name="default"]/frr-zebra:zebra/ribs/rib[afi-safi-name="frr-routing:ipv4-unicast"][table-id="254"]' > ${resdir}/result-ribs-rib-ipv4-unicast.json diff --git a/tests/topotests/srv6_static_route/test_srv6_route.py b/tests/topotests/srv6_static_route/test_srv6_route.py index f23e199d4a..e26775daf7 100755 --- a/tests/topotests/srv6_static_route/test_srv6_route.py +++ b/tests/topotests/srv6_static_route/test_srv6_route.py @@ -27,7 +27,7 @@ from lib import topotest from lib.topogen import Topogen, TopoRouter, get_topogen from lib.topolog import logger -pytestmark = [pytest.mark.bgpd, pytest.mark.sharpd] +pytestmark = [pytest.mark.staticd] def open_json_file(filename): diff --git a/tools/frr-reload.py b/tools/frr-reload.py index 2bb364f32b..2ea63a290e 100755 --- a/tools/frr-reload.py +++ b/tools/frr-reload.py @@ -279,7 +279,11 @@ ctx_keywords = { "policy ": {"candidate-path ": {}}, "pcep": {"pcc": {}, "pce ": {}, "pce-config ": {}}, }, - "srv6": {"locators": {"locator ": {}}, "encapsulation": {}}, + "srv6": { + "locators": {"locator ": {}}, + "encapsulation": {}, + "formats": {"format": {}}, + }, }, "nexthop-group ": {}, "route-map ": {}, diff --git a/tools/gen_northbound_callbacks.c b/tools/gen_northbound_callbacks.c index 046dc9e99e..516743acab 100644 --- a/tools/gen_northbound_callbacks.c +++ b/tools/gen_northbound_callbacks.c @@ -11,6 +11,7 @@ #include <unistd.h> +#include "darr.h" #include "yang.h" #include "northbound.h" @@ -19,7 +20,7 @@ static bool static_cbs; static void __attribute__((noreturn)) usage(int status) { extern const char *__progname; - fprintf(stderr, "usage: %s [-h] [-s] [-p path] MODULE\n", __progname); + fprintf(stderr, "usage: %s [-h] [-s] [-p path]* MODULE\n", __progname); exit(status); } @@ -408,7 +409,8 @@ static int generate_nb_nodes(const struct lysc_node *snode, void *arg) int main(int argc, char *argv[]) { - const char *search_path = NULL; + char **search_paths = NULL; + char **iter = NULL; struct yang_module *module; char module_name_underscores[64]; struct stat st; @@ -433,7 +435,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - search_path = optarg; + *darr_append(search_paths) = darr_strdup(optarg); break; case 's': static_cbs = true; @@ -450,8 +452,11 @@ int main(int argc, char *argv[]) yang_init(false, true, false); - if (search_path) - ly_ctx_set_searchdir(ly_native_ctx, search_path); + darr_foreach_p (search_paths, iter) { + ly_ctx_set_searchdir(ly_native_ctx, *iter); + darr_free(*iter); + } + darr_free(search_paths); /* Load all FRR native models to ensure all augmentations are loaded. */ yang_module_load_all(); diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index e61c158ca9..a32fc2bb14 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1056,6 +1056,7 @@ static struct nhg_ctx *nhg_ctx_init(uint32_t id, struct nexthop *nh, struct nh_g static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid) { struct nhg_connected *rb_node_dep; + bool dependent_valid = valid; if (valid) SET_FLAG(nhe->flags, NEXTHOP_GROUP_VALID); @@ -1071,6 +1072,7 @@ 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) { + dependent_valid = valid; if (!valid) { /* * Grab the first nexthop from the depending nexthop group @@ -1080,16 +1082,22 @@ static void zebra_nhg_set_valid(struct nhg_hash_entry *nhe, bool valid) struct nexthop *nexthop = rb_node_dep->nhe->nhg.nexthop; while (nexthop) { - if (nexthop_same(nexthop, nhe->nhg.nexthop)) - break; - + if (nexthop_same(nexthop, nhe->nhg.nexthop)) { + /* Invalid Nexthop */ + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); + } else { + /* + * If other nexthops in the nexthop + * group are valid then we can continue + * to use this nexthop group as valid + */ + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + dependent_valid = true; + } nexthop = nexthop->next; } - - if (nexthop) - UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); } - zebra_nhg_set_valid(rb_node_dep->nhe, valid); + zebra_nhg_set_valid(rb_node_dep->nhe, dependent_valid); } } |
