diff options
| -rw-r--r-- | bgpd/bgp_ecommunity.c | 2 | ||||
| -rw-r--r-- | bgpd/bgp_evpn_vty.c | 46 | ||||
| -rw-r--r-- | bgpd/bgp_fsm.c | 87 | ||||
| -rw-r--r-- | bgpd/bgp_packet.c | 92 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_script.c | 9 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 56 | ||||
| -rw-r--r-- | bgpd/bgp_vty.h | 1 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 45 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 15 | ||||
| -rw-r--r-- | doc/user/basic.rst | 14 | ||||
| -rw-r--r-- | doc/user/zebra.rst | 4 | ||||
| -rw-r--r-- | isisd/isis_spf.c | 28 | ||||
| -rw-r--r-- | lib/frrscript.c | 6 | ||||
| -rw-r--r-- | lib/northbound.c | 21 | ||||
| -rw-r--r-- | lib/northbound_cli.c | 21 | ||||
| -rw-r--r-- | m4/.gitignore | 1 | ||||
| -rw-r--r-- | ospfd/ospf_lsa.c | 6 | ||||
| -rw-r--r-- | ospfd/ospf_sr.c | 21 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 32 | ||||
| -rw-r--r-- | ospfd/ospf_zebra.c | 7 | ||||
| -rw-r--r-- | vtysh/vtysh.c | 2 | ||||
| -rw-r--r-- | zebra/zebra_srv6_vty.c | 6 |
23 files changed, 372 insertions, 161 deletions
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c index 5a053a7f34..08caa24a1b 100644 --- a/bgpd/bgp_ecommunity.c +++ b/bgpd/bgp_ecommunity.c @@ -63,7 +63,7 @@ void ecommunity_strfree(char **s) XFREE(MTYPE_ECOMMUNITY_STR, *s); } -/* Allocate ecommunities. */ +/* Free ecommunities. */ void ecommunity_free(struct ecommunity **ecom) { if (!(*ecom)) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 4da3fa8f3b..5f519e84ed 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -5858,16 +5858,15 @@ DEFUN (bgp_evpn_vrf_rt, return CMD_WARNING; } + ecomadd = ecommunity_str2com(argv[2]->arg, ECOMMUNITY_ROUTE_TARGET, 0); + if (!ecomadd) { + vty_out(vty, "%% Malformed Route Target list\n"); + return CMD_WARNING; + } + ecommunity_str(ecomadd); + /* Add/update the import route-target */ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) { - ecomadd = ecommunity_str2com(argv[2]->arg, - ECOMMUNITY_ROUTE_TARGET, 0); - if (!ecomadd) { - vty_out(vty, "%% Malformed Route Target list\n"); - return CMD_WARNING; - } - ecommunity_str(ecomadd); - /* Do nothing if we already have this import route-target */ if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl, ecomadd)) bgp_evpn_configure_import_rt_for_vrf(bgp, ecomadd); @@ -5875,14 +5874,6 @@ DEFUN (bgp_evpn_vrf_rt, /* Add/update the export route-target */ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT) { - ecomadd = ecommunity_str2com(argv[2]->arg, - ECOMMUNITY_ROUTE_TARGET, 0); - if (!ecomadd) { - vty_out(vty, "%% Malformed Route Target list\n"); - return CMD_WARNING; - } - ecommunity_str(ecomadd); - /* Do nothing if we already have this export route-target */ if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl, ecomadd)) bgp_evpn_configure_export_rt_for_vrf(bgp, ecomadd); @@ -6107,16 +6098,15 @@ DEFUN (bgp_evpn_vni_rt, return CMD_WARNING; } + ecomadd = ecommunity_str2com(argv[2]->arg, ECOMMUNITY_ROUTE_TARGET, 0); + if (!ecomadd) { + vty_out(vty, "%% Malformed Route Target list\n"); + return CMD_WARNING; + } + ecommunity_str(ecomadd); + /* Add/update the import route-target */ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) { - ecomadd = ecommunity_str2com(argv[2]->arg, - ECOMMUNITY_ROUTE_TARGET, 0); - if (!ecomadd) { - vty_out(vty, "%% Malformed Route Target list\n"); - return CMD_WARNING; - } - ecommunity_str(ecomadd); - /* Do nothing if we already have this import route-target */ if (!bgp_evpn_rt_matches_existing(vpn->import_rtl, ecomadd)) evpn_configure_import_rt(bgp, vpn, ecomadd); @@ -6124,14 +6114,6 @@ DEFUN (bgp_evpn_vni_rt, /* Add/update the export route-target */ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT) { - ecomadd = ecommunity_str2com(argv[2]->arg, - ECOMMUNITY_ROUTE_TARGET, 0); - if (!ecomadd) { - vty_out(vty, "%% Malformed Route Target list\n"); - return CMD_WARNING; - } - ecommunity_str(ecomadd); - /* Do nothing if we already have this export route-target */ if (!bgp_evpn_rt_matches_existing(vpn->export_rtl, ecomadd)) evpn_configure_export_rt(bgp, vpn, ecomadd); diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index f8de3b8dc4..43908fcb78 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -677,7 +677,8 @@ static void bgp_llgr_stale_timer_expire(struct thread *thread) * stale routes from the neighbor that it is retaining. */ if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s Long-lived stale timer (%s) expired", peer->host, + zlog_debug("%s(%s) Long-lived stale timer (%s) expired", + peer->host, bgp_peer_hostname(peer), get_afi_safi_str(afi, safi, false)); UNSET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_LLGR_WAIT); @@ -719,8 +720,10 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Long-lived set stale community (LLGR_STALE) for: %pFX", - peer->host, &dest->p); + "%s(%s) Long-lived set stale community (LLGR_STALE) for: %pFX", + peer->host, + bgp_peer_hostname(peer), + &dest->p); attr = *pi->attr; bgp_attr_add_llgr_community(&attr); @@ -747,8 +750,10 @@ static void bgp_set_llgr_stale(struct peer *peer, afi_t afi, safi_t safi) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Long-lived set stale community (LLGR_STALE) for: %pFX", - peer->host, &dest->p); + "%s(%s) Long-lived set stale community (LLGR_STALE) for: %pFX", + peer->host, + bgp_peer_hostname(peer), + &dest->p); attr = *pi->attr; bgp_attr_add_llgr_community(&attr); @@ -772,9 +777,10 @@ static void bgp_graceful_restart_timer_expire(struct thread *thread) peer = THREAD_ARG(thread); if (bgp_debug_neighbor_events(peer)) { - zlog_debug("%s graceful restart timer expired", peer->host); - zlog_debug("%s graceful restart stalepath timer stopped", - peer->host); + zlog_debug("%s(%s) graceful restart timer expired", peer->host, + bgp_peer_hostname(peer)); + zlog_debug("%s(%s) graceful restart stalepath timer stopped", + peer->host, bgp_peer_hostname(peer)); } FOREACH_AFI_SAFI (afi, safi) { @@ -800,8 +806,8 @@ static void bgp_graceful_restart_timer_expire(struct thread *thread) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Long-lived stale timer (%s) started for %d sec", - peer->host, + "%s(%s) Long-lived stale timer (%s) started for %d sec", + peer->host, bgp_peer_hostname(peer), get_afi_safi_str(afi, safi, false), peer->llgr[afi][safi].stale_time); @@ -836,8 +842,8 @@ static void bgp_graceful_stale_timer_expire(struct thread *thread) peer = THREAD_ARG(thread); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s graceful restart stalepath timer expired", - peer->host); + zlog_debug("%s(%s) graceful restart stalepath timer expired", + peer->host, bgp_peer_hostname(peer)); /* NSF delete stale route */ FOREACH_AFI_SAFI_NSF (afi, safi) @@ -1390,11 +1396,10 @@ int bgp_stop(struct peer *peer) zlog_info( "%%ADJCHANGE: neighbor %s(%s) in vrf %s Down %s", - peer->host, - (peer->hostname) ? peer->hostname : "Unknown", + peer->host, bgp_peer_hostname(peer), vrf ? ((vrf->vrf_id != VRF_DEFAULT) - ? vrf->name - : VRF_DEFAULT_NAME) + ? vrf->name + : VRF_DEFAULT_NAME) : "", peer_down_str[(int)peer->last_reset]); } @@ -1404,17 +1409,19 @@ int bgp_stop(struct peer *peer) BGP_TIMER_OFF(peer->t_gr_stale); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s graceful restart stalepath timer stopped", - peer->host); + "%s(%s) graceful restart stalepath timer stopped", + peer->host, bgp_peer_hostname(peer)); } if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) { if (bgp_debug_neighbor_events(peer)) { zlog_debug( - "%s graceful restart timer started for %d sec", - peer->host, peer->v_gr_restart); + "%s(%s) graceful restart timer started for %d sec", + peer->host, bgp_peer_hostname(peer), + peer->v_gr_restart); zlog_debug( - "%s graceful restart stalepath timer started for %d sec", - peer->host, peer->bgp->stalepath_time); + "%s(%s) graceful restart stalepath timer started for %d sec", + peer->host, bgp_peer_hostname(peer), + peer->bgp->stalepath_time); } BGP_TIMER_ON(peer->t_gr_restart, bgp_graceful_restart_timer_expire, @@ -1435,8 +1442,8 @@ int bgp_stop(struct peer *peer) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s: route-refresh restart stalepath timer stopped", - peer->host); + "%s(%s) route-refresh restart stalepath timer stopped", + peer->host, bgp_peer_hostname(peer)); } /* If peer reset before receiving EOR, decrement EOR count and @@ -2092,12 +2099,12 @@ static int bgp_establish(struct peer *peer) /* bgp log-neighbor-changes of neighbor Up */ if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) { struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id); - zlog_info( - "%%ADJCHANGE: neighbor %s(%s) in vrf %s Up", peer->host, - (peer->hostname) ? peer->hostname : "Unknown", - vrf ? ((vrf->vrf_id != VRF_DEFAULT) ? vrf->name - : VRF_DEFAULT_NAME) - : ""); + zlog_info("%%ADJCHANGE: neighbor %s(%s) in vrf %s Up", + peer->host, bgp_peer_hostname(peer), + vrf ? ((vrf->vrf_id != VRF_DEFAULT) + ? vrf->name + : VRF_DEFAULT_NAME) + : ""); } /* assign update-group/subgroup */ update_group_adjust_peer_afs(peer); @@ -2182,16 +2189,16 @@ static int bgp_establish(struct peer *peer) BGP_TIMER_OFF(peer->t_gr_stale); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s graceful restart stalepath timer stopped", - peer->host); + "%s(%s) graceful restart stalepath timer stopped", + peer->host, bgp_peer_hostname(peer)); } } if (peer->t_gr_restart) { BGP_TIMER_OFF(peer->t_gr_restart); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s graceful restart timer stopped", - peer->host); + zlog_debug("%s(%s) graceful restart timer stopped", + peer->host, bgp_peer_hostname(peer)); } /* Reset uptime, turn on keepalives, send current table. */ @@ -2200,8 +2207,18 @@ static int bgp_establish(struct peer *peer) peer->uptime = bgp_clock(); - /* Send route-refresh when ORF is enabled */ + /* Send route-refresh when ORF is enabled. + * Stop Long-lived Graceful Restart timers. + */ FOREACH_AFI_SAFI (afi, safi) { + if (peer->t_llgr_stale[afi][safi]) { + BGP_TIMER_OFF(peer->t_llgr_stale[afi][safi]); + if (bgp_debug_neighbor_events(peer)) + zlog_debug( + "%s Long-lived stale timer stopped for afi/safi: %d/%d", + peer->host, afi, safi); + } + if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV)) { if (CHECK_FLAG(peer->af_cap[afi][safi], diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 09db041780..424659136e 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -483,8 +483,10 @@ void bgp_generate_updgrp_packets(struct thread *thread) if (bgp_debug_neighbor_events( peer)) zlog_debug( - "%s sending route-refresh (EoRR) for %s/%s", + "%s(%s) sending route-refresh (EoRR) for %s/%s", peer->host, + bgp_peer_hostname( + peer), afi2str(afi), safi2str(safi)); } @@ -913,9 +915,12 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, stream_putc(s, ORF_COMMON_PART_REMOVE_ALL); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s", - peer->host, orf_type, - (when_to_refresh == REFRESH_DEFER + "%s(%s) sending REFRESH_REQ to remove ORF(%d) (%s) for afi/safi: %s/%s", + peer->host, + bgp_peer_hostname(peer), + orf_type, + (when_to_refresh == + REFRESH_DEFER ? "defer" : "immediate"), iana_afi2str(pkt_afi), @@ -930,9 +935,12 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, ORF_COMMON_PART_DENY); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s", - peer->host, orf_type, - (when_to_refresh == REFRESH_DEFER + "%s(%s) sending REFRESH_REQ with pfxlist ORF(%d) (%s) for afi/safi: %s/%s", + peer->host, + bgp_peer_hostname(peer), + orf_type, + (when_to_refresh == + REFRESH_DEFER ? "defer" : "immediate"), iana_afi2str(pkt_afi), @@ -949,9 +957,10 @@ void bgp_route_refresh_send(struct peer *peer, afi_t afi, safi_t safi, if (bgp_debug_neighbor_events(peer)) { if (!orf_refresh) - zlog_debug("%s sending REFRESH_REQ for afi/safi: %s/%s", - peer->host, iana_afi2str(pkt_afi), - iana_safi2str(pkt_safi)); + zlog_debug( + "%s(%s) sending REFRESH_REQ for afi/safi: %s/%s", + peer->host, bgp_peer_hostname(peer), + iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); } /* Add packet to the peer. */ @@ -995,8 +1004,8 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi, if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s", - peer->host, + "%s(%s) sending CAPABILITY has %s MP_EXT CAP for afi/safi: %s/%s", + peer->host, bgp_peer_hostname(peer), action == CAPABILITY_ACTION_SET ? "Advertising" : "Removing", iana_afi2str(pkt_afi), iana_safi2str(pkt_safi)); @@ -1551,8 +1560,9 @@ static void bgp_refresh_stalepath_timer_expire(struct thread *thread) bgp_clear_stale_route(peer, afi, safi); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s: route-refresh (BoRR) timer for %s/%s expired", - peer->host, afi2str(afi), safi2str(safi)); + zlog_debug( + "%s(%s) route-refresh (BoRR) timer expired for afi/safi: %d/%d", + peer->host, bgp_peer_hostname(peer), afi, safi); bgp_timer_set(peer); } @@ -1708,7 +1718,8 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) peer->host); if (ret && bgp_debug_update(peer, NULL, NULL, 1)) { - zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host, + zlog_debug("%s(%s) rcvd UPDATE w/ attr: %s", peer->host, + bgp_peer_hostname(peer), peer->rcvd_attr_str); peer->rcvd_attr_printed = 1; } @@ -1738,8 +1749,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) } if (BGP_DEBUG(update, UPDATE_IN)) - zlog_debug("%s rcvd UPDATE wlen %d attrlen %d alen %d", - peer->host, withdraw_len, attribute_len, update_len); + zlog_debug("%s(%s) rcvd UPDATE wlen %d attrlen %d alen %d", + peer->host, bgp_peer_hostname(peer), withdraw_len, + attribute_len, update_len); /* Parse any given NLRIs */ for (int i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++) { @@ -2273,18 +2285,18 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) PEER_STATUS_EOR_RECEIVED)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s rcvd route-refresh (BoRR) for %s/%s before EoR", - peer->host, afi2str(afi), - safi2str(safi)); + "%s(%s) rcvd route-refresh (BoRR) for %s/%s before EoR", + peer->host, bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi)); return BGP_PACKET_NOOP; } if (peer->t_refresh_stalepath) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received", - peer->host, afi2str(afi), - safi2str(safi)); + "%s(%s) rcvd route-refresh (BoRR) for %s/%s, whereas BoRR already received", + peer->host, bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi)); return BGP_PACKET_NOOP; } @@ -2312,14 +2324,16 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds", - peer->host, afi2str(afi), safi2str(safi), + "%s(%s) rcvd route-refresh (BoRR) for %s/%s, triggering timer for %u seconds", + peer->host, bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi), peer->bgp->stalepath_time); } else if (subtype == BGP_ROUTE_REFRESH_EORR) { if (!peer->t_refresh_stalepath) { zlog_err( - "%s rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received", - peer->host, afi2str(afi), safi2str(safi)); + "%s(%s) rcvd route-refresh (EoRR) for %s/%s, whereas no BoRR received", + peer->host, bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi)); return BGP_PACKET_NOOP; } @@ -2331,15 +2345,18 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer", - peer->host, afi2str(afi), safi2str(safi)); + "%s(%s) rcvd route-refresh (EoRR) for %s/%s, stopping BoRR timer", + peer->host, bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi)); if (peer->nsf[afi][safi]) bgp_clear_stale_route(peer, afi, safi); } else { if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s rcvd route-refresh (REQUEST) for %s/%s", - peer->host, afi2str(afi), safi2str(safi)); + zlog_debug( + "%s(%s) rcvd route-refresh (REQUEST) for %s/%s", + peer->host, bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi)); /* In response to a "normal route refresh request" from the * peer, the speaker MUST send a BoRR message. @@ -2354,9 +2371,10 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) PEER_STATUS_EOR_SEND)) { if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s rcvd route-refresh (REQUEST) for %s/%s before EoR", - peer->host, afi2str(afi), - safi2str(safi)); + "%s(%s) rcvd route-refresh (REQUEST) for %s/%s before EoR", + peer->host, + bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi)); return BGP_PACKET_NOOP; } @@ -2365,9 +2383,9 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s sending route-refresh (BoRR) for %s/%s", - peer->host, afi2str(afi), - safi2str(safi)); + "%s(%s) sending route-refresh (BoRR) for %s/%s", + peer->host, bgp_peer_hostname(peer), + afi2str(afi), safi2str(safi)); /* Set flag Ready-To-Send to know when we can send EoRR * message. diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5255eb5800..01120ef44a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3433,9 +3433,9 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi, return false; zlog_info( - "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u", - get_afi_safi_str(afi, safi, false), peer->host, pcount, - peer->pmax[afi][safi]); + "%%MAXPFXEXCEED: No. of %s prefix received from %s(%s) %u exceed, limit %u", + get_afi_safi_str(afi, safi, false), peer->host, + bgp_peer_hostname(peer), pcount, peer->pmax[afi][safi]); SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT); if (CHECK_FLAG(peer->af_flags[afi][safi], @@ -3473,8 +3473,9 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi, if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Maximum-prefix restart timer started for %d secs", - peer->host, peer->v_pmax_restart); + "%s(%s) Maximum-prefix restart timer started for %d secs", + peer->host, bgp_peer_hostname(peer), + peer->v_pmax_restart); BGP_TIMER_ON(peer->t_pmax_restart, bgp_maximum_prefix_restart_timer, diff --git a/bgpd/bgp_script.c b/bgpd/bgp_script.c index 9446a25a05..bf3e612bfd 100644 --- a/bgpd/bgp_script.c +++ b/bgpd/bgp_script.c @@ -156,18 +156,19 @@ void lua_pushattr(lua_State *L, const struct attr *attr) void lua_decode_attr(lua_State *L, int idx, struct attr *attr) { - lua_getfield(L, -1, "metric"); + lua_getfield(L, idx, "metric"); attr->med = lua_tointeger(L, -1); lua_pop(L, 1); - lua_getfield(L, -1, "ifindex"); + lua_getfield(L, idx, "ifindex"); attr->nh_ifindex = lua_tointeger(L, -1); lua_pop(L, 1); - lua_getfield(L, -1, "aspath"); + lua_getfield(L, idx, "aspath"); attr->aspath = aspath_str2aspath(lua_tostring(L, -1)); lua_pop(L, 1); - lua_getfield(L, -1, "localpref"); + lua_getfield(L, idx, "localpref"); attr->local_pref = lua_tointeger(L, -1); lua_pop(L, 1); + lua_pop(L, 1); } void *lua_toattr(lua_State *L, int idx) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index dea1433f6d..3600e2f0ec 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -17599,11 +17599,67 @@ static const struct cmd_variable_handler bgp_var_peergroup[] = { {.tokenname = "PGNAME", .completions = bgp_ac_peergroup}, {.completions = NULL} }; +DEFINE_HOOK(bgp_config_end, (struct bgp *bgp), (bgp)); + +static struct thread *t_bgp_cfg; + +bool bgp_config_inprocess(void) +{ + return thread_is_scheduled(t_bgp_cfg); +} + +static void bgp_config_finish(struct thread *t) +{ + struct listnode *node; + struct bgp *bgp; + + for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp)) + hook_call(bgp_config_end, bgp); +} + +static void bgp_config_start(void) +{ +#define BGP_PRE_CONFIG_MAX_WAIT_SECONDS 600 + THREAD_OFF(t_bgp_cfg); + thread_add_timer(bm->master, bgp_config_finish, NULL, + BGP_PRE_CONFIG_MAX_WAIT_SECONDS, &t_bgp_cfg); +} + +/* When we receive a hook the configuration is read, + * we start a timer to make sure we postpone sending + * EoR before route-maps are processed. + * This is especially valid if using `bgp route-map delay-timer`. + */ +static void bgp_config_end(void) +{ +#define BGP_POST_CONFIG_DELAY_SECONDS 1 + uint32_t bgp_post_config_delay = + thread_is_scheduled(bm->t_rmap_update) + ? thread_timer_remain_second(bm->t_rmap_update) + : BGP_POST_CONFIG_DELAY_SECONDS; + + /* If BGP config processing thread isn't running, then + * we can return and rely it's properly handled. + */ + if (!bgp_config_inprocess()) + return; + + THREAD_OFF(t_bgp_cfg); + + /* Start a new timer to make sure we don't send EoR + * before route-maps are processed. + */ + thread_add_timer(bm->master, bgp_config_finish, NULL, + bgp_post_config_delay, &t_bgp_cfg); +} + void bgp_vty_init(void) { cmd_variable_handler_register(bgp_var_neighbor); cmd_variable_handler_register(bgp_var_peergroup); + cmd_init_config_callbacks(bgp_config_start, bgp_config_end); + /* Install bgp top node. */ install_node(&bgp_node); install_node(&bgp_ipv4_unicast_node); diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h index 93026c663a..4b393275d6 100644 --- a/bgpd/bgp_vty.h +++ b/bgpd/bgp_vty.h @@ -164,6 +164,7 @@ extern void bgp_config_write_rpkt_quanta(struct vty *vty, struct bgp *bgp); extern void bgp_config_write_listen(struct vty *vty, struct bgp *bgp); extern void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp); extern int bgp_vty_return(struct vty *vty, int ret); +extern bool bgp_config_inprocess(void); extern struct peer *peer_and_group_lookup_vty(struct vty *vty, const char *peer_str); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 38a106359e..22c09a38ac 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1731,6 +1731,8 @@ struct peer *peer_create(union sockunion *su, const char *conf_if, peer->v_routeadv = (peer_sort(peer) == BGP_PEER_IBGP) ? BGP_DEFAULT_IBGP_ROUTEADV : BGP_DEFAULT_EBGP_ROUTEADV; + if (bgp_config_inprocess()) + peer->shut_during_cfg = true; peer = peer_lock(peer); /* bgp peer list reference */ peer->group = group; @@ -2347,15 +2349,15 @@ void peer_nsf_stop(struct peer *peer) if (peer->t_gr_restart) { BGP_TIMER_OFF(peer->t_gr_restart); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s graceful restart timer stopped", - peer->host); + zlog_debug("%s(%s) graceful restart timer stopped", + peer->host, bgp_peer_hostname(peer)); } if (peer->t_gr_stale) { BGP_TIMER_OFF(peer->t_gr_stale); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s graceful restart stalepath timer stopped", - peer->host); + "%s(%s) graceful restart stalepath timer stopped", + peer->host, bgp_peer_hostname(peer)); } bgp_clear_route_all(peer); } @@ -4294,8 +4296,9 @@ static void peer_flag_modify_action(struct peer *peer, uint32_t flag) BGP_TIMER_OFF(peer->t_pmax_restart); if (bgp_debug_neighbor_events(peer)) zlog_debug( - "%s Maximum-prefix restart timer canceled", - peer->host); + "%s(%s) Maximum-prefix restart timer canceled", + peer->host, + bgp_peer_hostname(peer)); } if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status)) { @@ -7185,8 +7188,9 @@ static bool peer_maximum_prefix_clear_overflow(struct peer *peer) if (peer->t_pmax_restart) { BGP_TIMER_OFF(peer->t_pmax_restart); if (bgp_debug_neighbor_events(peer)) - zlog_debug("%s Maximum-prefix restart timer cancelled", - peer->host); + zlog_debug( + "%s(%s) Maximum-prefix restart timer cancelled", + peer->host, bgp_peer_hostname(peer)); } BGP_EVENT_ADD(peer, BGP_Start); return true; @@ -7938,8 +7942,33 @@ void bgp_pthreads_finish(void) frr_pthread_stop_all(); } +static int peer_unshut_after_cfg(struct bgp *bgp) +{ + struct listnode *node; + struct peer *peer; + + for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) { + if (!peer->shut_during_cfg) + continue; + + if (bgp_debug_neighbor_events(peer)) + zlog_debug("%s: released from config-pending hold", + peer->host); + + peer->shut_during_cfg = false; + if (peer_active(peer) && peer->status != Established) { + if (peer->status != Idle) + BGP_EVENT_ADD(peer, BGP_Stop); + BGP_EVENT_ADD(peer, BGP_Start); + } + } + + return 0; +} + void bgp_init(unsigned short instance) { + hook_register(bgp_config_end, peer_unshut_after_cfg); /* allocates some vital data structures used by peer commands in * vty_init */ diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index a9475f39a7..766b0199f4 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -771,6 +771,7 @@ DECLARE_HOOK(bgp_inst_delete, (struct bgp *bgp), (bgp)); DECLARE_HOOK(bgp_inst_config_write, (struct bgp *bgp, struct vty *vty), (bgp, vty)); +DECLARE_HOOK(bgp_config_end, (struct bgp *bgp), (bgp)); /* Thread callback information */ struct afi_safi_info { @@ -1676,6 +1677,8 @@ struct peer { /* Long-lived Graceful Restart */ struct llgr_info llgr[AFI_MAX][SAFI_MAX]; + bool shut_during_cfg; + QOBJ_FIELDS; }; DECLARE_QOBJ_TYPE(peer); @@ -1703,9 +1706,10 @@ DECLARE_QOBJ_TYPE(peer); /* Check if suppress start/restart of sessions to peer. */ #define BGP_PEER_START_SUPPRESSED(P) \ - (CHECK_FLAG((P)->flags, PEER_FLAG_SHUTDOWN) \ - || CHECK_FLAG((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW) \ - || CHECK_FLAG((P)->bgp->flags, BGP_FLAG_SHUTDOWN)) + (CHECK_FLAG((P)->flags, PEER_FLAG_SHUTDOWN) || \ + CHECK_FLAG((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW) || \ + CHECK_FLAG((P)->bgp->flags, BGP_FLAG_SHUTDOWN) || \ + (P)->shut_during_cfg) #define PEER_ROUTE_ADV_DELAY(peer) \ (CHECK_FLAG(peer->thread_flags, PEER_THREAD_SUBGRP_ADV_DELAY)) @@ -2469,6 +2473,11 @@ static inline bool bgp_in_graceful_shutdown(struct bgp *bgp) !!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)); } +static inline const char *bgp_peer_hostname(struct peer *peer) +{ + return peer->hostname ? peer->hostname : "Unknown"; +} + /* For benefit of rfapi */ extern struct peer *peer_new(struct bgp *bgp); diff --git a/doc/user/basic.rst b/doc/user/basic.rst index 4c196cfcfe..ea4b3f41f3 100644 --- a/doc/user/basic.rst +++ b/doc/user/basic.rst @@ -678,6 +678,20 @@ Terminal Mode Commands This command displays FRR's timer data for timers that will pop in the future. +.. clicmd:: show yang operational-data XPATH [{format <json|xml>|translate TRANSLATOR|with-config}] DAEMON + + Display the YANG operational data starting from XPATH. The default + format is JSON, but can be displayed in XML as well. + + Normally YANG operational data are located inside containers marked + as `read-only`. + + Optionally it is also possible to display configuration leaves in + addition to operational data with the option `with-config`. This + option enables the display of configuration leaves with their + currently configured value (if the leaf is optional it will only show + if it was created or has a default value). + .. _common-invocation-options: Common Invocation Options diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index 0244f7c583..cd220a4141 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -712,7 +712,7 @@ and this section also helps that case. Create a new locator. If the name of an existing locator is specified, move to specified locator's configuration node to change the settings it. -.. clicmd:: prefix X:X::X:X/M [function-bits-length 32] +.. clicmd:: prefix X:X::X:X/M [func-bits 32] Set the ipv6 prefix block of the locator. SRv6 locator is defined by RFC8986. The actual routing protocol specifies the locator and allocates a @@ -732,7 +732,7 @@ and this section also helps that case. will be ``2001:db8:1:1:1::``) The function bits range is 16bits by default. If operator want to change - function bits range, they can configure with ``function-bits-length`` + function bits range, they can configure with ``func-bits`` option. :: diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index fd05fb94df..b5fce35b1e 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -1400,14 +1400,13 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree, spf_adj_list_parse_lsp(spftree, adj_list, lsp, id, metric); } -static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, - struct list *adj_list, struct isis_lsp *lsp, - const uint8_t *pseudo_nodeid, - uint32_t pseudo_metric) +static void spf_adj_list_parse_lsp_frag(struct isis_spftree *spftree, + struct list *adj_list, + struct isis_lsp *lsp, + const uint8_t *pseudo_nodeid, + uint32_t pseudo_metric) { bool pseudo_lsp = LSP_PSEUDO_ID(lsp->hdr.lsp_id); - struct isis_lsp *frag; - struct listnode *node; struct isis_item *head; struct isis_item_list *te_neighs; @@ -1445,14 +1444,27 @@ static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, } } } +} + + +static void spf_adj_list_parse_lsp(struct isis_spftree *spftree, + struct list *adj_list, struct isis_lsp *lsp, + const uint8_t *pseudo_nodeid, + uint32_t pseudo_metric) +{ + struct isis_lsp *frag; + struct listnode *node; + + spf_adj_list_parse_lsp_frag(spftree, adj_list, lsp, pseudo_nodeid, + pseudo_metric); /* Parse LSP fragments. */ for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { if (!frag->tlvs) continue; - spf_adj_list_parse_lsp(spftree, adj_list, frag, pseudo_nodeid, - pseudo_metric); + spf_adj_list_parse_lsp_frag(spftree, adj_list, frag, + pseudo_nodeid, pseudo_metric); } } diff --git a/lib/frrscript.c b/lib/frrscript.c index 4fee79991a..8add44c19e 100644 --- a/lib/frrscript.c +++ b/lib/frrscript.c @@ -373,7 +373,7 @@ int frrscript_load(struct frrscript *fs, const char *function_name, } if (luaL_dofile(L, script_name) != 0) { - zlog_err("frrscript: failed loading script '%s.lua': error: %s", + zlog_err("frrscript: failed loading script '%s': error: %s", script_name, lua_tostring(L, -1)); goto fail; } @@ -381,7 +381,7 @@ int frrscript_load(struct frrscript *fs, const char *function_name, /* To check the Lua function, we get it from the global table */ lua_getglobal(L, function_name); if (lua_isfunction(L, lua_gettop(L)) == 0) { - zlog_err("frrscript: loaded script '%s.lua' but %s not found", + zlog_err("frrscript: loaded script '%s' but %s not found", script_name, function_name); goto fail; } @@ -391,7 +391,7 @@ int frrscript_load(struct frrscript *fs, const char *function_name, if (load_cb && (*load_cb)(fs) != 0) { zlog_err( - "frrscript: '%s.lua': %s: loaded but callback returned non-zero exit code", + "frrscript: '%s': %s: loaded but callback returned non-zero exit code", script_name, function_name); goto fail; } diff --git a/lib/northbound.c b/lib/northbound.c index 49adea6d53..2cc7ac6ea1 100644 --- a/lib/northbound.c +++ b/lib/northbound.c @@ -1649,10 +1649,12 @@ static int nb_oper_data_iter_container(const struct nb_node *nb_node, uint32_t flags, nb_oper_data_cb cb, void *arg) { + const struct lysc_node *snode = nb_node->snode; + if (CHECK_FLAG(nb_node->flags, F_NB_NODE_CONFIG_ONLY)) return NB_OK; - /* Presence containers. */ + /* Read-only presence containers. */ if (nb_node->cbs.get_elem) { struct yang_data *data; int ret; @@ -1662,15 +1664,24 @@ static int nb_oper_data_iter_container(const struct nb_node *nb_node, /* Presence container is not present. */ return NB_OK; - ret = (*cb)(nb_node->snode, translator, data, arg); + ret = (*cb)(snode, translator, data, arg); if (ret != NB_OK) return ret; } + /* Read-write presence containers. */ + if (CHECK_FLAG(snode->flags, LYS_CONFIG_W)) { + struct lysc_node_container *scontainer; + + scontainer = (struct lysc_node_container *)snode; + if (CHECK_FLAG(scontainer->flags, LYS_PRESENCE) + && !yang_dnode_get(running_config->dnode, xpath)) + return NB_OK; + } + /* Iterate over the child nodes. */ - return nb_oper_data_iter_children(nb_node->snode, xpath, list_entry, - list_keys, translator, false, flags, - cb, arg); + return nb_oper_data_iter_children(snode, xpath, list_entry, list_keys, + translator, false, flags, cb, arg); } static int diff --git a/lib/northbound_cli.c b/lib/northbound_cli.c index 1e25f6a1e2..56eac9dc32 100644 --- a/lib/northbound_cli.c +++ b/lib/northbound_cli.c @@ -1464,6 +1464,7 @@ DEFPY (show_yang_operational_data, [{\ format <json$json|xml$xml>\ |translate WORD$translator_family\ + |with-config$with_config\ }]", SHOW_STR "YANG information\n" @@ -1473,13 +1474,15 @@ DEFPY (show_yang_operational_data, "JavaScript Object Notation\n" "Extensible Markup Language\n" "Translate operational data\n" - "YANG module translator\n") + "YANG module translator\n" + "Merge configuration data\n") { LYD_FORMAT format; struct yang_translator *translator = NULL; struct ly_ctx *ly_ctx; struct lyd_node *dnode; char *strp; + uint32_t print_options = LYD_PRINT_WITHSIBLINGS; if (xml) format = LYD_XML; @@ -1507,13 +1510,21 @@ DEFPY (show_yang_operational_data, yang_dnode_free(dnode); return CMD_WARNING; } + + if (with_config && yang_dnode_exists(running_config->dnode, xpath)) { + struct lyd_node *config_dnode = + yang_dnode_get(running_config->dnode, xpath); + if (config_dnode != NULL) { + lyd_merge_tree(&dnode, yang_dnode_dup(config_dnode), + LYD_MERGE_DESTRUCT); + print_options |= LYD_PRINT_WD_ALL; + } + } + (void)lyd_validate_all(&dnode, ly_ctx, 0, NULL); /* Display the data. */ - if (lyd_print_mem(&strp, dnode, format, - LYD_PRINT_WITHSIBLINGS | LYD_PRINT_WD_ALL) - != 0 - || !strp) { + if (lyd_print_mem(&strp, dnode, format, print_options) != 0 || !strp) { vty_out(vty, "%% Failed to display operational data.\n"); yang_dnode_free(dnode); return CMD_WARNING; diff --git a/m4/.gitignore b/m4/.gitignore index 01a2a593d0..63f9fa78ed 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -3,6 +3,7 @@ !ax_compare_version.m4 !ax_cxx_compile_stdcxx.m4 +!ax_lua.m4 !ax_prog_perl_modules.m4 !ax_pthread.m4 !ax_python.m4 diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 48751dfba8..3ad7ca7d1b 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2422,10 +2422,10 @@ void ospf_external_lsa_flush(struct ospf *ospf, uint8_t type, && !(CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))) ospf_nssa_lsa_flush(ospf, p); - /* Sweep LSA from Link State Retransmit List. */ - ospf_ls_retransmit_delete_nbr_as(ospf, lsa); - if (!IS_LSA_MAXAGE(lsa)) { + /* Sweep LSA from Link State Retransmit List. */ + ospf_ls_retransmit_delete_nbr_as(ospf, lsa); + /* Unregister LSA from Refresh queue. */ ospf_refresher_unregister_lsa(ospf, lsa); diff --git a/ospfd/ospf_sr.c b/ospfd/ospf_sr.c index e4059d05c2..b5dbc4a5a9 100644 --- a/ospfd/ospf_sr.c +++ b/ospfd/ospf_sr.c @@ -2053,11 +2053,15 @@ void ospf_sr_config_write_router(struct vty *vty) vty_out(vty, " segment-routing global-block %u %u", OspfSR.srgb.start, upper); - if ((OspfSR.srlb.start != DEFAULT_SRLB_LABEL) - || (OspfSR.srlb.end != DEFAULT_SRLB_END)) + if ((OspfSR.srlb.start != DEFAULT_SRLB_LABEL) || + (OspfSR.srlb.end != DEFAULT_SRLB_END)) { + if ((OspfSR.srgb.start == DEFAULT_SRGB_LABEL) && + (OspfSR.srgb.size == DEFAULT_SRGB_SIZE)) + vty_out(vty, " segment-routing global-block %u %u", + OspfSR.srgb.start, upper); vty_out(vty, " local-block %u %u\n", OspfSR.srlb.start, OspfSR.srlb.end); - else + } else vty_out(vty, "\n"); if (OspfSR.msd != 0) @@ -2663,12 +2667,18 @@ DEFUN (no_sr_prefix_sid, return CMD_WARNING_CONFIG_FAILED; } + osr_debug("SR (%s): Remove Prefix %pFX with index %u", __func__, + (struct prefix *)&srp->prefv4, srp->sid); + /* Get Interface */ ifp = if_lookup_by_index(srp->nhlfe.ifindex, VRF_DEFAULT); if (ifp == NULL) { vty_out(vty, "interface for prefix %s not found.\n", argv[idx]->arg); - return CMD_WARNING_CONFIG_FAILED; + /* silently remove from list */ + listnode_delete(OspfSR.self->ext_prefix, srp); + XFREE(MTYPE_OSPF_SR_PARAMS, srp); + return CMD_SUCCESS; } /* Update Extended Prefix LSA */ @@ -2677,9 +2687,6 @@ DEFUN (no_sr_prefix_sid, return CMD_WARNING; } - osr_debug("SR (%s): Remove Prefix %pFX with index %u", __func__, - (struct prefix *)&srp->prefv4, srp->sid); - /* Delete NHLFE if NO-PHP is set and EXPLICIT NULL not set */ if (CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_NPFLG) && !CHECK_FLAG(srp->flags, EXT_SUBTLV_PREFIX_SID_EFLG)) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index d4245bde7f..a753340476 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -4395,11 +4395,18 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, json_neighbor = json_object_new_object(); ospf_nbr_ism_state_message(nbr, msgbuf, 16); - +#if CONFDATE > 20230321 +CPP_NOTICE("Remove show_ip_ospf_neighbor_sub() JSON keys: priority, state, deadTimeMsecs, address, retransmitCounter, requestCounter, dbSummaryCounter") +#endif json_object_int_add(json_neighbor, "priority", nbr->priority); json_object_string_add(json_neighbor, "state", msgbuf); + json_object_int_add(json_neighbor, + "nbrPriority", + nbr->priority); + json_object_string_add(json_neighbor, + "nbrState", msgbuf); json_object_string_add( json_neighbor, "converged", @@ -4425,6 +4432,10 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, json_object_int_add(json_neighbor, "deadTimeMsecs", time_store); + json_object_int_add( + json_neighbor, + "routerDeadIntervalTimerDueMsec", + time_store); json_object_string_add( json_neighbor, "upTime", ospf_timeval_dump( @@ -4440,22 +4451,41 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty, json_object_string_add(json_neighbor, "deadTimeMsecs", "inactive"); + json_object_string_add( + json_neighbor, + "routerDeadIntervalTimerDueMsec", + "inactive"); } json_object_string_addf(json_neighbor, "address", "%pI4", &nbr->src); + json_object_string_addf(json_neighbor, + "ifaceAddress", "%pI4", + &nbr->src); json_object_string_add(json_neighbor, "ifaceName", IF_NAME(oi)); json_object_int_add( json_neighbor, "retransmitCounter", ospf_ls_retransmit_count(nbr)); + json_object_int_add( + json_neighbor, + "linkStateRetransmissionListCounter", + ospf_ls_retransmit_count(nbr)); json_object_int_add(json_neighbor, "requestCounter", ospf_ls_request_count(nbr)); + json_object_int_add( + json_neighbor, + "linkStateRequestListCounter", + ospf_ls_request_count(nbr)); json_object_int_add(json_neighbor, "dbSummaryCounter", ospf_db_summary_count(nbr)); + json_object_int_add( + json_neighbor, + "databaseSummaryListCounter", + ospf_db_summary_count(nbr)); json_object_array_add(json_neigh_array, json_neighbor); diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 389d3647d0..496d85fd7b 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -1280,6 +1280,7 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) { struct zapi_route api; struct prefix_ipv4 p; + struct prefix pgen; unsigned long ifindex; struct in_addr nexthop; struct external_info *ei; @@ -1302,13 +1303,17 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS) if (IPV4_NET127(ntohl(p.prefix.s_addr))) return 0; + pgen.family = p.family; + pgen.prefixlen = p.prefixlen; + pgen.u.prefix4 = p.prefix; + /* Re-destributed route is default route. * Here, route type is used as 'ZEBRA_ROUTE_KERNEL' for * updating ex-info. But in resetting (no default-info * originate)ZEBRA_ROUTE_MAX is used to delete the ex-info. * Resolved this inconsistency by maintaining same route type. */ - if (is_default_prefix4(&p)) + if ((is_default_prefix(&pgen)) && (api.type != ZEBRA_ROUTE_OSPF)) rt_type = DEFAULT_ROUTE; if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index ed1f1fb5bb..9e8f73b101 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -2955,6 +2955,7 @@ DEFUN (show_yang_operational_data, [{\ format <json|xml>\ |translate WORD\ + |with-config\ }]" DAEMONS_LIST, SHOW_STR "YANG information\n" @@ -2965,6 +2966,7 @@ DEFUN (show_yang_operational_data, "Extensible Markup Language\n" "Translate operational data\n" "YANG module translator\n" + "Merge configuration data\n" DAEMONS_STR) { return show_one_daemon(vty, argv, argc - 1, argv[argc - 1]->text); diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c index ebe0fffcb2..62ce17326c 100644 --- a/zebra/zebra_srv6_vty.c +++ b/zebra/zebra_srv6_vty.c @@ -354,8 +354,12 @@ static int zebra_sr_config(struct vty *vty) inet_ntop(AF_INET6, &locator->prefix.prefix, str, sizeof(str)); vty_out(vty, " locator %s\n", locator->name); - vty_out(vty, " prefix %s/%u\n", str, + vty_out(vty, " prefix %s/%u", str, locator->prefix.prefixlen); + if (locator->function_bits_length) + vty_out(vty, " func-bits %u", + locator->function_bits_length); + vty_out(vty, "\n"); vty_out(vty, " exit\n"); vty_out(vty, " !\n"); } |
