diff options
46 files changed, 574 insertions, 217 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 24fa2b2a53..c0ad72dc33 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -5866,13 +5866,6 @@ static int parse_rtlist(struct bgp *bgp, struct vty *vty, int argc, * the ecommunity parser. */ if ((argv[i]->arg)[0] == '*') { - if (!is_import) { - vty_out(vty, - "%% Wildcard '*' only applicable for import\n"); - ret = CMD_WARNING; - continue; - } - (argv[i]->arg)[0] = '0'; is_wildcard = true; } @@ -5950,6 +5943,16 @@ DEFUN (bgp_evpn_vrf_rt, return CMD_WARNING_CONFIG_FAILED; } + if (rt_type != RT_TYPE_IMPORT) { + for (int i = 2; i < argc; i++) { + if ((argv[i]->arg)[0] == '*') { + vty_out(vty, + "%% Wildcard '*' only applicable for import\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + } + /* Add/update the import route-target */ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) tmp_ret = parse_rtlist(bgp, vty, argc, argv, 2, true, true); @@ -6056,6 +6059,16 @@ DEFUN (no_bgp_evpn_vrf_rt, } } + if (rt_type != RT_TYPE_IMPORT) { + for (int i = 3; i < argc; i++) { + if ((argv[i]->arg)[0] == '*') { + vty_out(vty, + "%% Wildcard '*' only applicable for import\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + } + if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) tmp_ret = parse_rtlist(bgp, vty, argc, argv, 3, false, true); diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index a85432a33b..40598b7757 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -601,40 +601,40 @@ void bgp_delayopen_timer(struct thread *thread) /* BGP Peer Down Cause */ const char *const peer_down_str[] = {"", - "Router ID changed", - "Remote AS changed", - "Local AS change", - "Cluster ID changed", - "Confederation identifier changed", - "Confederation peer changed", - "RR client config change", - "RS client config change", - "Update source change", - "Address family activated", - "Admin. shutdown", - "User reset", - "BGP Notification received", - "BGP Notification send", - "Peer closed the session", - "Neighbor deleted", - "Peer-group add member", - "Peer-group delete member", - "Capability changed", - "Passive config change", - "Multihop config change", - "NSF peer closed the session", - "Intf peering v6only config change", - "BFD down received", - "Interface down", - "Neighbor address lost", - "Waiting for NHT", - "Waiting for Peer IPv6 LLA", - "Waiting for VRF to be initialized", - "No AFI/SAFI activated for peer", - "AS Set config change", - "Waiting for peer OPEN", - "Reached received prefix count", - "Socket Error"}; + "Router ID changed", + "Remote AS changed", + "Local AS change", + "Cluster ID changed", + "Confederation identifier changed", + "Confederation peer changed", + "RR client config change", + "RS client config change", + "Update source change", + "Address family activated", + "Admin. shutdown", + "User reset", + "BGP Notification received", + "BGP Notification send", + "Peer closed the session", + "Neighbor deleted", + "Peer-group add member", + "Peer-group delete member", + "Capability changed", + "Passive config change", + "Multihop config change", + "NSF peer closed the session", + "Intf peering v6only config change", + "BFD down received", + "Interface down", + "Neighbor address lost", + "No path to specified Neighbor", + "Waiting for Peer IPv6 LLA", + "Waiting for VRF to be initialized", + "No AFI/SAFI activated for peer", + "AS Set config change", + "Waiting for peer OPEN", + "Reached received prefix count", + "Socket Error"}; static void bgp_graceful_restart_timer_off(struct peer *peer) { @@ -1880,8 +1880,9 @@ int bgp_start(struct peer *peer) if (!bgp_peer_reg_with_nht(peer)) { if (bgp_zebra_num_connects()) { if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s [FSM] Waiting for NHT", - peer->host); + zlog_debug( + "%s [FSM] Waiting for NHT, no path to neighbor present", + peer->host); peer->last_reset = PEER_DOWN_WAITING_NHT; BGP_EVENT_ADD(peer, TCP_connection_open_failed); return 0; diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 8ae31bf2e6..769f9613da 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -124,6 +124,7 @@ static void bgp_packet_add(struct peer *peer, struct stream *s) { intmax_t delta; uint32_t holdtime; + intmax_t sendholdtime; frr_with_mutex (&peer->io_mtx) { /* if the queue is empty, reset the "last OK" timestamp to @@ -136,8 +137,14 @@ static void bgp_packet_add(struct peer *peer, struct stream *s) stream_fifo_push(peer->obuf, s); delta = monotime(NULL) - peer->last_sendq_ok; - holdtime = atomic_load_explicit(&peer->holdtime, - memory_order_relaxed); + + if (CHECK_FLAG(peer->flags, PEER_FLAG_TIMER)) + holdtime = atomic_load_explicit(&peer->holdtime, + memory_order_relaxed); + else + holdtime = peer->bgp->default_holdtime; + + sendholdtime = holdtime * 2; /* Note that when we're here, we're adding some packet to the * OutQ. That includes keepalives when there is nothing to @@ -149,18 +156,18 @@ static void bgp_packet_add(struct peer *peer, struct stream *s) */ if (!holdtime) { /* no holdtime, do nothing. */ - } else if (delta > 2 * (intmax_t)holdtime) { + } else if (delta > sendholdtime) { flog_err( EC_BGP_SENDQ_STUCK_PROPER, - "%s has not made any SendQ progress for 2 holdtimes, terminating session", - peer->host); + "%pBP has not made any SendQ progress for 2 holdtimes (%jds), terminating session", + peer, sendholdtime); BGP_EVENT_ADD(peer, TCP_fatal_error); } else if (delta > (intmax_t)holdtime && monotime(NULL) - peer->last_sendq_warn > 5) { flog_warn( EC_BGP_SENDQ_STUCK_WARN, - "%s has not made any SendQ progress for 1 holdtime, peer overloaded?", - peer->host); + "%pBP has not made any SendQ progress for 1 holdtime (%us), peer overloaded?", + peer, holdtime); peer->last_sendq_warn = monotime(NULL); } } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f6b6cb93db..cbb597fdab 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2418,7 +2418,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if (aspath_check_as_sets(attr->aspath)) return false; - /* If neighbor sso is configured, then check if the route has + /* If neighbor soo is configured, then check if the route has * SoO extended community and validate against the configured * one. If they match, do not announce, to prevent routing * loops. @@ -2431,6 +2431,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS, ECOMMUNITY_SITE_ORIGIN) || ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4, + ECOMMUNITY_SITE_ORIGIN) || + ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP, ECOMMUNITY_SITE_ORIGIN)) && ecommunity_include(ecomm, ecomm_soo)) { if (bgp_debug_update(NULL, p, subgrp->update_group, 0)) @@ -4000,6 +4002,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bool force_evpn_import = false; safi_t orig_safi = safi; bool leak_success = true; + int allowas_in = 0; if (frrtrace_enabled(frr_bgp, process_update)) { char pfxprint[PREFIX2STR_BUFFER]; @@ -4045,6 +4048,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, && peer != bgp->peer_self) bgp_adj_in_set(dest, peer, attr, addpath_id); + /* Update permitted loop count */ + if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) + allowas_in = peer->allowas_in[afi][safi]; + /* Check previously received route. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (pi->peer == peer && pi->type == type @@ -4054,8 +4061,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* AS path local-as loop check. */ if (peer->change_local_as) { - if (peer->allowas_in[afi][safi]) - aspath_loop_count = peer->allowas_in[afi][safi]; + if (allowas_in) + aspath_loop_count = allowas_in; else if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) aspath_loop_count = 1; @@ -4078,11 +4085,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* AS path loop check. */ if (do_loop_check) { - if (aspath_loop_check(attr->aspath, bgp->as) - > peer->allowas_in[afi][safi] - || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) - && aspath_loop_check(attr->aspath, bgp->confed_id) - > peer->allowas_in[afi][safi])) { + if (aspath_loop_check(attr->aspath, bgp->as) > allowas_in || + (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && + (aspath_loop_check(attr->aspath, bgp->confed_id) > + allowas_in))) { peer->stat_pfx_aspath_loop++; reason = "as-path contains our own AS;"; goto filtered; @@ -9035,6 +9041,8 @@ static void route_vty_short_status_out(struct vty *vty, vty_out(vty, "I"); else if (rpki_state == RPKI_NOTFOUND) vty_out(vty, "N"); + else + vty_out(vty, " "); /* Route status display. */ if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 7c6e60bd92..dfe741914d 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -80,7 +80,7 @@ enum bgp_show_adj_route_type { #define BGP_SHOW_NCODE_HEADER "Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self\n" #define BGP_SHOW_RPKI_HEADER \ "RPKI validation codes: V valid, I invalid, N Not found\n\n" -#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\n" +#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 diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 88a81f255d..344aea16f5 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -527,7 +527,7 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, && !CHECK_FLAG(vec->flags, BPKT_ATTRVEC_FLAGS_RMAP_NH_UNCHANGED) && !peer_af_flag_check( - peer, nhafi, paf->safi, + peer, paf->afi, paf->safi, PEER_FLAG_NEXTHOP_UNCHANGED)) { /* NOTE: not handling case where NH has new AFI */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index c5ce295c55..e856529fc6 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -12282,6 +12282,16 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, json_addr, "privateAsNumsRemovedInUpdatesToNbr"); + if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) { + if (CHECK_FLAG(p->af_flags[afi][safi], + PEER_FLAG_ALLOWAS_IN_ORIGIN)) + json_object_boolean_true_add(json_addr, + "allowAsInOrigin"); + else + json_object_int_add(json_addr, "allowAsInCount", + p->allowas_in[afi][safi]); + } + if (p->addpath_type[afi][safi] != BGP_ADDPATH_NONE) json_object_boolean_true_add( json_addr, @@ -12598,6 +12608,17 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi, vty_out(vty, " Private AS numbers removed in updates to this neighbor\n"); + if (CHECK_FLAG(p->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN)) { + if (CHECK_FLAG(p->af_flags[afi][safi], + PEER_FLAG_ALLOWAS_IN_ORIGIN)) + vty_out(vty, + " Local AS allowed as path origin\n"); + else + vty_out(vty, + " Local AS allowed in path, %d occurrences\n", + p->allowas_in[afi][safi]); + } + if (p->addpath_type[afi][safi] != BGP_ADDPATH_NONE) vty_out(vty, " %s\n", bgp_addpath_names(p->addpath_type[afi][safi]) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 1583eba50b..512b52836d 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -4272,9 +4272,9 @@ static const struct peer_flag_action peer_flag_action_list[] = { {PEER_FLAG_TIMER_CONNECT, 0, peer_change_none}, {PEER_FLAG_TIMER_DELAYOPEN, 0, peer_change_none}, {PEER_FLAG_PASSWORD, 0, peer_change_none}, - {PEER_FLAG_LOCAL_AS, 0, peer_change_none}, - {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_none}, - {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_none}, + {PEER_FLAG_LOCAL_AS, 0, peer_change_reset}, + {PEER_FLAG_LOCAL_AS_NO_PREPEND, 0, peer_change_reset}, + {PEER_FLAG_LOCAL_AS_REPLACE_AS, 0, peer_change_reset}, {PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none}, {PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none}, {PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset}, @@ -6160,18 +6160,8 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend, (void)peer_sort(peer); /* Check if handling a regular peer. */ - if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) { - /* Send notification or reset peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) { - peer->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; - bgp_notify_send(peer, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else - bgp_session_reset(peer); - - /* Skip peer-group mechanics for regular peers. */ + if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) return 0; - } /* * Set flag and configuration on all peer-group members, unless they are @@ -6200,14 +6190,6 @@ int peer_local_as_set(struct peer *peer, as_t as, bool no_prepend, COND_FLAG(member->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS, replace_as); member->change_local_as = as; - - /* Send notification or stop peer depending on state. */ - if (BGP_IS_VALID_STATE_FOR_NOTIF(member->status)) { - member->last_reset = PEER_DOWN_LOCAL_AS_CHANGE; - bgp_notify_send(member, BGP_NOTIFY_CEASE, - BGP_NOTIFY_CEASE_CONFIG_CHANGE); - } else - BGP_EVENT_ADD(member, BGP_Stop); } return 0; diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 0093279cde..155d1e6fed 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -66,6 +66,8 @@ DEFINE_MTYPE_STATIC(ISISD, ISIS_MPLS_TE, "ISIS MPLS_TE parameters"); +static void isis_mpls_te_circuit_ip_update(struct isis_circuit *circuit); + /*------------------------------------------------------------------------* * Following are control functions for MPLS-TE parameters management. *------------------------------------------------------------------------*/ @@ -111,9 +113,13 @@ void isis_mpls_te_create(struct isis_area *area) if (area->mta->ted) isis_te_init_ted(area); - /* Update Extended TLVs according to Interface link parameters */ - for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) + /* Update Extended TLVs according to Interface link parameters + * and neighbor IP addresses + */ + for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { isis_link_params_update(circuit, circuit->interface); + isis_mpls_te_circuit_ip_update(circuit); + } } /** @@ -132,7 +138,7 @@ void isis_mpls_te_disable(struct isis_area *area) area->mta->status = disable; /* Remove Link State Database */ - ls_ted_del_all(&area->mta->ted); + ls_ted_clean(area->mta->ted); /* Disable Extended SubTLVs on all circuit */ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { @@ -336,16 +342,12 @@ void isis_link_params_update(struct isis_circuit *circuit, return; } -static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family, - bool global) +static int _isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family, + bool global) { struct isis_circuit *circuit; struct isis_ext_subtlvs *ext; - /* Sanity Check */ - if (!adj || !adj->circuit) - return 0; - circuit = adj->circuit; /* Check that MPLS TE is enabled */ @@ -366,6 +368,12 @@ static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family, } break; case AF_INET6: + /* Nothing to do for link-local addresses - ie. not global. + * https://datatracker.ietf.org/doc/html/rfc6119#section-3.1.1 + * Because the IPv6 traffic engineering TLVs present in LSPs are + * propagated across networks, they MUST NOT use link-local + * addresses. + */ if (!global) return 0; @@ -381,22 +389,32 @@ static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family, return 0; } - /* Update LSP */ - lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); - return 0; } -static int isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family, - bool global) +static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family, + bool global) { - struct isis_circuit *circuit; - struct isis_ext_subtlvs *ext; + int ret; /* Sanity Check */ - if (!adj || !adj->circuit || !adj->circuit->ext) + if (!adj || !adj->circuit) return 0; + ret = _isis_mpls_te_adj_ip_enabled(adj, family, global); + + /* Update LSP */ + lsp_regenerate_schedule(adj->circuit->area, adj->circuit->is_type, 0); + + return ret; +} + +static int _isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family, + bool global) +{ + struct isis_circuit *circuit; + struct isis_ext_subtlvs *ext; + circuit = adj->circuit; /* Check that MPLS TE is enabled */ @@ -422,12 +440,59 @@ static int isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family, return 0; } + return 0; +} + +static int isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family, + bool global) +{ + int ret; + + /* Sanity Check */ + if (!adj || !adj->circuit || !adj->circuit->ext) + return 0; + + ret = _isis_mpls_te_adj_ip_disabled(adj, family, global); + /* Update LSP */ - lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); + lsp_regenerate_schedule(adj->circuit->area, adj->circuit->is_type, 0); - return 0; + return ret; } +static void isis_mpls_te_circuit_ip_update(struct isis_circuit *circuit) +{ + struct isis_adjacency *adj; + + /* https://datatracker.ietf.org/doc/html/rfc6119#section-3.2.3 + * This sub-TLV of the Extended IS Reachability TLV is used for point- + * to-point links + */ + if (circuit->circ_type != CIRCUIT_T_P2P) + return; + + adj = circuit->u.p2p.neighbor; + + if (!adj) + return; + + /* Nothing to do for link-local addresses. + * https://datatracker.ietf.org/doc/html/rfc6119#section-3.1.1 + * Because the IPv6 traffic engineering TLVs present in LSPs are + * propagated across networks, they MUST NOT use link-local addresses. + */ + if (adj->ipv4_address_count > 0) + _isis_mpls_te_adj_ip_enabled(adj, AF_INET, false); + else + _isis_mpls_te_adj_ip_disabled(adj, AF_INET, false); + + if (adj->global_ipv6_count > 0) + _isis_mpls_te_adj_ip_enabled(adj, AF_INET6, true); + else + _isis_mpls_te_adj_ip_disabled(adj, AF_INET6, true); +} + + int isis_mpls_te_update(struct interface *ifp) { struct isis_circuit *circuit; diff --git a/isisd/isisd.c b/isisd/isisd.c index efea1e5d5e..17f4b20737 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -723,7 +723,7 @@ void isis_vrf_init(void) vrf_cmd_init(NULL); } -void isis_terminate() +void isis_terminate(void) { struct isis *isis; struct listnode *node, *nnode; @@ -2745,7 +2745,6 @@ static void show_isis_database_json(struct json_object *json, const char *sysid_ struct isis_area *area; int level; struct json_object *tag_area_json,*area_json, *lsp_json, *area_arr_json, *arr_json; - uint8_t area_cnt = 0; if (isis->area_list->count == 0) return; @@ -2770,7 +2769,6 @@ static void show_isis_database_json(struct json_object *json, const char *sysid_ json_object_array_add(arr_json, lsp_json); } json_object_array_add(area_arr_json, area_json); - area_cnt++; } } @@ -3232,7 +3230,7 @@ void isis_area_overload_on_startup_set(struct isis_area *area, * Returns the path of the file (non-volatile memory) that contains restart * information. */ -char *isis_restart_filepath() +char *isis_restart_filepath(void) { static char filepath[MAXPATHLEN]; snprintf(filepath, sizeof(filepath), ISISD_RESTART, ""); diff --git a/ldpd/neighbor.c b/ldpd/neighbor.c index e1db9e8e1e..6d6c7d00cd 100644 --- a/ldpd/neighbor.c +++ b/ldpd/neighbor.c @@ -359,8 +359,7 @@ nbr_find_ldpid(uint32_t lsr_id) return (RB_FIND(nbr_id_head, &nbrs_by_id, &n)); } -struct nbr * -nbr_get_first_ldpid() +struct nbr *nbr_get_first_ldpid(void) { return (RB_MIN(nbr_id_head, &nbrs_by_id)); } @@ -1095,13 +1095,15 @@ const char *if_link_type_str(enum zebra_link_type llt) struct if_link_params *if_link_params_get(struct interface *ifp) { - int i; + return ifp->link_params; +} - if (ifp->link_params != NULL) - return ifp->link_params; +struct if_link_params *if_link_params_enable(struct interface *ifp) +{ + struct if_link_params *iflp; + int i; - struct if_link_params *iflp = - XCALLOC(MTYPE_IF_LINK_PARAMS, sizeof(struct if_link_params)); + iflp = if_link_params_init(ifp); /* Compute default bandwidth based on interface */ iflp->default_bw = @@ -1129,6 +1131,20 @@ struct if_link_params *if_link_params_get(struct interface *ifp) return iflp; } +struct if_link_params *if_link_params_init(struct interface *ifp) +{ + struct if_link_params *iflp = if_link_params_get(ifp); + + if (iflp) + return iflp; + + iflp = XCALLOC(MTYPE_IF_LINK_PARAMS, sizeof(struct if_link_params)); + + ifp->link_params = iflp; + + return iflp; +} + void if_link_params_free(struct interface *ifp) { XFREE(MTYPE_IF_LINK_PARAMS, ifp->link_params); @@ -588,6 +588,8 @@ struct connected *connected_get_linklocal(struct interface *ifp); /* link parameters */ struct if_link_params *if_link_params_get(struct interface *); +struct if_link_params *if_link_params_enable(struct interface *ifp); +struct if_link_params *if_link_params_init(struct interface *ifp); void if_link_params_free(struct interface *); /* Northbound. */ diff --git a/lib/zclient.c b/lib/zclient.c index 8ec82ab7bb..4a553f4718 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -2299,13 +2299,22 @@ static int zclient_handle_error(ZAPI_CALLBACK_ARGS) return 0; } -static int link_params_set_value(struct stream *s, struct if_link_params *iflp) +static int link_params_set_value(struct stream *s, struct interface *ifp) { + uint8_t link_params_enabled; + struct if_link_params *iflp; + uint32_t bwclassnum; + + iflp = if_link_params_get(ifp); if (iflp == NULL) - return -1; + iflp = if_link_params_init(ifp); - uint32_t bwclassnum; + STREAM_GETC(s, link_params_enabled); + if (!link_params_enabled) { + if_link_params_free(ifp); + return 0; + } STREAM_GETL(s, iflp->lp_status); STREAM_GETL(s, iflp->te_metric); @@ -2346,9 +2355,9 @@ struct interface *zebra_interface_link_params_read(struct stream *s, bool *changed) { struct if_link_params *iflp; - struct if_link_params iflp_copy; + struct if_link_params iflp_prev; ifindex_t ifindex; - bool params_changed = false; + bool iflp_prev_set; STREAM_GETL(s, ifindex); @@ -2361,22 +2370,33 @@ struct interface *zebra_interface_link_params_read(struct stream *s, return NULL; } - if (ifp->link_params == NULL) - params_changed = true; - - if ((iflp = if_link_params_get(ifp)) == NULL) - return NULL; - - memcpy(&iflp_copy, iflp, sizeof(iflp_copy)); + if (if_link_params_get(ifp)) { + iflp_prev_set = true; + memcpy(&iflp_prev, ifp->link_params, sizeof(iflp_prev)); + } else + iflp_prev_set = false; - if (link_params_set_value(s, iflp) != 0) + /* read the link_params from stream + * Free ifp->link_params if the stream has no params + * to means that link-params are not enabled on links. + */ + if (link_params_set_value(s, ifp) != 0) goto stream_failure; - if (memcmp(&iflp_copy, iflp, sizeof(iflp_copy))) - params_changed = true; + if (changed == NULL) + return ifp; + + iflp = if_link_params_get(ifp); - if (changed) - *changed = params_changed; + if (iflp_prev_set && iflp) { + if (memcmp(&iflp_prev, iflp, sizeof(iflp_prev))) + *changed = true; + else + *changed = false; + } else if (!iflp_prev_set && !iflp) + *changed = false; + else + *changed = true; return ifp; @@ -2415,10 +2435,8 @@ static void zebra_interface_if_set_value(struct stream *s, /* Read Traffic Engineering status */ link_params_status = stream_getc(s); /* Then, Traffic Engineering parameters if any */ - if (link_params_status) { - struct if_link_params *iflp = if_link_params_get(ifp); - link_params_set_value(s, iflp); - } + if (link_params_status) + link_params_set_value(s, ifp); nexthop_group_interface_state_change(ifp, old_ifindex); @@ -2435,12 +2453,20 @@ size_t zebra_interface_link_params_write(struct stream *s, struct if_link_params *iflp; int i; - if (s == NULL || ifp == NULL || ifp->link_params == NULL) + if (s == NULL || ifp == NULL) return 0; iflp = ifp->link_params; w = 0; + /* encode if link_params is enabled */ + if (iflp) { + w += stream_putc(s, true); + } else { + w += stream_putc(s, false); + return w; + } + w += stream_putl(s, iflp->lp_status); w += stream_putl(s, iflp->te_metric); diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index a0cb455798..78b2ffbcf3 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -39,6 +39,8 @@ #include "ospf6_spf.h" #include "ospf6_top.h" #include "ospf6_area.h" +#include "ospf6_message.h" +#include "ospf6_neighbor.h" #include "ospf6_interface.h" #include "ospf6_intra.h" #include "ospf6_abr.h" @@ -348,9 +350,17 @@ void ospf6_area_delete(struct ospf6_area *oa) * deleting an area. * So just detach the interface from the area and * keep it around. */ - for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi)) + for (ALL_LIST_ELEMENTS_RO(oa->if_list, n, oi)) { oi->area = NULL; + struct listnode *node; + struct listnode *nnode; + struct ospf6_neighbor *on; + + for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) + ospf6_neighbor_delete(on); + } + list_delete(&oa->if_list); ospf6_lsdb_delete(oa->lsdb); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index ae3ce2f0c7..924c2d6c5b 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -3169,6 +3169,14 @@ void ospf6_external_aggregator_free(struct ospf6_external_aggr_rt *aggr) hash_clean(aggr->match_extnl_hash, ospf6_aggr_unlink_external_info); + if (aggr->route) { + if (aggr->route->route_option) + XFREE(MTYPE_OSPF6_EXTERNAL_INFO, + aggr->route->route_option); + + ospf6_route_delete(aggr->route); + } + if (IS_OSPF6_DEBUG_AGGR) zlog_debug("%s: Release the aggregator Address(%pFX)", __func__, diff --git a/ospf6d/ospf6_route.c b/ospf6d/ospf6_route.c index 8e964393f1..fab0479d42 100644 --- a/ospf6d/ospf6_route.c +++ b/ospf6d/ospf6_route.c @@ -1360,7 +1360,7 @@ static void ospf6_route_show_table_summary(struct vty *vty, struct ospf6_route *route, *prev = NULL; int i, pathtype[OSPF6_PATH_TYPE_MAX]; unsigned int number = 0; - int nh_count = 0, nhinval = 0, ecmp = 0; + int nh_count = 0, ecmp = 0; int alternative = 0, destination = 0; char path_str[30]; @@ -1374,9 +1374,7 @@ static void ospf6_route_show_table_summary(struct vty *vty, else alternative++; nh_count = ospf6_num_nexthops(route->nh_list); - if (!nh_count) - nhinval++; - else if (nh_count > 1) + if (nh_count > 1) ecmp++; pathtype[route->path.type]++; number++; diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index e686a93ba9..c2af09a679 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -648,6 +648,13 @@ int ospf_flood_through_interface(struct ospf_interface *oi, OSPF_SEND_PACKET_DIRECT); } } else + /* Optimization: for P2MP interfaces, + don't send back out the incoming interface immediately, + allow time to rx multicast ack to the rx'ed (multicast) + update */ + if (retx_flag != 1 || + oi->type != OSPF_IFTYPE_POINTOMULTIPOINT || inbr == NULL || + oi != inbr->oi) ospf_ls_upd_send_lsa(oi->nbr_self, lsa, OSPF_SEND_PACKET_INDIRECT); diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 57643f637e..466b5fa2a2 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -4220,7 +4220,8 @@ static void ospf_ls_ack_send_list(struct ospf_interface *oi, struct list *ack, op->length = length; /* Decide destination address. */ - if (oi->type == OSPF_IFTYPE_POINTOPOINT) + if (oi->type == OSPF_IFTYPE_POINTOPOINT || + oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) op->dst.s_addr = htonl(OSPF_ALLSPFROUTERS); else op->dst.s_addr = dst.s_addr; diff --git a/pathd/path_ted.c b/pathd/path_ted.c index 316255a97e..bb04d285c9 100644 --- a/pathd/path_ted.c +++ b/pathd/path_ted.c @@ -162,7 +162,7 @@ bool path_ted_is_initialized(void) * * @return Ptr to ted or NULL */ -struct ls_ted *path_ted_create_ted() +struct ls_ted *path_ted_create_ted(void) { struct ls_ted *ted = ls_ted_new(TED_KEY, TED_NAME, TED_ASN); diff --git a/pceplib/pcep_msg_messages.c b/pceplib/pcep_msg_messages.c index 9bbfc5372b..5a244098d4 100644 --- a/pceplib/pcep_msg_messages.c +++ b/pceplib/pcep_msg_messages.c @@ -163,7 +163,7 @@ pcep_msg_create_error_with_objects(uint8_t error_type, uint8_t error_value, return message; } -struct pcep_message *pcep_msg_create_keepalive() +struct pcep_message *pcep_msg_create_keepalive(void) { return (pcep_msg_create_common(PCEP_TYPE_KEEPALIVE)); } diff --git a/pceplib/pcep_msg_messages_encoding.c b/pceplib/pcep_msg_messages_encoding.c index e90ca1cfd8..2d27e40407 100644 --- a/pceplib/pcep_msg_messages_encoding.c +++ b/pceplib/pcep_msg_messages_encoding.c @@ -348,7 +348,7 @@ struct pcep_message *pcep_decode_message(const uint8_t *msg_buf) return msg; } -struct pcep_versioning *create_default_pcep_versioning() +struct pcep_versioning *create_default_pcep_versioning(void) { struct pcep_versioning *versioning = pceplib_malloc(PCEPLIB_INFRA, sizeof(struct pcep_versioning)); diff --git a/pceplib/pcep_pcc.c b/pceplib/pcep_pcc.c index 18ccf250ae..47e357729c 100644 --- a/pceplib/pcep_pcc.c +++ b/pceplib/pcep_pcc.c @@ -74,7 +74,6 @@ static const short DEFAULT_SRC_TCP_PORT = 4999; // Private fn's struct cmd_line_args *get_cmdline_args(int argc, char *argv[]); void handle_signal_action(int sig_number); -int setup_signals(void); void send_pce_path_request_message(pcep_session *session); void send_pce_report_message(pcep_session *session); void print_queue_event(struct pcep_event *event); @@ -211,8 +210,7 @@ void handle_signal_action(int sig_number) } } - -int setup_signals() +static int setup_signals(void) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); diff --git a/pceplib/pcep_pcc_api.c b/pceplib/pcep_pcc_api.c index b7813c5a05..75c2b59b66 100644 --- a/pceplib/pcep_pcc_api.c +++ b/pceplib/pcep_pcc_api.c @@ -55,7 +55,7 @@ const char UNKNOWN_EVENT_STR[] = "UNKNOWN Event Type"; /* Session Logic Handle managed in pcep_session_logic.c */ extern pcep_event_queue *session_logic_event_queue_; -bool initialize_pcc() +bool initialize_pcc(void) { if (!run_session_logic()) { pcep_log(LOG_ERR, "%s: Error initializing PCC session logic.", @@ -85,13 +85,13 @@ bool initialize_pcc_infra(struct pceplib_infra_config *infra_config) /* this function is blocking */ -bool initialize_pcc_wait_for_completion() +bool initialize_pcc_wait_for_completion(void) { return run_session_logic_wait_for_completion(); } -bool destroy_pcc() +bool destroy_pcc(void) { if (!stop_session_logic()) { pcep_log(LOG_WARNING, "%s: Error stopping PCC session logic.", @@ -103,7 +103,7 @@ bool destroy_pcc() } -pcep_configuration *create_default_pcep_configuration() +pcep_configuration *create_default_pcep_configuration(void) { pcep_configuration *config = pceplib_malloc(PCEPLIB_INFRA, sizeof(pcep_configuration)); @@ -226,7 +226,7 @@ void send_message(pcep_session *session, struct pcep_message *msg, } /* Returns true if the queue is empty, false otherwise */ -bool event_queue_is_empty() +bool event_queue_is_empty(void) { if (session_logic_event_queue_ == NULL) { pcep_log( @@ -246,7 +246,7 @@ bool event_queue_is_empty() /* Return the number of events on the queue, 0 if empty */ -uint32_t event_queue_num_events_available() +uint32_t event_queue_num_events_available(void) { if (session_logic_event_queue_ == NULL) { pcep_log( @@ -266,7 +266,7 @@ uint32_t event_queue_num_events_available() /* Return the next event on the queue, NULL if empty */ -struct pcep_event *event_queue_get_event() +struct pcep_event *event_queue_get_event(void) { if (session_logic_event_queue_ == NULL) { pcep_log( diff --git a/pceplib/pcep_session_logic.c b/pceplib/pcep_session_logic.c index 78d1072552..02cf3bffbd 100644 --- a/pceplib/pcep_session_logic.c +++ b/pceplib/pcep_session_logic.c @@ -111,7 +111,7 @@ static bool run_session_logic_common(void) } -bool run_session_logic() +bool run_session_logic(void) { if (!run_session_logic_common()) { return false; @@ -234,7 +234,7 @@ bool run_session_logic_with_infra(pceplib_infra_config *infra_config) return true; } -bool run_session_logic_wait_for_completion() +bool run_session_logic_wait_for_completion(void) { if (!run_session_logic()) { return false; @@ -247,7 +247,7 @@ bool run_session_logic_wait_for_completion() } -bool stop_session_logic() +bool stop_session_logic(void) { if (session_logic_handle_ == NULL) { pcep_log(LOG_WARNING, "%s: Session logic already stopped", diff --git a/pceplib/pcep_socket_comm.c b/pceplib/pcep_socket_comm.c index e22eb6e675..4a97c84891 100644 --- a/pceplib/pcep_socket_comm.c +++ b/pceplib/pcep_socket_comm.c @@ -62,7 +62,7 @@ int socket_fd_node_compare(void *list_entry, void *new_entry) } -bool initialize_socket_comm_pre() +bool initialize_socket_comm_pre(void) { socket_comm_handle_ = pceplib_malloc(PCEPLIB_INFRA, sizeof(pcep_socket_comm_handle)); @@ -129,7 +129,7 @@ bool initialize_socket_comm_external_infra( return true; } -bool initialize_socket_comm_loop() +bool initialize_socket_comm_loop(void) { if (socket_comm_handle_ != NULL) { /* already initialized */ @@ -152,7 +152,7 @@ bool initialize_socket_comm_loop() } -bool destroy_socket_comm_loop() +bool destroy_socket_comm_loop(void) { socket_comm_handle_->active = false; diff --git a/pceplib/pcep_timers.c b/pceplib/pcep_timers.c index b0f3e70b50..61fda16363 100644 --- a/pceplib/pcep_timers.c +++ b/pceplib/pcep_timers.c @@ -197,7 +197,7 @@ void free_all_timers(pcep_timers_context *timers_context) } -bool teardown_timers() +bool teardown_timers(void) { if (timers_context_ == NULL) { pcep_log( @@ -252,7 +252,7 @@ bool teardown_timers() } -int get_next_timer_id() +int get_next_timer_id(void) { if (timer_id_ == INT_MAX) { timer_id_ = 0; diff --git a/pceplib/pcep_utils_double_linked_list.c b/pceplib/pcep_utils_double_linked_list.c index 696e46632a..7f90df40f2 100644 --- a/pceplib/pcep_utils_double_linked_list.c +++ b/pceplib/pcep_utils_double_linked_list.c @@ -31,7 +31,7 @@ #include "pcep_utils_logging.h" #include "pcep_utils_memory.h" -double_linked_list *dll_initialize() +double_linked_list *dll_initialize(void) { double_linked_list *handle = pceplib_malloc(PCEPLIB_INFRA, sizeof(double_linked_list)); diff --git a/pceplib/pcep_utils_logging.c b/pceplib/pcep_utils_logging.c index 0286c23078..c9b2588b4b 100644 --- a/pceplib/pcep_utils_logging.c +++ b/pceplib/pcep_utils_logging.c @@ -45,7 +45,7 @@ void set_logging_level(int level) logging_level_ = level; } -int get_logging_level() +int get_logging_level(void) { return logging_level_; } diff --git a/pceplib/pcep_utils_memory.c b/pceplib/pcep_utils_memory.c index c564705f66..10856cac2a 100644 --- a/pceplib/pcep_utils_memory.c +++ b/pceplib/pcep_utils_memory.c @@ -75,7 +75,7 @@ bool pceplib_memory_initialize(void *pceplib_infra_mt, return true; } -void pceplib_memory_reset() +void pceplib_memory_reset(void) { pceplib_infra_mt.total_bytes_allocated = 0; pceplib_infra_mt.num_allocates = 0; @@ -88,7 +88,7 @@ void pceplib_memory_reset() pceplib_messages_mt.num_frees = 0; } -void pceplib_memory_dump() +void pceplib_memory_dump(void) { if (PCEPLIB_INFRA) { pcep_log( diff --git a/pceplib/pcep_utils_queue.c b/pceplib/pcep_utils_queue.c index 627533d01b..22e417111f 100644 --- a/pceplib/pcep_utils_queue.c +++ b/pceplib/pcep_utils_queue.c @@ -33,7 +33,7 @@ #include "pcep_utils_memory.h" #include "pcep_utils_queue.h" -queue_handle *queue_initialize() +queue_handle *queue_initialize(void) { /* Set the max_entries to 0 to disable it */ return queue_initialize_with_size(0); diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 9feb064e96..f9a9aeb1b0 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -495,12 +495,13 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim, uint32_t hash_val = 0, mod_val = 0; uint8_t nh_iter = 0, found = 0; uint32_t i, num_nbrs = 0; - pim_addr nh_addr = nexthop->mrib_nexthop_addr; - pim_addr grp_addr = pim_addr_from_prefix(grp); if (!pnc || !pnc->nexthop_num || !nexthop) return 0; + pim_addr nh_addr = nexthop->mrib_nexthop_addr; + pim_addr grp_addr = pim_addr_from_prefix(grp); + memset(&nbrs, 0, sizeof(nbrs)); memset(&ifps, 0, sizeof(ifps)); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 1dce6b3562..c3e6a303fc 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -950,10 +950,12 @@ void pim_rp_setup(struct pim_instance *pim) pim_find_or_track_nexthop(pim, nht_p, NULL, rp_info, NULL); if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, - nht_p, &rp_info->group, 1)) + nht_p, &rp_info->group, 1)) { if (PIM_DEBUG_PIM_NHT_RP) zlog_debug( "Unable to lookup nexthop for rp specified"); + pim_rp_nexthop_del(rp_info); + } } } diff --git a/pimd/pim_tib.c b/pimd/pim_tib.c index 8f5de3e938..3455e30064 100644 --- a/pimd/pim_tib.c +++ b/pimd/pim_tib.c @@ -49,7 +49,8 @@ tib_sg_oil_setup(struct pim_instance *pim, pim_sgaddr sg, struct interface *oif) if (up) { memcpy(&nexthop, &up->rpf.source_nexthop, sizeof(struct pim_nexthop)); - pim_ecmp_nexthop_lookup(pim, &nexthop, vif_source, &grp, 0); + (void)pim_ecmp_nexthop_lookup(pim, &nexthop, vif_source, &grp, + 0); if (nexthop.interface) input_iface_vif_index = pim_if_find_vifindex_by_ifindex( pim, nexthop.interface->ifindex); diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index 9021f1e12f..553c1314d2 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -401,7 +401,7 @@ static int gm_config_write(struct vty *vty, int writes, vty_out(vty, " ipv6 mld last-member-query-interval %d\n", pim_ifp->gm_specific_query_max_response_time_dsec); - return 0; + return writes; } #endif diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref index b38701a53d..b2e8de5ce1 100644 --- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref +++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post4.1.ref @@ -5,5 +5,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found - Network Next Hop Metric LocPrf Weight Path -*> 192.168.0.0 0.0.0.0 0 32768 i + Network Next Hop Metric LocPrf Weight Path + *> 192.168.0.0 0.0.0.0 0 32768 i diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref index 82b64c0d98..7bee704182 100644 --- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref +++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post5.0.ref @@ -5,5 +5,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found - Network Next Hop Metric LocPrf Weight Path -*> 192.168.0.0/24 0.0.0.0 0 32768 i + Network Next Hop Metric LocPrf Weight Path + *> 192.168.0.0/24 0.0.0.0 0 32768 i diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref index fd333b3084..31071e760d 100644 --- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref +++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4-post6.1.ref @@ -6,5 +6,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found - Network Next Hop Metric LocPrf Weight Path -*> 192.168.0.0/24 0.0.0.0 0 32768 i + Network Next Hop Metric LocPrf Weight Path + *> 192.168.0.0/24 0.0.0.0 0 32768 i diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref index 3be6cd3d7b..53c4793bf4 100644 --- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref +++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv4.ref @@ -3,5 +3,5 @@ Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, i internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete - Network Next Hop Metric LocPrf Weight Path -*> 192.168.0.0 0.0.0.0 0 32768 i + Network Next Hop Metric LocPrf Weight Path + *> 192.168.0.0 0.0.0.0 0 32768 i diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref index 20034b7408..fe3f0720d8 100644 --- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref +++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6-post4.1.ref @@ -5,5 +5,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found - Network Next Hop Metric LocPrf Weight Path -*> fc00::/64 :: 0 32768 i + Network Next Hop Metric LocPrf Weight Path + *> fc00::/64 :: 0 32768 i diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref index fffee63c6b..363b4f5349 100644 --- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref +++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6.ref @@ -3,5 +3,5 @@ Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, i internal, r RIB-failure, S Stale, R Removed Origin codes: i - IGP, e - EGP, ? - incomplete - Network Next Hop Metric LocPrf Weight Path -*> fc00::/64 :: 0 32768 i + Network Next Hop Metric LocPrf Weight Path + *> fc00::/64 :: 0 32768 i diff --git a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref index 5b5f8596cf..8c3229b45d 100644 --- a/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref +++ b/tests/topotests/all_protocol_startup/r1/show_bgp_ipv6_post6.1.ref @@ -6,5 +6,5 @@ Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found - Network Next Hop Metric LocPrf Weight Path -*> fc00::/64 :: 0 32768 i + Network Next Hop Metric LocPrf Weight Path + *> fc00::/64 :: 0 32768 i diff --git a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py index 3b84a99cdf..e131fba0c3 100644 --- a/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py +++ b/tests/topotests/ospf_basic_functionality/test_ospf_p2mp.py @@ -47,10 +47,12 @@ from lib.common_config import ( step, create_interfaces_cfg, topo_daemons, + retry, + run_frr_cmd, ) from lib.topolog import logger from lib.topojson import build_config_from_json -from lib.topotest import frr_unicode +from lib.topotest import frr_unicode, json_cmp from lib.ospf import ( verify_ospf_interface, @@ -378,6 +380,158 @@ def test_ospf_p2mp_tc1_p0(request): write_test_footer(tc_name) +@retry(retry_timeout=30) +def verify_ospf_json(tgen, dut, input_dict, cmd="show ip ospf database json"): + del tgen + show_ospf_json = run_frr_cmd(dut, cmd, isjson=True) + if not bool(show_ospf_json): + return "ospf is not running" + result = json_cmp(show_ospf_json, input_dict) + return str(result) if result else None + + +@pytest.mark.parametrize("tgen", [2], indirect=True) +def test_ospf_nbrs(tgen): + db_full = { + "areas": { + "0.0.0.0": { + "routerLinkStates": [ + { + "lsId": "100.1.1.0", + "advertisedRouter": "100.1.1.0", + "numOfRouterLinks": 6, + }, + { + "lsId": "100.1.1.1", + "advertisedRouter": "100.1.1.1", + "numOfRouterLinks": 6, + }, + { + "lsId": "100.1.1.2", + "advertisedRouter": "100.1.1.2", + "numOfRouterLinks": 6, + }, + { + "lsId": "100.1.1.3", + "advertisedRouter": "100.1.1.3", + "numOfRouterLinks": 7, + }, + ] + } + } + } + input = [ + [ + "r0", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.1": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.2": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.3": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + [ + "r1", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.0": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.2": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.3": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + [ + "r2", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.0": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.1": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.3": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + [ + "r3", + "show ip ospf n json", + { + "neighbors": { + "100.1.1.0": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.1": [ + { + "state": "Full/DROther", + } + ], + "100.1.1.2": [ + { + "state": "Full/DROther", + } + ], + } + }, + ], + ["r0", "show ip ospf database json", db_full], + ["r1", "show ip ospf database json", db_full], + ["r2", "show ip ospf database json", db_full], + ["r3", "show ip ospf database json", db_full], + ["r0", "show ip ospf database json", db_full], + ["r0", "show ip ospf database router json", {}], + ["r0", "show ip ospf interface traffic json", {}], + ["r1", "show ip ospf interface traffic json", {}], + ["r2", "show ip ospf interface traffic json", {}], + ["r3", "show ip ospf interface traffic json", {}], + ] + for cmd_set in input: + step("test_ospf: %s - %s" % (cmd_set[0], cmd_set[1])) + assert ( + verify_ospf_json(tgen, tgen.gears[cmd_set[0]], cmd_set[2], cmd_set[1]) + is None + ) + + if __name__ == "__main__": args = ["-s"] + sys.argv[1:] sys.exit(pytest.main(args)) diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index d98f83dbf6..0f28b49f72 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -652,18 +652,21 @@ int vtysh_read_config(const char *config_default_dir, bool dry_run) */ void vtysh_config_write(void) { + const char *name; char line[512]; - if (cmd_hostname_get()) { - snprintf(line, sizeof(line), "hostname %s", cmd_hostname_get()); + name = cmd_hostname_get(); + if (name && name[0] != '\0') { + snprintf(line, sizeof(line), "hostname %s", name); vtysh_config_parse_line(NULL, line); } - if (cmd_domainname_get()) { - snprintf(line, sizeof(line), "domainname %s", - cmd_domainname_get()); + name = cmd_domainname_get(); + if (name && name[0] != '\0') { + snprintf(line, sizeof(line), "domainname %s", name); vtysh_config_parse_line(NULL, line); } + if (vtysh_write_integrated == WRITE_INTEGRATED_NO) vtysh_config_parse_line(NULL, "no service integrated-vtysh-config"); diff --git a/zebra/interface.c b/zebra/interface.c index c674b499ac..5d62ec071f 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -3279,14 +3279,8 @@ DEFUN (link_params_enable, "Link-params: enable TE link parameters on interface %s", ifp->name); - if (!if_link_params_get(ifp)) { - if (IS_ZEBRA_DEBUG_EVENT || IS_ZEBRA_DEBUG_MPLS) - zlog_debug( - "Link-params: failed to init TE link parameters %s", - ifp->name); - - return CMD_WARNING_CONFIG_FAILED; - } + if (!if_link_params_get(ifp)) + if_link_params_enable(ifp); /* force protocols to update LINK STATE due to parameters change */ if (if_is_operative(ifp)) @@ -3330,6 +3324,9 @@ DEFUN (link_params_metric, metric = strtoul(argv[idx_number]->arg, NULL, 10); + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update TE metric if needed */ link_param_cmd_set_uint32(ifp, &iflp->te_metric, LP_TE_METRIC, metric); @@ -3370,17 +3367,20 @@ DEFUN (link_params_maxbw, /* Check that Maximum bandwidth is not lower than other bandwidth * parameters */ - if ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0]) - || (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2]) - || (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4]) - || (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6]) - || (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw) - || (bw <= iflp->res_bw) || (bw <= iflp->use_bw)) { + if (iflp && ((bw <= iflp->max_rsv_bw) || (bw <= iflp->unrsv_bw[0]) || + (bw <= iflp->unrsv_bw[1]) || (bw <= iflp->unrsv_bw[2]) || + (bw <= iflp->unrsv_bw[3]) || (bw <= iflp->unrsv_bw[4]) || + (bw <= iflp->unrsv_bw[5]) || (bw <= iflp->unrsv_bw[6]) || + (bw <= iflp->unrsv_bw[7]) || (bw <= iflp->ava_bw) || + (bw <= iflp->res_bw) || (bw <= iflp->use_bw))) { vty_out(vty, "Maximum Bandwidth could not be lower than others bandwidth\n"); return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Maximum Bandwidth if needed */ link_param_cmd_set_float(ifp, &iflp->max_bw, LP_MAX_BW, bw); @@ -3406,13 +3406,16 @@ DEFUN (link_params_max_rsv_bw, /* Check that bandwidth is not greater than maximum bandwidth parameter */ - if (bw > iflp->max_bw) { + if (iflp && bw > iflp->max_bw) { vty_out(vty, "Maximum Reservable Bandwidth could not be greater than Maximum Bandwidth (%g)\n", iflp->max_bw); return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Maximum Reservable Bandwidth if needed */ link_param_cmd_set_float(ifp, &iflp->max_rsv_bw, LP_MAX_RSV_BW, bw); @@ -3448,13 +3451,16 @@ DEFUN (link_params_unrsv_bw, /* Check that bandwidth is not greater than maximum bandwidth parameter */ - if (bw > iflp->max_bw) { + if (iflp && bw > iflp->max_bw) { vty_out(vty, "UnReserved Bandwidth could not be greater than Maximum Bandwidth (%g)\n", iflp->max_bw); return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Unreserved Bandwidth if needed */ link_param_cmd_set_float(ifp, &iflp->unrsv_bw[priority], LP_UNRSV_BW, bw); @@ -3479,6 +3485,9 @@ DEFUN (link_params_admin_grp, return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Administrative Group if needed */ link_param_cmd_set_uint32(ifp, &iflp->admin_grp, LP_ADM_GRP, value); @@ -3521,6 +3530,9 @@ DEFUN (link_params_inter_as, return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + as = strtoul(argv[idx_number]->arg, NULL, 10); /* Update Remote IP and Remote AS fields if needed */ @@ -3548,6 +3560,9 @@ DEFUN (no_link_params_inter_as, VTY_DECLVAR_CONTEXT(interface, ifp); struct if_link_params *iflp = if_link_params_get(ifp); + if (!iflp) + return CMD_SUCCESS; + /* Reset Remote IP and AS neighbor */ iflp->rmt_as = 0; iflp->rmt_ip.s_addr = 0; @@ -3595,13 +3610,17 @@ DEFUN (link_params_delay, * Therefore, it is also allowed that the average * delay be equal to the min delay or max delay. */ - if (IS_PARAM_SET(iflp, LP_MM_DELAY) - && (delay < iflp->min_delay || delay > iflp->max_delay)) { + if (iflp && IS_PARAM_SET(iflp, LP_MM_DELAY) && + (delay < iflp->min_delay || delay > iflp->max_delay)) { vty_out(vty, "Average delay should be in range Min (%d) - Max (%d) delay\n", iflp->min_delay, iflp->max_delay); return CMD_WARNING_CONFIG_FAILED; } + + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update delay if value is not set or change */ if (IS_PARAM_UNSET(iflp, LP_DELAY) || iflp->av_delay != delay) { iflp->av_delay = delay; @@ -3626,6 +3645,10 @@ DEFUN (link_params_delay, low, high); return CMD_WARNING_CONFIG_FAILED; } + + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Delays if needed */ if (IS_PARAM_UNSET(iflp, LP_DELAY) || IS_PARAM_UNSET(iflp, LP_MM_DELAY) @@ -3656,6 +3679,9 @@ DEFUN (no_link_params_delay, VTY_DECLVAR_CONTEXT(interface, ifp); struct if_link_params *iflp = if_link_params_get(ifp); + if (!iflp) + return CMD_SUCCESS; + /* Unset Delays */ iflp->av_delay = 0; UNSET_PARAM(iflp, LP_DELAY); @@ -3683,6 +3709,9 @@ DEFUN (link_params_delay_var, value = strtoul(argv[idx_number]->arg, NULL, 10); + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Delay Variation if needed */ link_param_cmd_set_uint32(ifp, &iflp->delay_var, LP_DELAY_VAR, value); @@ -3723,6 +3752,9 @@ DEFUN (link_params_pkt_loss, if (fval > MAX_PKT_LOSS) fval = MAX_PKT_LOSS; + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Packet Loss if needed */ link_param_cmd_set_float(ifp, &iflp->pkt_loss, LP_PKT_LOSS, fval); @@ -3762,13 +3794,16 @@ DEFUN (link_params_res_bw, /* Check that bandwidth is not greater than maximum bandwidth parameter */ - if (bw > iflp->max_bw) { + if (iflp && bw > iflp->max_bw) { vty_out(vty, "Residual Bandwidth could not be greater than Maximum Bandwidth (%g)\n", iflp->max_bw); return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Residual Bandwidth if needed */ link_param_cmd_set_float(ifp, &iflp->res_bw, LP_RES_BW, bw); @@ -3808,13 +3843,16 @@ DEFUN (link_params_ava_bw, /* Check that bandwidth is not greater than maximum bandwidth parameter */ - if (bw > iflp->max_bw) { + if (iflp && bw > iflp->max_bw) { vty_out(vty, "Available Bandwidth could not be greater than Maximum Bandwidth (%g)\n", iflp->max_bw); return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Residual Bandwidth if needed */ link_param_cmd_set_float(ifp, &iflp->ava_bw, LP_AVA_BW, bw); @@ -3854,13 +3892,16 @@ DEFUN (link_params_use_bw, /* Check that bandwidth is not greater than maximum bandwidth parameter */ - if (bw > iflp->max_bw) { + if (iflp && bw > iflp->max_bw) { vty_out(vty, "Utilised Bandwidth could not be greater than Maximum Bandwidth (%g)\n", iflp->max_bw); return CMD_WARNING_CONFIG_FAILED; } + if (!iflp) + iflp = if_link_params_enable(ifp); + /* Update Utilized Bandwidth if needed */ link_param_cmd_set_float(ifp, &iflp->use_bw, LP_USE_BW, bw); diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 761ba789b8..4d7ad21bf3 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -232,11 +232,6 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp) { struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); - if (!ifp->link_params) { - stream_free(s); - return 0; - } - zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf->vrf_id); /* Add Interface Index */ |
